First Game Reflections


Hey everybody,

Recently, I just finished my first ever game "No Leaves Left!" and I think it was an incredibly fun, insightful experience. In this post, I want to work through my general approach to how I developed the game in about 20 hours.

Initial Idea

For this game jam, the theme was optional so I didn't stress too much about including it. The vibes were meant to be something cozy (which I interpreted as simply "low stakes") and autumn-themed. I did end up planning for the theme, but ended up scrapping it toward the end because I didn't really want to add a whole new mechanic to the game.

I knew I needed to have a reasonable scope, considering this is both my first game ever and the fact that the jam was only 4 days long. I was inspired by mobile games like "Where's My Water?" where you basically have to move some material from point A to point B while avoiding obstacles, and however much material you gather is calculated into how many stars you earn. Thus, the base idea of the game was formed: a leaf-collecting game.

Here is what I wrote down in my Game Design Document for the premise of the game:

"Raking leaves simulator where the goal is to get all the leaves in a defined area. Get a certain percentage of leaves in the area to get stars. You can beat the level with 0-3 stars. You can collect up to 2 lost toys. After each level, give the lost toy to the corresponding child and get upgrades to your rake (toy-based?)."

The theme was "lost and found" and so I wanted to incorporate some sort of toy-collecting mechanic for toys lost by children, but I think this would've taken too long and probably wasn't needed for a game like this.

Choosing an Engine

I'm going to be honest, I do not have extensive knowledge of any game engines. I think after researching which game engine is best for a beginner, I came to the conclusion that there isn't really a best one and to just stick with something. Literally any of them. The only engine I had worked in previously was RPGMaker XP, but I never finished anything with it. And it didn't seem right for the game's scope anyway, so I figured it was time to learn a new engine.

I ended up choosing Godot because people said it was beginner-friendly with its node and signal system. In hindsight, I probably would have preferred an engine with visual scripting, but GDScript's similarity to Python made it rather approachable for me. Even though the consensus seems to be that Godot is beginner-friendly, I found that it still has quite a learning curve. I attributed this initially to my lack of experience with engines as a whole, but one of my friends told me that Godot was probably the hardest of the Big 3 engines (Godot, Unreal, Unity). Regardless, I think that Godot was suitable enough for this project, and I plan on using it extensively to develop more games in the future now that I have a more solid understanding of it.

Actually Making the Game

The first thing I did was make a Trello board with a few categories: a to-do list, a "done" list, a "doing" list, and a "kind of done" list. I wrote down as many things I thought the game would need and put that in the to-do list. As I worked on the game, I would move things into appropriate categories that I hope are rather self-explanatory. "Kind of done" in this context just means that the mechanic is working but probably could use some polish. In the end, the star system would be the only thing in this category.

So, here's the list of things I added:

  • Main menu
  • Play button
  • Title card
  • Credits
  • Rake mechanics
  • Leaf mechanics
  • Assets for rake, leaf, background, and obstacles
  • Obstacle implementation/mechanics
  • Coding the win condition
  • Coding the star system
  • Adding levels
  • Making tooltips
  • Next level/Restart level screen
  • SFX
  • Music
  • Toy system

In the end, I never ended up adding SFX, music, or the toy system I briefly touched on, and the game definitely would have been enhanced with these elements. But considering I did everything else, I would consider this a win.

The main menu was surprisingly pretty easy. I knocked this out in about an hour after following a simple tutorial on how to make a main menu. I used fonts that were free to use, and tried to make the color scheme fit more in-line with autumn.

This is probably the part where I should explain the assets I chose to use. I used any assets that were considered free to use, and made sure to give proper credit to individuals who created them, unless these assets were in the public domain (i.e., the rake). I did not make any assets myself, save for a circle that I quickly did in Aesprite because I couldn't figure out how to make a circle in Godot.

Next up, the rake and leaf mechanics. The rake basically had to follow the player's mouse, and I knew you would press a button to have the ends of the rake be able to scoop up leaves. This involved a lot about learning how collisions work in Godot, as well as the classes of certain Nodes and how they operate. The rake made sense to be a CharacterBody2D node, while the leaves had to be a RigidBody2D node so that they could actually move. I quickly picked up that every object in the game needed to have a sprite and a collision box at minimum. For the rake, I wanted the collision box to only be active once the player pressed the "rake" button, so that they could drag leaves like a real rake would. This involved making a collision box at only the end of the rake.

To actually get the rake to follow the player was a bit tough, and it includes code that even I don't actually understand and got off a forum. It was pretty easy, at least, to hide the mouse (even though it doesn't work for a browser game--glad I figured that one out). 

I also needed to get the rake to rotate, so I copied the code from the template of the player movement and just changed a few things to make the A and D keys rotate the CharacterBody2D.

The leaves were pretty simple to make once I understood collision layers, because you can't have the rake collide with the leaves until the player pressed the rake button (which I chose to be LShift). I followed a tutorial online for these collision layers.

Now I had to add in a background, which required me to learn the TileMapLayer node and all its systems. Luckily, I had watched a basic tutorial on Godot which covered this briefly, so it wasn't so hard to relearn for my own project's goals. It's pretty simple and reminds me of RPGMaker XP where you can just place tiles in a map. I'm sure this is how it works for probably every game engine, but it's interesting to know for a first timer.

I had to think of some obstacles for the player, because just shuffling leaves around until they got into a pile didn't seem like a fun or particularly stimulating experience. The first thing I knew was I wanted to make it so if any leaves went out of bounds, they would be deleted and would count against your score. Similarly, I wanted something that would delete leaves, like a hole, that I could place in the map for the player to avoid. When I got my tileset, I also decided to have a tree simply block the player's path, though it has the side effect of reducing visibility of the leaves that I had to ensure was implemented by placing the Nodes in the scene in the correct order (the leaves go first, then the second layer of the TileMap containing the tree). Finally, I had the idea of making fans blow leaves away. It was really, really hard to find a good, free fan asset to use, but thankfully I did find one.

By the way, all assets I used are properly credited in the game, so be sure to check it out if you like what you saw. I didn't pay for any asset.

The holes were easy to program. Basically, when the leaves collide with the hole, then the leaves get removed from the game with queue_free(). The fans... not so much. I couldn't figure out how to make an object emit an outward force without the object itself just falling because it applies the force to itself. So, I had to make a Line2D node with a path child node, and a follow path child node, and a static body child node (all of these are nested if that wasn't clear) with a collision box. Basically, the static body child node would follow this path at a high velocity, effectively "pushing" any leaves that are in its path. I then had to implement a script that followed a Timer node to have the fan turn on and off at certain intervals. Getting the particle effects was a pain in itself, but I ended up with a result I was relatively happy with.

Now that all of the obstacles are implemented, I had to code in a win condition (which is more like a "level completed" condition). And, oh man, this took a long time.  Essentially, I had to make it so that the game would detect if all of the leaves were either in a designated pile region, or if they were otherwise deleted. Once all of the leaves met one of these conditions, then the level would end. I did the GDScript tutorial from Godot's official docs before this jam to familiarize myself with the language, and I borrowed a lot from that.

Essentially, the game has to detect how many leaves are in the level at first. This is done by defining variables that are empty lists, and when the leaves spawn in, the game inserts an item into the list for each leaf. Then, the game knows when the level is done by updating a variable called "maxscore" to equal the length of the list (using len()). To figure out when a leaf has entered/exited the game or the collection region, basically I had to make empty lists and define functions that would update the lists with append or pop_front. It's basically identical to the GDScript tutorial's section on making a restaurant order queue system. I then had to ensure that my score and progress variables updated for each leaf that either got deleted or entered the collection region. It also had to account for if the leaves were pushed out of the collection region, so that you couldn't just keep putting the same leaf in and out of the collection region and win that way. 

Finally, I had a function called all_done() which ran if the progress variable was equal to the maxscore variable. This function displayed the level completed screen and calculated how many stars you earned at the end of each level. It would also unhide the mouse, which was supposed to be hidden (it would be if it were a downloadable game and not a web game).

Tooltips were then implemented alongside actual levels for the game. Since I made such a robust structure for my game already, designing levels felt like just using a map editor in a different game. It was really, really easy to make levels once I figured out all the quirks, but I had to do the legwork first. I knew the first few levels should introduce the player to the mechanics of the game, and then the last levels should challenge the player in some way. I feel like I did a good job in this regard. Tooltips were then implemented alongside actual levels for the game.

The star system was implemented with the help of global variables (apparently called singletons, but I don't know the terminology well enough). Basically, upon level completion, a global variable called "starcount" would be updated to add in any stars the player earned at that level. Simple enough, but there is a bug that I don't feel like fixing at the moment where the player can restart the level and just keep stockpiling stars for each level completed, so that their total in the end of the level is way more than the maximum of 24 you could get.

Global variables also helped with changing levels. You start with a global variable "levelnumber" at 1, and then each time the player clicks "Next" after completing a level, this variable increases by 1. If they click "Retry" the variable stays the same. This allowed me to do something clever with string concatenation so that I could name my level files with this variable in mind.

And, yeah, that was basically the development process of my first ever game. I'll link the GitHub page below if you want to see the actual code I used. There's also a lot of unused assets in there, so it's not well-organized by any means. But, I at least organized most of my assets into the assets folder, and all of my scripts into the scripts folder.

Thanks for reading! If you have any feedback, let me know.

https://github.com/joedapr0/no-leaves-left

Leave a comment

Log in with itch.io to leave a comment.