pingpoli.de



Ludum Dare 48 Post-Mortem

Creating a game completely from scratch in 48 hours

28.04.2021 - 09:49
Last weekend, the 48th edition of Ludum Dare took place. Ludum Dare is a game jam where you have 48 hours to create a game completely from scratch. This includes all of the programming, every art asset, every sound effect, the music, everything.

A theme is announced at the beginning of the event, but it is generally a loose theme, so a wide range of games can be submitted. The theme this time around was "Deeper and deeper".

Technology

For the past Ludum Dare events, I have either used my C++/OpenGL engine or HTML5/JavaScript, both of which work pretty well for a game jam. However, in the past weeks, I have been working with Babylon.js, a JavaScript WebGL engine. So for this edition, I wanted to make a game with Babylon.js to test its feasibility for game jams.

I have been favoring JavaScript games over C++ in recent events because browser-based games are a lot easier for others to play and judge. They don’t have to download and install anything and they work on every operating system. So having the option to create 3D WebGL games with Babylon.js would be a great benefit for future events.

Theme

The theme for this Ludum Dare was "Deeper and deeper". When I saw the announcement I wasn’t too excited. My first ideas were all 2D games where going down on the screen meant going deeper into something, but I wanted to make a 3D game this time around. So I sat there for a while brainstorming ideas, but I couldn’t come up with a great concept.

When I thought about game mechanics, however, there was one idea that kept coming back to me. A game inspired by castle fight, an old Warcraft III custom map, where you have two teams with a castle each and you build spawners that send mobs to attack the enemy’s castle.

So in the end, I decided to go with that idea and make a mining-themed castle fight-like game. Both players have a huge pile of gold to defend and at the same time try to mine their opponent's gold. Just like in castle fight you can build buildings that spawn minions, which fight against each other, can destroy the buildings, and mine the enemy's gold. In addition to spawner buildings, I also added a gold mine, which provides a base income and a turret, that can be used as additional core defense.

Implementation

Once I had a rough idea of how the game was going to work, I started the implementation. In a game jam, the first step is always to create a basic prototype with the core mechanics. In this case, I started with building construction. When the player selects a building and then clicks on the ground plane, I had to figure out the coordinates of the click and convert it to a tile position and place a building on that tile. Even though vanilla JavaScript has no class inheritance, I made a building superclass, which handles functions shared by every type of building. Then I added subclasses for every building type that have an object of the superclass and other, building-specific functions.

After that, I worked on entity spawning and movement, which was the most time-consuming programming task. I wanted to have walls with gates around the player areas to indicate their territory. However, this meant that I had to come up with a way to make the entities walk through the gates without implementing a fully-blown pathfinding algorithm. I ended up with a fairly hardcoding solution, that works decently. It has a few issues though. When an entity sees an opponent its opponent chasing overrides the walking, so they can still go through the walls sometimes, which is a bit of a shame.

Then I worked on the combat system. The entities can attack each other, enemy buildings, and, of course, the gold pile. Because there are a bunch of different cases, especially after I added flying and ranged units that can only attack certain other units, the entity behavior code ended up being a bit of a mess, but I think it works convincingly enough to not impact the gameplay negatively.

The third major gameplay programming task was the AI that plays the opponent. Creating an AI in a game jam is always a risk because even when you have a lot of time it is a very difficult task, which means you probably won't be able to create a good AI with the limited time during an event. However, with some cheating, the AI ended up being good enough to emulate a bad human player. When you really try, you can always win against it though.

Early development progress, just some boxes to represent buildings and entities:


Graphics

One of the reasons why I wanted to try Babylon.js in a game jam was to have the ability to create web-based 3D games. I can create 3D games with my C++/OpenGL engine, but my WebGL code is a bit outdated and lacks features, so it’s not great for 3D games at the moment.

I went with a low poly, mostly non-textured look for the game, which is pretty much the only option you can go in a solo 48-hour game jam. I have been doing a lot of low poly modeling in Blender, so I can create simple low poly models quite quickly. Texturing, however, takes a lot more time, so it’s not feasible to texture every model. The only texture is on the floor, which would have been a big, flat, single-color plane otherwise, so I gave it some details with a texture instead. It would have been great to animate the entities for the game and I think it would have been possible, but I decided not to do it and save the time for other features. The entities are small enough so it's not too glaring that they are missing animations.

A look at the gold pile and the base with some buildings and entities:


Music

My music strategy for game jams is pretty simple. I have no idea how to compose music, so I just use a random music generator, which is allowed even in the Compo rules. For the last events, I have been using Wolfram Tones. It has a wide range of different music styles and you can usually create a decent sounding track within a few minutes. It has a maximum duration of 30 seconds, but people are only playing a game jam entry for a few minutes, so it doesn’t become too repetitive.

Sound Effects

Similar to music, I’m not great at creating sound effects. I don’t have the equipment, the software, or a lot of experience. However, just making weird sounds into the microphone or hitting random objects together works surprisingly well for game jams. I started with the gold mining sound by hitting scissors against a cup and it turned out great. The building constructions and demolishing sounds weren’t too bad either. But then I had to make sound effects for the dying entities and I spend several minutes making weird moaning sounds into my microphone and they were getting weirder by the minute. In the end, I decided to embrace the awkwardness of my death sounds and also made victory and game over jingles with my mouth.

UI

One of the big advantages of web-based games is the ability to use normal HTML elements for the user interface. Rather than having to learn the intricacies of the Babylon.js UI elements, I could just use HTML and CSS to create some basic UI elements for the game. I went with a wooden look, which is one of my favorite styles for video game interfaces. It’s easy to create a wood texture in Photoshop and add some jagged edges. At first, I wanted to make custom textures for the building buttons as well, but they looked decent enough with a plain gold color, so I just went with that.

A zoomed-out look at the game, you can see the bases of both players:


Tutorial

A feature that I always appreciate when playing other Ludum Dare entries is a good in-game tutorial. I started with an instruction scene when the game launches that briefly explains the goal of the game, which would have been good enough to submit. However, I had some time left near the end, so I added a step-by-step tutorial with small popups that tell the player what to build. When somebody plays the game for the first time, which will be the case when they are judging the game, it's going to be a very helpful feature.

Balancing

Balancing is the biggest weakness of my Ludum Dare game. When I was trying to balance the different buildings, entities, and the AI towards the end of the event, I wasn’t able to get them very balanced. And I also added a new building upgrade feature late in the development process, which made the balancing even worse.

Even when you have a lot of time, balancing a game is a very difficult task and even major games like League of Legends release new balance patches every few weeks. The only way to get close to a good balance is by trial and error, which is something you cannot do with a fixed deadline after which you cannot change the game anymore.

This is also the main criticism I got from a few people that have already played the game. They generally liked the game but mentioned that it isn’t well balanced.



Overall, I am happy with my Ludum Dare development process. I don’t think my game matches the theme very well, but I think it’s fun to play and that’s more important to me than a good theme fit. The balancing issues make it easy to win and can sometimes turn into a snowball effect, but watching a lot of entities fighting is quite interesting as well. Some things, like the miner and archer models and especially the death sounds, turned out a bit weird and derpy. But hey, humor is a voting category so maybe I got a shot.

As for Babylon.js: It worked pretty well. I didn’t have any major hiccups and I didn’t have to read the documentation too often. It’s a great and easy way to create a browser-based 3D game for a game jam. The only disadvantage is the performance. When there are slightly more entities on the screen, the game becomes laggy. There are probably some optimizations that could improve the framerate, but I don’t think even a naive usage should start to lag at only 100 or so moving entities.



If you want to try the game, you can do it here: pingpoli.de/ld48/

I have also filmed the complete development process and turned it into a timelapse:





by Christian - 28.04.2021 - 09:49


Comments

Social Media:  © pingpoli.de 2020 All rights reservedCookiesImpressum generated in 15 ms