News Remaking My First Game in 24 Hours (Part 2)
Remaking My First Game in 24 Hours: Part 2
In this post I continue the challenge I gave myself to remake my first game in only 24 hours. If you haven't read the first part yet you can find it here. Let's get straight to it!
Hour 13: Polish
I noticed boxes and the player would get caught on the edges of conveyors. This is because of how the entities check what type of tile they are standing on. They will only check a single centered point directly below them. I quickly fixed this issue by adding a
conveyor_velocity variable which is updated when the entity stands on a conveyor. Before this the conveyors would directly set the entity's velocity. Every physics process frame friction is applied to the new variable. This makes it where the entity will retain some momentum making it where they slide off the edges of the tile. A more proper solution to this issue would be to check below the entity for the entire span of its collision shape, however that's a bit more complicated. Maybe I can do it later if there is enough time to spare...
Player Cursor Look
I thought the player would look more a little more interesting if it watched the mouse cursor. This was pretty simple to add.
Variable World Sizes
Having a fixed world size is kind of boring, so I added an new option when creating a world. You can now make your world the following sizes:
- Mini (32x32)
- Small (64x64)
- Medium (128x128)
- Large (256x256)
- Extra Large (512x512)
The player will be able to choose a size for each individual world. I may end up reserving "large" and "extra large" worlds to elite members.
Hours 14-16: Saving & Loading Tiles
For New Cubied's save system I decided to create a custom format so I could make the file sizes as small as possible. I leveraged Godot's built in
StreamPeerBuffer class quite a bit for this. It's not really made with this use in mind but it offers several very useful helper functions for reading and writing data. To start off a new buffer is created and important meta-data is written to it first. I call this the "header" and it contains (but is not limited to): save format version, game version, the world's name and its creation date. For the tile data itself two arrays are created, one for the main
TileMap and another for the color
TileMap. Each and every tile's type ID and color index is added to their corresponding arrays. Afterwards each array is added to the buffer, which is then saved to a file.
A very well made diagram showing how the two-dimensional tile grid translates to a one-dimensional array.
To load a world we basically have to reverse the process above. The header data is unpacked and the corresponding variables get their values. Afterwards the tile and color data is parsed and the two
TileMap nodes are updated with this information.
Hours 17-18: Title Screen & Menus
Saying the title screen in the original game is lackluster would be putting it lightly. Take a look for yourself;
I think laughable would be a better word to describe it. For the new version of the game I was tempted to make a cleaner but faithful recreation of it, but ultimately decided to make a whole new one instead. It even has a fancy world select menu!
Hour 19: Improving Tile Interactions
I was still not 100% happy with how the tile interactions worked. They were all hardcoded into the player script and had to be copied and pasted to the physics box. This is pretty lame if you ask me, so I replaced all that with a new
TileInteractor node. Now if I want to add the interactions to an entity, all I have to do is add this node to its scene and set a few parameters. I also changed up how it detects tiles and it should be way more consistent. It also makes updating the interactions easier as I don't have to copy and paste a ton of stuff. I should have made it this way to begin with honestly.
Hour 20: More New Tiles
This tile acts similar to the elevator, except it is activated when an entity is directly below it rather than standing on it.
The spike tile will destroy any box that comes into contact with it and teleports the player to the world's spawn location.
This one is also pretty similar to the elevator. Once an entity steps on it there is a 50/50 chance it will either teleport up or down.
This literally does nothing. It just looks nice.
As the name implies these are identical to the regular conveyors but fast!
Hour 21: Noclip & Improved Building
Inspired by Gmod, noclip allows the player to fly and pass through solid objects. This works by disabling some of the player's collision layers. It can by toggled on and off with the
As a small quality of life improvement I added a way to copy a tile and quickly place new identical ones. When you hover your cursor over a tile and middle click your tile type and color selections will be updated to match it. If you hold control while you do this only the color will be copied.
Rather than having the cursor constantly be a mostly transparent white box I decided to make it a bit more responsive. It will now change to look like the tile type and color you have selected. A more subtle change is that when you mouse over an existing tile it will be masked by its shape.
I was showing off the new version of the game to blockerlocker and he suggested that I make it possible to quickly switch your tile selection by scrolling. So now you can do just that! You can also hold down control to iterate through the color palette instead.
Hour 22: Saving & Loading Entities
Saving and loading entities are a bit more complicated than tiles. With tiles all I need to save is a single integer for each one. Meanwhile, each type of entity can have unique and multiple variables that need to persist and be saved. And these darn variables come in all shapes and sizes! There are multiple types such as
Vector2s and more. My solution to this is was to create a reusable and configurable
EntitySaver node, similar to what I did earlier with the
TileInteractor. Once the
EntitySaver node is added to a scene I tell it what variables it needs to save. Once the player requests to save the world, the game will find every
EntitySaver node and ask it to gather and return its data. First the saver node creates a buffer. It then loops through and checks the type of each variable its told to save. Using a format depending on said type, It will add the variable's value to the buffer. Lastly, the entity's data buffer is returned and is appended to the final save buffer after all of the tile data.
Hour 23: Cheats
I'll be taking a bit of a different approach to cheats compared to what I had in the original Cubied. Many of the cheats there were either broken, pointless or both. For New Cubied they need to make a bit more sense, so some cheats were reworked or excluded. I created a
CheatProcessor node along with an input box. The
CheatProcessor takes the player's input, finds a matching cheat and then parses arguments if needed. I have included a list of all the cheats below.
- setspawn Updates the world's spawn location to where the player currently is
- lock <code> Disables world modification
- unlock <code> Enables world modification
- sky <hex color code> Changes the background color
- gravity <scale> Changes the world's gravity scale
Hour 24: Teleporter Tile
I still had some time left, so I made a last second (or hour?) tile addition. I had this idea in mind previously but it would have taken a little extra work to implement so I skipped over it. This would be the teleporter tile type. When an entity makes contact with one it should be moved to another teleporter of the same color. It sounds simple enough, but it was actually a little more complicated than the other tiles. The game needs to track the position of each teleporter tile and group it by color. So my
CubiedGrid node does exactly that by creating a position array for each color available. When a teleporter is placed its position is added to the array matching it's color, and when destroyed its position is removed. Now whenever an entity steps on a teleporter it will take the appropriate array and randomly choose a new position from it to move the entity to.
I had a lot of fun with this little challenge! While I still have plenty to learn it was pretty interesting to look back and see how far I've come. I hope you enjoyed reading this and I appreciate that you took the time to do so! And on one final note, I want to point out that I am not done with New Cubied yet. I still have some cool ideas for features that the challenge's time budget did not allow. I'm planning to release a proper
1.0 update later on to include them. See ya later!
Remaking My First Game in 24 Hours (Part 2)
Published Jun 19, 2023, 6:14pm CST
Edited Sep 26, 2023, 10:07pm CST
I continue the challenge I gave myself to remake my first game "Cubied" in only 24 hours. This post contains hours 13 through 24.