pingpoli.de



Ludum Dare 50 Post Mortem

Creating a game from scratch in 48 hours

09.04.2022 - 13:05
Last weekend marked the 20th anniversary and the 50th installment of the very popular Ludum Dare game jam, where you have to create a game completely from scratch in 48 hours for a given theme. This includes all of the programming, graphics, UI, sound effects, music, and everything else that makes up a game. Here is a slightly-longer-than-ideal blog post about my thoughts and experiences during the event:

Theme and Idea

The theme for this event was Delay the Inevitable, which I wasn't a big fan of. My last Ludum Dare game had a major flaw: Playing the game felt very depressive and it was too difficult to win. The problem with that is that constantly losing is not a great player experience and therefore it didn't get good ratings.

The theme Delay the Inevitable sounded like another theme where you technically would never be able to win and only delay the loss as long as possible, which is something that I wanted to avoid after my lessons from the last event.

One of the ideas I had before the weekend was to create some kind of logistic/traffic management game inspired by Mini Metro, which is a game that is based on a Ludum Dare submission from a few years ago. When the theme was announced I wrote down a bunch of ideas and quickly narrowed it down to a shipping simulation game where the player would need to create and maintain global supply chains for as long as possible before they inevitably break down.

Finally, I wanted to take a slightly more relaxed approach to Ludum Dare because I have been quite busy in the past weeks, which meant limiting the scope even more than normal. However, it only lasted about an hour or so before I realized that my idea was still quite complicated and required a lot of work.

Programming

I once again used vanilla JavaScript and HTML canvas, because web-based games are a lot more convenient for people to judge, and for the most part, it's a low-hassle development environment.

I started with the implementation of the line connections between the ports and interconnects, which wasn't too difficult. But then, only an hour into development, my plans for a more relaxed Ludum Dare were already stopped. For whatever reason, it didn't cross my mind that my game idea required pathfinding when I thought of it. Luckily, I have a working implementation of A* in C++, so I only had to convert it to JavaScript and completely change the way I implemented the nodes and connections just a few minutes before. But because I only converted it and didn't have all its intricacies in mind, I missed a small detail, which meant that the path it found wasn't always the shortest possible path. It took me a while to find the issue and it turns out that using an exact value for the heuristic in A* wasn't a good idea. After changing it to the Manhattan approximation, it was finally working and always found the shortest path. One of the advantages of A* is that you can also include other costs of a connection besides only its geometric distance. A bit later, I implemented route congestion and slower traveling speeds along congested connections. When a new ship spawns and calculates its route it takes the congestion into account and finds the fastest path to its target, which may not always be the shortest.

A* pathfinding:


In games with many units, pathfinding is one of the most computationally heavy tasks and I wanted my game to have a decent number of ships at the same time to make it look busy. Therefore I wasn't sure, whether an average computer could handle all of the pathfinding, so I opted to only calculate the path of a ship once when it spawns and not recalculate it every few seconds. Recalculating the path would have been better so the ship could take dynamically-changing traffic conditions into account, but I don't think it hurts the game either way. It also means that ships can sometimes travel along a connection that is freshly deleted if it was still part of an old path, but I don't think it's a big problem either.

Besides the pathfinding, there wasn't anything majorly interesting about the programming of the game. The ports keep a queue of incoming ships and can only process one ship every so often, which can be lowered by hiring port workers and I implemented the pirates in a way so that they set the congestion of a route to a high number instead of outright blocking it. Blocking it would have required recalculating all paths to prevent the ships from traveling along a pirate-blocked route. Although in hindsight, this would have made the pirates much more interesting, because as they are right now, they aren't a big problem and you can mostly ignore them while playing the game.

Finally, I changed the money reward you get when a ship is processed in a port to be dependent on the average speed of the ship to make slow routes more punishing, but I don't think I made it punishing enough because you can mostly ignore it and still win the game.

Most mechanics are implemented:


Graphics

When creating games for Ludum Dare I typically go with pixel art. However, this time around I wanted to go for a more stylized and minimalistic look. Before the event, I had the rough idea of creating a game using only basic geometric shapes, i.e. only the shapes that HTML canvas supports natively. For a while, I considered using colored squares and circles to represent the ports, interconnects, and ships, but I ended up creating some simple graphics for them. Nevertheless, the final game has a fairly minimalistic style and I think it fits the game.

Sound Effects and Music

I always struggle with sound effects and music during game jams, but this time it was even worse. Partly because many of the sounds are very arbitrary. There isn't a real-world sound for connecting a port to a waypoint, so I couldn't come up with anything great. In past events, I experimented with spoken in-game announcements and I liked the idea, but not my voice-acting skills. Instead, I tried something new this time: I used a text-to-speech browser plugin and recorded the results. It was usable for some phrases like "pirates are blocking one of your routes" or the victory and loss messages, but for some reason, it struggled with pronouncing the word pandemic in "a global pandemic has increased demand" and I had to record that one myself anyway. So I ended up with a weird mix of voice styles and arbitrary sound effects. I don't think they actively hurt the game, but they aren't great either.

For the music, I went back to the Wolfram Tones procedural music generator after a failed attempt at using an online sequencer to make the music last time. You can generally get a nice piece of music after a few minutes of experimenting, and even though it has a maximum length of 30 seconds, it works well enough for a short Ludum Dare game. However, I still have the dream of being able to compose and create a short piece of music for a game jam by myself at some point or at the very least create my own music generator, so I'm never really happy with just using an existing solution.

Balancing

I didn't learn any lessons from last Ludum Dare when I made a game that was very difficult to balance, because my game once again was impossible to balance. Even though I had enough time for balancing on the second day, I don't think I managed to find a good solution. The biggest problem with the balance is that you can mostly ignore the pirates and you don't need to build any extra waypoints or add more connections. If you focus on hiring port workers it's pretty easy to win. The game has just too many complicated and interconnected systems to balance within a few hours during a game jam.

Polishing

In some ways, my plan of not overdoing it worked out because my time management was quite good. The game was mostly playable by the end of Saturday, which meant I was able to polish some aspects of it more than usual. One feature, that worked out very well is the popup texts, which either confirm an action or show an error. This gives a lot of feedback to the player and avoids confusion. It's also properly encapsulated in a class, so I can easily copy-paste it for the next event and make use of it again. The initial tutorial of the game, however, didn't turn out great. I was quite exhausted by the end, so I only did the bare minimum and added some basic text instructions before the game starts.

The final look of the game:


Development Timelapse

I once again recorded my complete development process and turned it into a timelapse:




Overall, the game turned out okay. I am happy with the gameplay and the visual style. It's pretty fun to connect the ports and watch the ships travel between them, kinda like observing a colony of ants. On the other hand, the sound effects didn't turn out great and the balancing is pretty bad because it makes some game mechanics mostly obsolete. At least it's pretty easy to win the game and it delivers a much more light-hearted experience compared to my last Ludum Dare game which you would almost always lose.



Play the game here: https://pingpoli.de/ld50/
Ludum Dare page: https://ldjam.com/events/ludum-dare/50/international-shipping-simulator




by Christian - 09.04.2022 - 13:05


Comments

555
by dwUQQUrL - 31.08.2022 - 00:32
Social Media:  © pingpoli.de 2020 All rights reservedCookiesImpressum generated in 25 ms