cstris banner

cstris

16 devlogs
96h 3m 24s

A familiar stacking game, modernized and written in C# using Raylib-cs.

Play a stacking puzzle game, where you have to clear lines to recieve score, the harder the way you manage to clear a line (Single, Quad, T-Spin Triple…) - the more scor…

A familiar stacking game, modernized and written in C# using Raylib-cs.

Play a stacking puzzle game, where you have to clear lines to recieve score, the harder the way you manage to clear a line (Single, Quad, T-Spin Triple…) - the more score you get. Should you stack too high up and top out - you lose.

Includes multiple playable gamemodes: Marathon, 40Lines, Blitz, 4Wide, Survival.
The main focus of the game is feel. The game should feel good, letting you control every keybind and handling settings.

This is my first ever C# project, and I am writing it at the same time as learning about C#, so hopefully it turned out great :).

This project uses AI

I used ChatGPT for help with creating the Pseudorandom number generator since I had no clue how to make one.
I did not use AI anywhere else, since this is a learning project. (I have copilot tab suggestions disabled in Visual Studio)

Demo Repository

Loading README...

readprocessmemory

BIG update for the stacking game

five new gamemodes!
• Dig: Dig through 10 lines of random garbage as fast as you can.
• 20G: hard gamemode where you have to play with max gravity, goal is score (good luck🙏🙏)
• 20 Line sprint: clear 20 lines as fast as you can (a faster version of 40lines)
• Classic: Recreation of NES tetris (lil off but it’s ok)
• Practice: Chill stacking with an undo ability and lots of stats displayed on your left.

And small changes which I have already forgotten. (the usual)
Ran into a lot of issues while trying to implement practice and needed to write a lot of new stuff, but it works and it’s really nice.
Also had to make a lot of changes to the classic rotation system, it was already implemented, but pretty badly so I fixed it up for the gamemode.
(Watch the attached videos for gameplay of each gamemode)

Attachment
1

Comments

tunnor
tunnor 1 day ago

This is so cool! I’m working on a game in C# (MonoGame for me) too, although you are much further along. Keep cooking, fellow chef! A follow from me!

readprocessmemory

Performance!
I spent a lot of time in the performance profiler looking at flame graphs and found some massive performance optimizations!!! (and stupidities):

• The space background was drawing 100 different size and color circles every frame. And for every single one of them it had to calculate lots of data (not ideal).
I fixed this by drawing a texture of a circle 100 times in different size and color.. that resulted in the space background dropping from ~58% (😱) of frametime -> ~3% of frametime, saving loads of time and leaving the space background visually unchanged.

• Another problem, was how I was drawing text, I have to draw text with an SDF shader, and I was switching to rendering with the shader and without for every single text draw call (not ideal).
So I created a text buffer, which when cleared results in raylib using only one batch draw call for rendering all the text.

So cstris gained ~1500 fps from the previous version. (I switched the way the fps label is rendered, which is only related to the text optimization).
I did some more optimizations related to lazy-loading. There will be a more in-depth explanation about these (and the ones i mentioned) in the repo (one day..)

Attachment
0
readprocessmemory

Shipped this project!

Hours: 87.48
Cookies: 🍪 1896
Multiplier: 21.67 cookies/hr

cstris v1.0.0 is being shipped! It was really interesting making a game (I had never done that before) and learning C# (I had never done that before).
The most challenging part, was most likely all the logic that had to be implemented for the gameplay to work (broke many times).
I am pretty proud of how it turned out at the end and perhaps I’ll add more since I still have a few ideas left.

readprocessmemory

Some changes before shipping (soon):
• added countdowns before playing and after unpausing
• added APM (attack per minute) counter
• added APP (attack per piece) counter
• added checking for if the player is in danger (stacking too high), when in danger display the next piece’s matrix border, so it is possible to discern where the next piece spawns
• added sound for incoming garbage
• added sound for the countdown ticking down
• changed how the garbage queue is drawn, so it would indicate how much garbage is about to enter
• fixed bug where the leveling sound wouldn’t play
• fixed overflow bugs in rare cases when loading saved stats (would result in a crash)

0
readprocessmemory

Oh my, there’s so much!

new gamemodes:
•4 Wide: try to get the highest combo you can, with the board being 4 blocks wide (it makes it really easy to combo multiple pieces, since they are made out of 4 blocks - yeah, that’s the tetra in tetris)
•Survival Easy/Medium/Hard: survive for as long as you can, but you have lines coming from below pushing you up!! You can choose your difficulty, and different attacks result in different amounts of garbage fended off (see next point)

•Attack tables: Every attack (T-Spin, Quad, Triple, Mini J-Spin..) has its own attack worth, essentially the harder the clear you pull of, the more you defend yourself, with combos included!

•Garbage: in gamemodes like Survival you recieve random lines in your garbage queue, when you place a piece that does not result in a clear (this allows you to save yourself with a combo) the garbage queue gets emptied out into the bottom of your board in the form of lines with random unfilled holes, pushing everything up. (the holes depend on the cleanliness% of the garbage, the less clean the garbage, the less chance there is for the hole to appear in a reachable position)

•SOUNDS: now there’s audio feedback for when you play the game, listen closely and tell me if it sounds good (I did not produce the sounds myself, there will be credits in the repo!)
•Many small fixes for gameplay and drawing logic.
Only a few things left until the ship, It’s almost finished!!

Attachment
0
readprocessmemory

this game looks so good now!!! wow
this update i mainly worked on visuals, effects and a few fixes:

• You might have noticed that the ugly gray background is no more, and it’s replaced by SPACE, wow…
(every scene can choose what background it wants to use, perhaps there will be more of them)
• Added more options to choose from when creating a custom game
• The queue drawing is finally fixed!! Before this it had really inconsistent spacing around certain pieces, like the I piece.
• Board easing effect: the board now reacts to your active piece’s movements and can bounce a lil from a hard drop
• Line clear effect: the pieces smoothly fall out of the board now, making the gameplay much more satisfying
• Some small things like a drawfps toggle and menu changes.
(you can turn off the effects in the settings individualy if you are against fun)

whats next:
perhaps SOUNDS

0
readprocessmemory

Custom Games!!
if you are so bored and sick of those regular preset gamemodes, you can now go make your own via a custom game!
there are a lot of choices and things to customize, like:
• drawing stuff, perhaps you didn’t even need to see the board anyways?
• functionality: all clear awards, allowing hold, hard dropping..
• gravity: change gravity, lock delay, starting levels (or just disable leveling entirely)
• counters: all those little information ridden numbers on the left of your board
• board width and height: make the board huge, or small (your choice)
• randomizer: change the order that the pieces come in to your queue
• rotation system: maybe you didn’t even need all those fancy rotations anyway
• spins: spin detection, for ex: detecting only t-spins and nothing else
• scoring: the score that you are awarded for every type of clear

with that there are some more fixes/changes:
• game pausing
• record saving bug fixes
• sorting record by date
• can now change gravity when leveling is off

0
readprocessmemory

STATS
WOW: You can now see stats of every completed game, when you feel like reminiscing

also:
• retry button is now functional after the game ends
• you can also just press the ‘restart’ button now to restart faster (rebindable in the settings)
• the game counts how many moves you are using when placing pieces, so the player can’t stall infinitely
• minor changes for more performance
• gamemodes can choose when to save a record into their statistics (ex: 40 Lines is a gamemode where you clear 40 lines as fast as possible, so we shouldn’t save a game where the player did not reach 40 lines cleared)
• config and stats files are now stored in ‘Environment.SpecialFolder.LocalApplicationData’ instead of just the relative location of the exe

0
readprocessmemory

huge!
there’s a game over screen now, which shows many many stats about your stacking
implemented gamemodes: marathon, 40 lines, blitz
there’s a scene that lets the player choose a gamemode now
lock delay now scales with level
level is now capped by a variable in game settings (controlled by gamemode)
some small things, like the action text fading :)

whats next:
I need to make some kind of background, since it looks really bland in the menus right now.
A custom gamemode type, where the player can edit all the settings themselves.

Attachment
Attachment
0
readprocessmemory

big!!
Now the game shows what you accomplish by stacking pieces on pieces and awards you accordingly!!
Added:
Spin Detection: the game now judges your placement and awards you more score, if you manage to put a mino into a more constricted spot.
Scoring systems: the player can choose any scoring system he wants (there’s only one). The chosen system decides how much score to award you for every specific spin, taking into account your current level, combo, B2B.
B2B: the scoring system checks if you only clear quads or spins in a row, and you get rewarded 1.5x the score for keeping it
Other than that, I did some early work on gamemodes and the overall feel of the controls (again) this time it feels polished, i swear

Attachment
0
readprocessmemory

Added counters that display data about the ongoing game. The player can choose what data he wants to see on the screen and it’ll be there!!
The real important ones include:
Pieces Per Second - your stacking speed in terms of pieces placed per second
Inputs Per Piece - the amount of inputs you use per every piece placed
Time - pretty important
Score - might be more important
And way more, which can be seen in the attached gif (that has every one of them enabled)

Attachment
0
readprocessmemory

MAJOR update, the player can now see the queue, which makes stacking way more fun and enjoyable!!
Added customizable counters to the side of the board. (for ex: pieces per second, time, lines cleared..)
I chose to not use the C# implementation of Random, because you can’t reliably copy the seed and in turn peek ahead of whats to come (thats the queue part of the game), so I had to implement another way of doing that, which ended up great.
There are also slight changes to handling, since I’m still stuck on that feeling not so perfect.
gif is going craazy this time wow!

Attachment
0
readprocessmemory

Small update
Made the movement system better, by implementing DAS, ARR, SDF, DCD. With this new update the player can move and place the pieces properly and do it way faster than before.
Simple explanations:
DAS (Delayed Auto Shift) - Time needed to hold a direction key, to activate ARR in that direction.
ARR (Automatic Repeat Rate) - Automatic tetromino moving speed.
SDF (Soft Drop Factor) - The amount of times the gravity is increased, when soft dropping.
DCD (DAS Cut Delay) - The amount of time that DAS will be paused for, after placing a tetromino.
They make the game feel better and are all customizable.

As for what’s next, I still need to work on adding a ghost piece and a queue so it would be possible to build faster.

Attachment
0
readprocessmemory

The game is in a playable state!!
Started working on the gameplay, basically made the entire base of the game. Some interesting parts include: interchangable rotation systems: different ways for the pieces to rotate into certain spots; interchangable randomizers: the order that the pieces come at; Gravity works too, with lock delay, so the piece does not instantly place when it touches the ground, only if there is no movement for a few frames (the lock delay).
A lot of my time went into the kick tables (rotations) and making sure all is correct for every piece, so it doesn’t come back to bite in the future.
There are still a lot of things left, like: gamemodes, better movement, text indicators, scoring, spin detection, ghost piece…
For now I think the next step I’ll be taking is fixing the movement, since it’s really unintuitive to be placing them now.
Man, look at those minos go!!

Attachment
Attachment
0
readprocessmemory

Finished up on the UI system, added more controls to use (ex: toggle, slider, progressbar..) with keyboard control working on all of them.
I discovered the hardest part - resolutions, scaling was hard to add because the text would look real bad since the font is rasterized for one font size, then scaled.
That’s why I added SDF (Signed Distance Field) rendering for text, which retains it’s beauty on (mostly) any size!!! So with all of these combined I can show you the all-new Settings!! With an extra code snippet, showing how drawing is handled in a scene.

Attachment
Attachment
0
readprocessmemory

Here I am again showing more menus, you know I would like to start working on the gameplay part, but I guess I’ll do that after I sort everything out with the UI. (it’s making me go crazy 😁)
Hey, I’ll make the next devlog include something with gameplay!!! 😉

Today I had to change a lot of logic to accompany a new feature, rewrote a big chunk of the button code, now it supports keybord control!!
I’m writing the UI code for buttons and such as immediate (that’s how dear imgui does it), needed somewhere to store data about the buttons, so the UIContext class was created, it’s real simple for now, but I’ll add more functionality later for more features.

woah! look at that gif, man that mountain looks good

Attachment
Attachment
0
readprocessmemory

9 hours and 42 minutes. That’s about 4-5 movies. a full night of sleep or maybe the amount of time one spends on youtube everyday…🤨(he’s looking at you)
Well whatever that time might amount to, for me It wasn’t about the length of the experience, It was definitely the result that mattered. At the end of this multi-day marathon, I did it, I created the main menu - the hub, one might even say quite the memorable part of a game, the screen that greets you when you launch the game.

most of the time was spent building the game engine (for block stacking game :) ), I have never used c# on a such a project so it was pretty interesting, also never made a game so it’ll be fun seeing how this ends up. this time round I setup important features: state managment, which displays different screens of the game (main menu, settings, gameplay..) it works using a stack, which i pop/push states on (🤔 am i a genius or is that problematic for the future - I DONT KNOW). Then came rendering, game config (for saving keybinds and such), ui styles, input management. man, just look at the main menu

For the astute amongst you, that have noticed the little pieces next to the title - they’re not really a part of anything i just added them in paint after taking the screenshot 😇

Attachment
Attachment
0