{"author_link":"\/users\/chuckeles","author_name":"chuckeles","author_uid":"chuckeles","comments":[],"epoch":1747059266,"event":"LD57","format":"md","ldjam_node_id":415487,"likes":8,"metadata":{"p_key":"84879","p_author":"chuckeles","p_authorkey":"1033631","p_urlkey":"295637","p_title":"Post-mortem retrospective of my golfing game","p_cat":"LDJam ","p_event":"LD57","p_time":"1747059266","p_likes":"8","p_comments":"0","p_status":"WAYBACK","us_key":"1033631","us_name":"chuckeles","us_username":"chuckeles","event_start":"1743811200","event_key":"111","event_name":"Ludum Dare 57"},"node":{"id":415487,"parent":408232,"_superparent":406845,"author":33631,"type":"post","subtype":"","subsubtype":"","published":"2025-05-12T14:14:26Z","created":"2025-05-12T13:58:05Z","modified":"2025-05-19T07:06:57Z","_trust":5,"version":1313094,"slug":"post-mortem-retrospective-of-my-golfing-game","name":"Post-mortem retrospective of my golfing game","body":"# Intro\n\nI made a cute and crazy golfing game for the Ludum Dare 57! I think I managed to build pretty cool game ideas and mechanics, based on the **\"depths\"** theme. This was over a month ago. Yeah\u2026 it took me a month of procrastination to finally sit down and write this. But better late than never, here we go!\n\n# Game jam\n\nI couldn't sleep well the night before the Ludum Dare began, so I had some time to think about what kind of game I wanted to make for the theme. I usually spend about the first half of the first day thinking about game ideas. But this time it was actually quite quick. Of course, the first ideas that came to my mind were games about caves, mining, and fishing. While I love these kinds of games (Minecraft, Terraria \u2764\ufe0f\u200d\ud83d\udd25), I wanted to do something more original.\n\nI got the idea to make a **golfing game, but each hole would lead into the next level**. I had never made a golfing game before, so this was\u2026 seductive! It would also be about **platforming** since the player would always have to get to the ball physically, and also get to the hole in the end to progress to the next level. I love platformers, so another plus point for this idea.\n\nBTW, if you're interested in caves and mining just like I am, here's one amazing video I recently saw about a mining game made for this Ludum Dare. I love how it looks, works, and feels! Check it out: [How I made a procedural cave game in 48 hours | Ludum Dare 57 Devlog](https:\/\/youtu.be\/D6YEypAf4pU?si=Ag6HZ5CnprV4B2At)\n\nI immediately jumped into making the game in the morning. I prototyped the golfing physics and having the player hit the ball. I drew a (quite nice, IMO) sprite and animations for the player and the ball. The first level is just on the ground, so I focused on making it work on the first day. I made a tree, implemented the golfing mechanics like hitting the pole and going to the next level. I also made a simple system for the camera, which tries to keep the player, the ball, and the current pole in view, while the player always gets priority. In the evening, I added the first sound effects (more about those later).\n\n![ffe9786b-4a76-4561-b51c-7fd3453f2322.png](\/\/\/raw\/f53\/8\/z\/6c8ab.png)\n\nOn the second day, I finished the second level and worked a lot on the systems of chaining levels in the game. \u26f3 I polished the first level, made a few more levels, added some juice and effects, better aiming, more sounds, and improved the physics. I added a scoring system and a simple menu. Finally, I added the last \"end\" level, packed everything, and submitted it to the compo version of Ludum Dare. Phew!\n\n![image.png](\/\/\/raw\/f53\/8\/z\/6c8ac.png)\n\n# Planning\n\nThere\u2019s usually not much time, nor point, for planning during a game jam. I just drew a couple of my ideas and kept a simple checklist of things I wanted for the game. I usually do it like this for game jams. Here\u2019s how it all looked for Down Golf:\n\n![planning.jpg](\/\/\/raw\/f53\/8\/z\/6c8bd.jpg)\n\n# Tech\n\nI made this game, as usual, in **Godot**. \ud83e\udd16\u00a0I used **Aseprite** to draw the sprites and I recorded my own sound effects for the very first time. It was a lot of fun! No special microphone or anything, just my iPhone.\n\nI originally wanted to also include some music and I would have used **Ableton** for that. But as usual, I did not have enough time. I always put sounds and music as the last priority and then almost never get to them. \ud83d\udd07\n\nOther than that, **Git** as usual, and I used Itch.io\u2019s **Butler** to publish new builds easily and often.\n\n# Constructing levels\n\nOkay, let's start with the game levels. The game works like this \u2014 when the player gets the ball to the hole, it opens up and lets the player pass through, going down into the next level. That means that all of the levels are connected (chained) in one big \"main\" scene.\n\nIn Godot, this is actually pretty easy to do. I have one big scene called \"main\" which contains all the levels, the player character, the ball, and the camera. The levels are positioned in a way so they connect correctly.\n\n![CleanShot_2025-05-06_at_17.01.55.png](\/\/\/raw\/f53\/8\/z\/6c8ad.png)\n\nEach level is a separate scene so I could work on them separately. I also needed a way to run and test each level independently, so I would not have to rerun the whole game to get to the level I\u2019m currently working on. I constructed each level from smaller **objects** or **components** which are all independent on the rest of the game. I heavily use Godot\u2019s **signals**, too. Here\u2019s how a level looks:\n\n![CleanShot_2025-05-06_at_16.58.55.png](\/\/\/raw\/f53\/8\/z\/6c8ae.png)\n\nHere we go a little into the technical details. If you are not interested in the implementation, you can skip ahead. You can see that each level is sort of made from **small LEGO pieces**. \ud83d\udce6 The spawner is what ensures that each level works correctly when it is run either in the main scene or separately on its own. When it loads, it checks whether there is a player in the game, and when not \u2014 which is only when the level is run on its own \u2014 it spawns the player and the ball at its position. In the main scene with all the levels, the player and ball are already there, so the spawner does nothing.\n\n![CleanShot_2025-05-06_at_17.03.34.png](\/\/\/raw\/f53\/8\/z\/6c8af.png)\n\nOther LEGO pieces work similarly. I won\u2019t go into too many details here. The pole tracks whether it is \u201cactive\u201d, and when it is, it counts how many shots the player takes in the current level. It does this by hooking into the player\u2019s signal `ball_hit`.\n\n![CleanShot_2025-05-06_at_17.08.01.png](\/\/\/raw\/f53\/8\/z\/6c8b0.png)\n\n![CleanShot_2025-05-06_at_17.08.09.png](\/\/\/raw\/f53\/8\/z\/6c8b2.png)\n\nYou can see that I rely heavily on groups and `@export` variables. I love writing scripts this way, it keeps them **independent** of each other and the scene structure. You will see a similar theme with the game objects (described below). \ud83d\udc40\n\nIf you are curious, check out the full source code of the game on GitHub: https:\/\/github.com\/martindzejky\/down-golf\n\nYou may be curious how all this connects in the \"main\" scene, the game. Well, it's actually very simple. Essentially, when a level is completed, it emits signals `ball_entered_hole` and `player_entered_hole`. I connect these signals between the levels in the editor, which means that when one level emits these signals, it calls the \"activate\" function in the next level.\n\nWhat I could have done better here is that, instead of placing and connecting the levels manually in the editor myself, I could have created a \"manager\" object with an array of levels. It would place and connect the levels automatically based on their \"enter\" and \"exit\" points, so they would be chained nicely. This would have also allowed me to load one level at a time and to allow the player to restart only the current level, instead of the whole game like it is right now.\n\nAll in all, I'm really proud of how I structured the levels. They are **flexible, independent, and easily testable on their own**. \ud83c\udf89\n\n# Game objects\n\nIn Godot, all game objects are just scenes \u2014 trees of nodes. I think the best practice is to try to **use as many small nodes to implement object behavior** as possible, instead of doing everything in script. This is called \"declarative\" programming, rather than \"imperative\". Using nodes, you \"describe\" the behavior of the game object and configure and connect the nodes to do that, instead of coding everything yourself.\n\nFor example, this means using Timer nodes to implement waiting a fixed time, instead of doing that in code; or heavily using the AnimationPlayer node to control all animations and scripted behaviors. Did you know that an animation in Godot can control **any other parameter of any other node**, as well as **call any function** during the animation? \ud83e\udd2f Very powerful!\n\nHere's the player object as an example. Notice how many nodes it consists of.\n\n![CleanShot_2025-05-07_at_10.10.23.png](\/\/\/raw\/f53\/8\/z\/6c8b3.png)\n\nI also needed to have a simple state machine for the player, because the player can be moving around, aiming, or shooting the ball. These states are mutually exclusive. I would usually also do this with nodes, but here for simplicity I just used a single `enum` and a variable `current_state` in the script, along with a fairly small match (switch) statement.\n\n![CleanShot_2025-05-07_at_10.12.34.png](\/\/\/raw\/f53\/8\/z\/6c8b4.png)\n\n![CleanShot_2025-05-07_at_10.12.45.png](\/\/\/raw\/f53\/8\/z\/6c8b5.png)\n\nThe ball is similarly very simple. It's basically a rigid-body physics object that displays particles and plays sounds when it collides with anything.\n\n![CleanShot_2025-05-07_at_10.14.08.png](\/\/\/raw\/f53\/8\/z\/6c8b6.png)\n\nOne last example. Here's the pole and its nodes. \u26f3 Its script is also fairly simple, it just detects when the ball or the player enters the hole, and emits appropriate signals. It plays an animation, displays particles, and plays sounds. That's all.\n\n![CleanShot_2025-05-07_at_10.16.06.png](\/\/\/raw\/f53\/8\/z\/6c8b7.png)\n\nNotice that all the objects are **independent of each other**. For example, the ball object does not use any external state or other objects. The pole is detecting collisions using its area colliders and collision groups. It does need to know when the player hits the ball, and I'm using groups and signals for these kinds of **soft dependencies**. It works very well and I don't have to connect the objects in any way in the editor.\n\n![CleanShot_2025-05-06_at_17.08.01.png](\/\/\/raw\/f53\/8\/z\/6c8b0.png)\n\n![CleanShot_2025-05-06_at_17.08.09.png](\/\/\/raw\/f53\/8\/z\/6c8b2.png)\n\nUsing groups is an excellent way to work with game objects in Godot. For example, I always have a \"player\" group and there's usually just a single player in the game, so it is easy to get access to it from anywhere using `get_tree().get_first_node_in_group('player')`. Similarly, all poles in the game are in the \"pole\" group, and it is very easy to look up or even deactivate all poles in the game at once using `get_tree().call_group('pole', 'make_inactive')`.\n\nUsing signals is another Godot way of hooking up game objects. \ud83d\udce3 It ensures that, for instance in my game, the pole game object does not have to care how ball hitting is made in the player object. It just uses the `ball_hit` signal, that's all it cares about, and then it is the responsibility of the player object to implement and emit the signal. **Simple inputs and outputs**, which I always like to work with!\n\nAgain, I won't go into more detail here, but if you are interested, check out the full source code of the game: https:\/\/github.com\/martindzejky\/down-golf\n\n# Graphics\n\nAs I've mentioned, I drew the sprite and animations of the player character first. I also drew the ball, the pole with the flag, and the tree in the very first level. It took me a lot of time, actually, but I think the first level in the game is the best. It is close to the style that I envisioned for the game. I'm proud of what I achieved here. \ud83c\udf33\n\n![image.png](\/\/\/raw\/f53\/8\/z\/6c8b8.png)\n\nThe other levels, unfortunately, did not receive as much attention, and as a result, they look very blank and boring. I was focusing on implementing the game mechanics pretty much for the whole time, so I did not have much time (nor ideas) for how I would like the underground levels to look. All the levels pretty much look the same. \ud83d\ude35\u200d\ud83d\udcab\n\n![image 2.png](\/\/\/raw\/f53\/8\/z\/6c8b9.png)\n\nI learned once again during this game jam that I\u2019m a great programmer but not a great artist. I can implement game mechanics quite quickly and efficiently, but I spend way too much time on art, and the result is not that amazing. \ud83c\udfa8\u00a0Others have also noticed this:\n\n![CleanShot_2025-05-06_at_15.58.44.png](\/\/\/raw\/f53\/8\/z\/6c8ba.png)\n\n![CleanShot_2025-05-06_at_16.00.40.png](\/\/\/raw\/f53\/8\/z\/6c8bb.png)\n\n![CleanShot_2025-05-06_at_16.03.16.png](\/\/\/raw\/f53\/8\/z\/6c8bc.png)\n\nWhat can I do about this next time? Well, I can either team up with an artist \u2014 which I\u2019ve never done before so that would be an interesting new experience! \ud83c\udfa8\u00a0\u2014 or really focus on making games with great mechanics and super simple graphics. It can be done and there are a lot of successful indie games out there with very simple graphics.\n\nI also recently watched a video about using vector art instead of pixel art for games: https:\/\/www.youtube.com\/watch?v=rKt95peINyk It got me really curious! I\u2019ve never really tried that and it might be worth it for some future game jam as an experiment. In general, **I\u2019ve always defaulted to pixel art** for my games. I would like to try some other simple styles of visuals, too.\n\n# Audio\n\nFor the very first time, I did not use **Bfxr\/Sfxr** or anything similar for generating sound effects! I instead used\u2026 **a microphone and my own mouth**. \ud83c\udf99\ufe0f I recorded hilarious sound effects for hitting the ball, steps, jumping, the trampoline\u2026 The sounds in this game add so much charm to it and honestly make it what it is.\n\nI had a lot of fun recording these. We laughed so much with my girlfriend when I was making weird hit sounds into my mobile phone! \ud83d\ude06 This was honestly **one of the best parts of this game jam** for me.\n\nThat's where it ends, though, for audio. I wish I had recorded and added some small ambience sounds. That would have added a lot of depth to the levels. There's also no music \u2014 I just did not have the time and I did not want to just slap in some AI-generated track (which isn't even allowed in Ludum Dare AFAIK).\n\n# Posting videos\n\nAnother \"first time!\" While I was working on the game, I made and posted several short-form videos about the game and my time in the jam. This was an entirely new experience for me \u2014 I've never really made videos before, especially ones where I talk to the camera! This was a very valuable experience, and I will make sure to do this for all of my future jams since it was so amazing. It also brought a lot more visibility to the game, and some of my friends were following the development closely. Some are still poking me today about where the next video and the next game are\u2026 \ud83d\ude2c Again, such a great experience!\n\nCheck out all the videos about the game over here:\n\n[Down Golf \u26f3\ufe0f](https:\/\/youtube.com\/playlist?list=PL52FaSLR1fYgYbtqNZ-RoWnRCK8SwrO3V&si=1VH5RUq29c75oCrE)\n\n# Lessons learned\n\nOkay, so **what did I learn on this project**? Well, I really think I have a good game idea here. Lots of people played the game and liked it, and I got a ton of positive feedback about it. I think it's a unique idea and a good mash of genres. It could be worth making it into a \"full\" game \u2014 what do you think?\n\n**Sound effects were a big win** in this project. This was the very first time I tried making and recording my own sounds, and it paid off big time. It actually defines the game, IMO! If I ever turn this into a \"full\" version, it still has to use these sound effects! \ud83d\ude06\n\n**Graphics were a fail**, I think. I spent a lot of time on the few important sprites in the first level and the main character and ball sprites. They look good, but the rest of the game then looks terrible. I could have instead focused on using very simple, even primitive graphics, so I could focus more on the other parts of the game. That being said, the main player character does have charm, so perhaps it wasn't a waste of time.\n\nWhat caught me by surprise is that the **physics are inconsistent**. I have no idea whether this is Godot's problem or I'm doing something wrong in my own code. The ball is basically using the built-in Godot 2D physics \u2014 nothing special. I'm just applying an impulse when the player hits the ball \u2014 the impulse is always applied at the center of the ball. And yet, sometimes the ball seems to fly in a different direction than the player was aiming for. This happens especially often when the ball is on a slope. I will have to do more experimentation here (an upcoming video? \ud83d\ude0f)\u2026 Although to be fair, I don't have that much experience with 2D physics.\n\nAnother big fail is that **I did not leave myself enough time for adding more mechanics**. The platforming aspect of the game is especially dry; there's not much to do aside from just jumping. I did manage to implement trampolines into the game and they are so much fun. But I had a lot more ideas for how to make the golfing levels more interesting.\n\nOn the other hand, **I really enjoyed working with Godot again** and using \"clean\" systems to implement the mechanics. I love that the **levels are self-contained and isolated** from each other, and I love how **objects are made from simple components**. It was very enjoyable to work with and easy to tweak and change when I needed. \ud83d\ude0c\n\n**Overall**, I had a lot of fun with this project. I enjoyed what I'm good at \u2014 programming and development of **game systems** \u2014 and I added 2 new things which I truly enjoyed \u2014 my own **sounds** and making **videos**. At the same time, I struggled with the same things I usually struggle with \u2014 **no music**, wasting time with **not great graphics**, and focusing too much on **pretty and clean code** rather than implementing a lot more game mechanics which would make the game more interesting.\n\n# Outro\n\nThank you very much for reading this retrospective! It was great for me to finally sit down and write this, even though I was procrastinating on it for a month. \ud83d\ude36\u200d\ud83c\udf2b\ufe0f\n\nIf you haven\u2019t yet played the game, check it out here: https:\/\/martindzejky.itch.io\/down-golf\nThe Ludum Dare submission page with comments is right here: https:\/\/ldjam.com\/events\/ludum-dare\/57\/down-golf\n\n**Please let me know if anything interested you** in this article, or if you have **any comments or questions**. I\u2019ll be happy to reply!\n\nMy next step is to make a long-form YouTube video out of this retrospective. \ud83d\udcfd\ufe0f\u00a0Wish me luck \u2014 I\u2019ve never made this before. Then, I\u2019m eager to jump into a new game project. Or, who knows, continue working on this one and exploring more ideas? Let me know if you would be interested.","scope":"public","node-timestamp":"2025-05-12T14:15:23Z","meta":[],"path":"\/events\/ludum-dare\/57\/down-golf\/post-mortem-retrospective-of-my-golfing-game","parents":[1,5,9,406845,408232],"files":[],"files-timestamp":0,"love":8,"love-timestamp":"2025-05-19T07:06:57Z","comments":1,"comments-timestamp":"2025-05-12T23:14:42Z","_wayback":{"timestamp":"20250525111447","url":"https:\/\/api.ldjam.com\/vx\/node2\/get\/415495+415494+415492+415491+415488+415487+415486+415484+415481+415479?author&parent&superparent"}},"node_metadata":{"n_key":"415487","n_urlkey":"295637","n_parent":"408232","n_path":"\/events\/ludum-dare\/57\/down-golf\/post-mortem-retrospective-of-my-golfing-game","n_slug":"post-mortem-retrospective-of-my-","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"33631","n_created":"1747058285","n_modified":"1747638417","n_version":"1313094","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/57\/down-golf\/post-mortem-retrospective-of-my-golfing-game","text":"# Intro\n\nI made a cute and crazy golfing game for the Ludum Dare 57! I think I managed to build pretty cool game ideas and mechanics, based on the **\"depths\"** theme. This was over a month ago. Yeah\u2026 it took me a month of procrastination to finally sit down and write this. But better late than never, here we go!\n\n# Game jam\n\nI couldn't sleep well the night before the Ludum Dare began, so I had some time to think about what kind of game I wanted to make for the theme. I usually spend about the first half of the first day thinking about game ideas. But this time it was actually quite quick. Of course, the first ideas that came to my mind were games about caves, mining, and fishing. While I love these kinds of games (Minecraft, Terraria \u2764\ufe0f\u200d\ud83d\udd25), I wanted to do something more original.\n\nI got the idea to make a **golfing game, but each hole would lead into the next level**. I had never made a golfing game before, so this was\u2026 seductive! It would also be about **platforming** since the player would always have to get to the ball physically, and also get to the hole in the end to progress to the next level. I love platformers, so another plus point for this idea.\n\nBTW, if you're interested in caves and mining just like I am, here's one amazing video I recently saw about a mining game made for this Ludum Dare. I love how it looks, works, and feels! Check it out: [How I made a procedural cave game in 48 hours | Ludum Dare 57 Devlog](https:\/\/youtu.be\/D6YEypAf4pU?si=Ag6HZ5CnprV4B2At)\n\nI immediately jumped into making the game in the morning. I prototyped the golfing physics and having the player hit the ball. I drew a (quite nice, IMO) sprite and animations for the player and the ball. The first level is just on the ground, so I focused on making it work on the first day. I made a tree, implemented the golfing mechanics like hitting the pole and going to the next level. I also made a simple system for the camera, which tries to keep the player, the ball, and the current pole in view, while the player always gets priority. In the evening, I added the first sound effects (more about those later).\n\n![ffe9786b-4a76-4561-b51c-7fd3453f2322.png](\/\/\/raw\/f53\/8\/z\/6c8ab.png)\n\nOn the second day, I finished the second level and worked a lot on the systems of chaining levels in the game. \u26f3 I polished the first level, made a few more levels, added some juice and effects, better aiming, more sounds, and improved the physics. I added a scoring system and a simple menu. Finally, I added the last \"end\" level, packed everything, and submitted it to the compo version of Ludum Dare. Phew!\n\n![image.png](\/\/\/raw\/f53\/8\/z\/6c8ac.png)\n\n# Planning\n\nThere\u2019s usually not much time, nor point, for planning during a game jam. I just drew a couple of my ideas and kept a simple checklist of things I wanted for the game. I usually do it like this for game jams. Here\u2019s how it all looked for Down Golf:\n\n![planning.jpg](\/\/\/raw\/f53\/8\/z\/6c8bd.jpg)\n\n# Tech\n\nI made this game, as usual, in **Godot**. \ud83e\udd16\u00a0I used **Aseprite** to draw the sprites and I recorded my own sound effects for the very first time. It was a lot of fun! No special microphone or anything, just my iPhone.\n\nI originally wanted to also include some music and I would have used **Ableton** for that. But as usual, I did not have enough time. I always put sounds and music as the last priority and then almost never get to them. \ud83d\udd07\n\nOther than that, **Git** as usual, and I used Itch.io\u2019s **Butler** to publish new builds easily and often.\n\n# Constructing levels\n\nOkay, let's start with the game levels. The game works like this \u2014 when the player gets the ball to the hole, it opens up and lets the player pass through, going down into the next level. That means that all of the levels are connected (chained) in one big \"main\" scene.\n\nIn Godot, this is actually pretty easy to do. I have one big scene called \"main\" which contains all the levels, the player character, the ball, and the camera. The levels are positioned in a way so they connect correctly.\n\n![CleanShot_2025-05-06_at_17.01.55.png](\/\/\/raw\/f53\/8\/z\/6c8ad.png)\n\nEach level is a separate scene so I could work on them separately. I also needed a way to run and test each level independently, so I would not have to rerun the whole game to get to the level I\u2019m currently working on. I constructed each level from smaller **objects** or **components** which are all independent on the rest of the game. I heavily use Godot\u2019s **signals**, too. Here\u2019s how a level looks:\n\n![CleanShot_2025-05-06_at_16.58.55.png](\/\/\/raw\/f53\/8\/z\/6c8ae.png)\n\nHere we go a little into the technical details. If you are not interested in the implementation, you can skip ahead. You can see that each level is sort of made from **small LEGO pieces**. \ud83d\udce6 The spawner is what ensures that each level works correctly when it is run either in the main scene or separately on its own. When it loads, it checks whether there is a player in the game, and when not \u2014 which is only when the level is run on its own \u2014 it spawns the player and the ball at its position. In the main scene with all the levels, the player and ball are already there, so the spawner does nothing.\n\n![CleanShot_2025-05-06_at_17.03.34.png](\/\/\/raw\/f53\/8\/z\/6c8af.png)\n\nOther LEGO pieces work similarly. I won\u2019t go into too many details here. The pole tracks whether it is \u201cactive\u201d, and when it is, it counts how many shots the player takes in the current level. It does this by hooking into the player\u2019s signal `ball_hit`.\n\n![CleanShot_2025-05-06_at_17.08.01.png](\/\/\/raw\/f53\/8\/z\/6c8b0.png)\n\n![CleanShot_2025-05-06_at_17.08.09.png](\/\/\/raw\/f53\/8\/z\/6c8b2.png)\n\nYou can see that I rely heavily on groups and `@export` variables. I love writing scripts this way, it keeps them **independent** of each other and the scene structure. You will see a similar theme with the game objects (described below). \ud83d\udc40\n\nIf you are curious, check out the full source code of the game on GitHub: https:\/\/github.com\/martindzejky\/down-golf\n\nYou may be curious how all this connects in the \"main\" scene, the game. Well, it's actually very simple. Essentially, when a level is completed, it emits signals `ball_entered_hole` and `player_entered_hole`. I connect these signals between the levels in the editor, which means that when one level emits these signals, it calls the \"activate\" function in the next level.\n\nWhat I could have done better here is that, instead of placing and connecting the levels manually in the editor myself, I could have created a \"manager\" object with an array of levels. It would place and connect the levels automatically based on their \"enter\" and \"exit\" points, so they would be chained nicely. This would have also allowed me to load one level at a time and to allow the player to restart only the current level, instead of the whole game like it is right now.\n\nAll in all, I'm really proud of how I structured the levels. They are **flexible, independent, and easily testable on their own**. \ud83c\udf89\n\n# Game objects\n\nIn Godot, all game objects are just scenes \u2014 trees of nodes. I think the best practice is to try to **use as many small nodes to implement object behavior** as possible, instead of doing everything in script. This is called \"declarative\" programming, rather than \"imperative\". Using nodes, you \"describe\" the behavior of the game object and configure and connect the nodes to do that, instead of coding everything yourself.\n\nFor example, this means using Timer nodes to implement waiting a fixed time, instead of doing that in code; or heavily using the AnimationPlayer node to control all animations and scripted behaviors. Did you know that an animation in Godot can control **any other parameter of any other node**, as well as **call any function** during the animation? \ud83e\udd2f Very powerful!\n\nHere's the player object as an example. Notice how many nodes it consists of.\n\n![CleanShot_2025-05-07_at_10.10.23.png](\/\/\/raw\/f53\/8\/z\/6c8b3.png)\n\nI also needed to have a simple state machine for the player, because the player can be moving around, aiming, or shooting the ball. These states are mutually exclusive. I would usually also do this with nodes, but here for simplicity I just used a single `enum` and a variable `current_state` in the script, along with a fairly small match (switch) statement.\n\n![CleanShot_2025-05-07_at_10.12.34.png](\/\/\/raw\/f53\/8\/z\/6c8b4.png)\n\n![CleanShot_2025-05-07_at_10.12.45.png](\/\/\/raw\/f53\/8\/z\/6c8b5.png)\n\nThe ball is similarly very simple. It's basically a rigid-body physics object that displays particles and plays sounds when it collides with anything.\n\n![CleanShot_2025-05-07_at_10.14.08.png](\/\/\/raw\/f53\/8\/z\/6c8b6.png)\n\nOne last example. Here's the pole and its nodes. \u26f3 Its script is also fairly simple, it just detects when the ball or the player enters the hole, and emits appropriate signals. It plays an animation, displays particles, and plays sounds. That's all.\n\n![CleanShot_2025-05-07_at_10.16.06.png](\/\/\/raw\/f53\/8\/z\/6c8b7.png)\n\nNotice that all the objects are **independent of each other**. For example, the ball object does not use any external state or other objects. The pole is detecting collisions using its area colliders and collision groups. It does need to know when the player hits the ball, and I'm using groups and signals for these kinds of **soft dependencies**. It works very well and I don't have to connect the objects in any way in the editor.\n\n![CleanShot_2025-05-06_at_17.08.01.png](\/\/\/raw\/f53\/8\/z\/6c8b0.png)\n\n![CleanShot_2025-05-06_at_17.08.09.png](\/\/\/raw\/f53\/8\/z\/6c8b2.png)\n\nUsing groups is an excellent way to work with game objects in Godot. For example, I always have a \"player\" group and there's usually just a single player in the game, so it is easy to get access to it from anywhere using `get_tree().get_first_node_in_group('player')`. Similarly, all poles in the game are in the \"pole\" group, and it is very easy to look up or even deactivate all poles in the game at once using `get_tree().call_group('pole', 'make_inactive')`.\n\nUsing signals is another Godot way of hooking up game objects. \ud83d\udce3 It ensures that, for instance in my game, the pole game object does not have to care how ball hitting is made in the player object. It just uses the `ball_hit` signal, that's all it cares about, and then it is the responsibility of the player object to implement and emit the signal. **Simple inputs and outputs**, which I always like to work with!\n\nAgain, I won't go into more detail here, but if you are interested, check out the full source code of the game: https:\/\/github.com\/martindzejky\/down-golf\n\n# Graphics\n\nAs I've mentioned, I drew the sprite and animations of the player character first. I also drew the ball, the pole with the flag, and the tree in the very first level. It took me a lot of time, actually, but I think the first level in the game is the best. It is close to the style that I envisioned for the game. I'm proud of what I achieved here. \ud83c\udf33\n\n![image.png](\/\/\/raw\/f53\/8\/z\/6c8b8.png)\n\nThe other levels, unfortunately, did not receive as much attention, and as a result, they look very blank and boring. I was focusing on implementing the game mechanics pretty much for the whole time, so I did not have much time (nor ideas) for how I would like the underground levels to look. All the levels pretty much look the same. \ud83d\ude35\u200d\ud83d\udcab\n\n![image 2.png](\/\/\/raw\/f53\/8\/z\/6c8b9.png)\n\nI learned once again during this game jam that I\u2019m a great programmer but not a great artist. I can implement game mechanics quite quickly and efficiently, but I spend way too much time on art, and the result is not that amazing. \ud83c\udfa8\u00a0Others have also noticed this:\n\n![CleanShot_2025-05-06_at_15.58.44.png](\/\/\/raw\/f53\/8\/z\/6c8ba.png)\n\n![CleanShot_2025-05-06_at_16.00.40.png](\/\/\/raw\/f53\/8\/z\/6c8bb.png)\n\n![CleanShot_2025-05-06_at_16.03.16.png](\/\/\/raw\/f53\/8\/z\/6c8bc.png)\n\nWhat can I do about this next time? Well, I can either team up with an artist \u2014 which I\u2019ve never done before so that would be an interesting new experience! \ud83c\udfa8\u00a0\u2014 or really focus on making games with great mechanics and super simple graphics. It can be done and there are a lot of successful indie games out there with very simple graphics.\n\nI also recently watched a video about using vector art instead of pixel art for games: https:\/\/www.youtube.com\/watch?v=rKt95peINyk It got me really curious! I\u2019ve never really tried that and it might be worth it for some future game jam as an experiment. In general, **I\u2019ve always defaulted to pixel art** for my games. I would like to try some other simple styles of visuals, too.\n\n# Audio\n\nFor the very first time, I did not use **Bfxr\/Sfxr** or anything similar for generating sound effects! I instead used\u2026 **a microphone and my own mouth**. \ud83c\udf99\ufe0f I recorded hilarious sound effects for hitting the ball, steps, jumping, the trampoline\u2026 The sounds in this game add so much charm to it and honestly make it what it is.\n\nI had a lot of fun recording these. We laughed so much with my girlfriend when I was making weird hit sounds into my mobile phone! \ud83d\ude06 This was honestly **one of the best parts of this game jam** for me.\n\nThat's where it ends, though, for audio. I wish I had recorded and added some small ambience sounds. That would have added a lot of depth to the levels. There's also no music \u2014 I just did not have the time and I did not want to just slap in some AI-generated track (which isn't even allowed in Ludum Dare AFAIK).\n\n# Posting videos\n\nAnother \"first time!\" While I was working on the game, I made and posted several short-form videos about the game and my time in the jam. This was an entirely new experience for me \u2014 I've never really made videos before, especially ones where I talk to the camera! This was a very valuable experience, and I will make sure to do this for all of my future jams since it was so amazing. It also brought a lot more visibility to the game, and some of my friends were following the development closely. Some are still poking me today about where the next video and the next game are\u2026 \ud83d\ude2c Again, such a great experience!\n\nCheck out all the videos about the game over here:\n\n[Down Golf \u26f3\ufe0f](https:\/\/youtube.com\/playlist?list=PL52FaSLR1fYgYbtqNZ-RoWnRCK8SwrO3V&si=1VH5RUq29c75oCrE)\n\n# Lessons learned\n\nOkay, so **what did I learn on this project**? Well, I really think I have a good game idea here. Lots of people played the game and liked it, and I got a ton of positive feedback about it. I think it's a unique idea and a good mash of genres. It could be worth making it into a \"full\" game \u2014 what do you think?\n\n**Sound effects were a big win** in this project. This was the very first time I tried making and recording my own sounds, and it paid off big time. It actually defines the game, IMO! If I ever turn this into a \"full\" version, it still has to use these sound effects! \ud83d\ude06\n\n**Graphics were a fail**, I think. I spent a lot of time on the few important sprites in the first level and the main character and ball sprites. They look good, but the rest of the game then looks terrible. I could have instead focused on using very simple, even primitive graphics, so I could focus more on the other parts of the game. That being said, the main player character does have charm, so perhaps it wasn't a waste of time.\n\nWhat caught me by surprise is that the **physics are inconsistent**. I have no idea whether this is Godot's problem or I'm doing something wrong in my own code. The ball is basically using the built-in Godot 2D physics \u2014 nothing special. I'm just applying an impulse when the player hits the ball \u2014 the impulse is always applied at the center of the ball. And yet, sometimes the ball seems to fly in a different direction than the player was aiming for. This happens especially often when the ball is on a slope. I will have to do more experimentation here (an upcoming video? \ud83d\ude0f)\u2026 Although to be fair, I don't have that much experience with 2D physics.\n\nAnother big fail is that **I did not leave myself enough time for adding more mechanics**. The platforming aspect of the game is especially dry; there's not much to do aside from just jumping. I did manage to implement trampolines into the game and they are so much fun. But I had a lot more ideas for how to make the golfing levels more interesting.\n\nOn the other hand, **I really enjoyed working with Godot again** and using \"clean\" systems to implement the mechanics. I love that the **levels are self-contained and isolated** from each other, and I love how **objects are made from simple components**. It was very enjoyable to work with and easy to tweak and change when I needed. \ud83d\ude0c\n\n**Overall**, I had a lot of fun with this project. I enjoyed what I'm good at \u2014 programming and development of **game systems** \u2014 and I added 2 new things which I truly enjoyed \u2014 my own **sounds** and making **videos**. At the same time, I struggled with the same things I usually struggle with \u2014 **no music**, wasting time with **not great graphics**, and focusing too much on **pretty and clean code** rather than implementing a lot more game mechanics which would make the game more interesting.\n\n# Outro\n\nThank you very much for reading this retrospective! It was great for me to finally sit down and write this, even though I was procrastinating on it for a month. \ud83d\ude36\u200d\ud83c\udf2b\ufe0f\n\nIf you haven\u2019t yet played the game, check it out here: https:\/\/martindzejky.itch.io\/down-golf\nThe Ludum Dare submission page with comments is right here: https:\/\/ldjam.com\/events\/ludum-dare\/57\/down-golf\n\n**Please let me know if anything interested you** in this article, or if you have **any comments or questions**. I\u2019ll be happy to reply!\n\nMy next step is to make a long-form YouTube video out of this retrospective. \ud83d\udcfd\ufe0f\u00a0Wish me luck \u2014 I\u2019ve never made this before. Then, I\u2019m eager to jump into a new game project. Or, who knows, continue working on this one and exploring more ideas? Let me know if you would be interested.","title":"Post-mortem retrospective of my golfing game","wayback_source":{"timestamp":"20250525111447","url":"https:\/\/api.ldjam.com\/vx\/node2\/get\/415495+415494+415492+415491+415488+415487+415486+415484+415481+415479?author&parent&superparent"}}