Ludum Dare 49: 48 Hours, One Game and a Bunch of Physics Calculations

[link-standalone]

Last weekend I took part in Ludum Dare 49. The theme was “Unstable” and I developed a platformer involving a bunch of unstable platforms. It’s called Watch Your Step and can be played in your browser here. You can also find the source code here. I haven’t done much work on my adventure game prototype the last couple of weeks, I’m instead writing a blog post about the game, how it came to be, and lessons I might apply to development of other games.

Tools I used for this project:

I also used some of the editor scripts I’ve written for the adventure game prototype which proved useful for the sprite animations.

Planning

Ludum Dare is a biannual game jam that takes place every April and October since 2002. Participants can choose to enter either the Jam (3 days) or the Compo (2 days). The Compo is a solo event and is taken a bit more seriously. All assets are meant to be created by the developer within the 48 hour time period, though you can decide to exclude asset types from being judged. This will be the fourth Ludum Dare I have participated in in a row and the fifth overall. For my first event I participated in the Jam but found that working three days in a row was a bit too much. Obviously I could take it more slowly but I ended up feeling pressed for time anyway. The Compo also fits nicely in a weekend, starting in the UK at 2am on the Saturday in April and 11pm on the Friday in October.

For the previous events, I would spend an hour planning and then try and squeeze out as much as possible in gameplay, spending maybe three hours on art and an hour or two on sound but I wasn’t particularly strict about it. This made my games have a lot of half-finished mechanics as well and worse than “programmer” art and sound. This time, I planned out how I would work during the event to the hour, including when I would eat and sleep.

Screenshot of my schedule for the weekend. This did not change much from the original plan. The main change is the addition of time for creating levels

As you can see from the spreadsheet above, most of the time is still spent on game development. However, there is also six hours just for art, three for music and sound, and two to do any last minute “polish”. When I decided I would develop a platformer, I replaced two of the gameplay hours with hours to work on levels, as I usually ended up rushing to create levels in the Sunday evening of the event. As you can see from the finished result, this led to a much more cohesive experience compared to my previous jams.

Initial Ideas

The theme was announced at 11pm UK times on Friday 1st October which was “Unstable”. Before going to bed, I planned what type of game I would develop. I was initially interested in developing a platformer as I would end up using some of the lessons learned to help with development of The Pilgrimage. However, I took the theme and thought about doing it in a more abstract way: mental stability. The idea was that you would be a freelance writer (originally an office worker à la Office Space) who would try to get work done while balancing their physical and mental health. It would be a point and click game, mostly taking place at a desk where you would click to do a particular action and manage resources such as stress, energy (tiredness) and money. You would just keep playing day by day until you gave up. I think it would be an interesting idea that could be developed to a playable game on Saturday and then adding more mechanics and art on Sunday. Happy with the idea, I went to bed on Friday close to midnight, happy that I had a good idea for event.

The next day, I completely changed my mind and went back to the platformer. My reasoning was that it would be a straightforward idea that would be very quick to get something out that is playable, compared to the more abstract resource management game. Also, I think drawing the scenes of the office would be more challenging for me to quickly look good compared to creating sprites for a platformer. I kind of regret the decision, as I feel like it would have been even more fun to work on something with a less common premise and mechanics. However, I think I’ll be more adventure next jam.

The idea behind the platformer would be simple: a 2D side-scroller where the player tries to move a character from left to right, avoiding enemies and trying not to fall. The more unusual mechanic would be balancing on tightropes which would involve both moving the character along and using the arrow keys to keep balance.

Art Changes

The original art style I came up with in the two hours on Saturday ended up resembling Super Mario Bros. It even had a flag pole at the end of the level. On Sunday, I decided instead to change the style to be sci-fi instead. This also added to the story, where the character is someone who needs to escape a collapsing city and avoid robots. Instead of a flag at the end of each level, instead the player would need to reach a portal. It then made sense to put a portal at the beginning of subsequent levels to make them feel more connected. I had also hoped to add a background to the game which would be a cityscape that would more slowly relative to the camera as the player moved across the level for that extra bit of immersion. Unfortunately I did not have the time in the end so had to settle for the default blue background.

Screenshot of the original art style, vaguely resembling Super Mario.
The final art style I had for the game.

Sounds and Music

For most of the sounds, I used rFXGen again. For the death and victory sounds, I quickly created them with a MIDI instrument in Ableton with a couple of notes. A descending tritone always work well for a quick “uh-oh” error sound. For getting them playing at the right time, I didn’t go for anything particularly sophisticated. Classes where actions will happen that result in a sound would contain a reference to the AudioSource and the AudioClip In a more serious project (like eventually in the The Pilgrimage), I would use a dedicated audio manager that events can be sent to and prevent too many sounds being played close to each other. Since you’re allowed some base code beforehand, I might end up using that in future projects once it its written.

For the music, originally I was going for something in minor and a bit faster paced. The mood I was originally trying to set was kind of frantic, where the player was trying to escape as quickly as possible. I spent the first hour of the two hours trying to get something work with an arpeggiated Cmin7 chord which ended up sounding pretty cool in isolation. It still sounded quite empty and I just couldn’t write a lead that would work. I was trying to write a melody in C minor but kept floating around the Eb and decided instead to write the track in Eb major instead and it ended up working quite well. It also produced a shift of mood to something a little more light-hearted, which worked better with the cartoonish movement of the main character. I wanted something that was not too short to be repetitive but also not too long. I settled on a 12 bar line that would repeat throughout the track. When adding chords, I ended up settling on a 12 bar blues and that also influenced how I ended up shaping the melody. I added a few extra layers including drums and it ended up sounding quite good within the two hours I had allotted myself. I then stuck in on an AudioSource and had it looping with a small break and that was it.

Equations of motion are annoying sometimes

As well as relying on the inbuilt physics engine including components such as the PlatformEffector2D, I also needed to do some physics calculations for other aspects of the game. These were the floating platforms and projectiles shot by enemies and I ended up spending a bit too much time on than I hoped.

Floating Platforms

The floating platform that was in the submitted game. It handles correcting linear movement quite nicely but is quite slow to correct rotation.

As well as having collapsible platforms that would shake for a bit before falling, I also wanted platforms that the player could jump on which would sink when the player walks on them and then eventually return to their original position. I ended up doing this using equations of motion I learned in secondary school. In particular:

v2 = u2 + 2as

where:

It took a while to figure out how to use this equation to get a result I liked. To summarise, it would accelerate either upwards or downwards if the platform was not in its original position or it was not stationary (or both). It would assume that it was accelerating in the opposite direction of its velocity and use the equation above to figure out the velocity it would be at the target position. If v2 was negative, then it can be reasoned that the platform would not ever reach the target position if the acceleration was constant. If the velocity was greater than 0, we would accelerate in the opposite direction of the target position. Otherwise, we would acceleration towards the targe position. I applied the same formula for the angular rotation and it worked well enough as can be seen from the video. I also restricted the maximum rotation in each direction. In this case I restricted it to 45 degrees either way mainly as it was a nice round number but would still give trouble to the player if they weren’t careful.

Retrospectively looking at some of the other Physics 2D components that are available, the TargetJoint2D component would have been a suitable substitute that seems to correct rotation much better. This would be added like I did with the HingeJoint2D component for the rotating platform. At least I will know to use it next time I might require it. I appreciated how much the Unity devs had actually put into developing not just the physics system but other components on top of it to make game developers’ lives easier.

An example of the floating platform with a TargetJoint2D attached with a max force of 70 (the mass of platform is 4), a damp ratio of 1.0 and a frequency of 5. It’s still restricted to rotate a maximum of 45 degrees.

Determining Trajectories for Projectiles

A crude diagram showing the variables needed for a projectile calculation. Both the initial velocity (u) and the final velocity (v) are unknown but we only care about the initial velocity.

I also had robots that would shoot projectiles. I didn’t have time to get the robots themselves to move but I did get them firing projectiles at the player from a stationary position. In order to hit their target, I would have to figure out the initial velocity that the projectile would need to have. After wrestling with the equations of motion for about an hour, I realised that there was a range of possible values for the initial velocity as the final velocity did not matter. I tried using inequalities but didn’t get very far and realised the practical solution was to sample a few initial velocities and work out if they would hit the target. I did this by applying the following equation:

s = ut + 1/2at2

where t is time. I calculated t from the x component quite easily as the acceleration is 0. I then used that value in the equation for the y component to calculate the initial velocity of the y component, since I knew the displacement of the target (the player) from the firing position. If the magnitude of the entire initial velocity is close to the magnitude I wanted, that would be the magnitude of the projectile. If not, I would pick another initial x velocity. For each projectile, 1000 samples are tried.

I had settled on a target initial velocity magnitude on 7.5. I tried 10 but found it a bit too fast for me as it was nearly impossible to dodge out of the way. People who ended up playing the game thought that this was still too fast. If I had a bit more time to playtest I might have found this out before the submission deadline.

What I got out of it

Over the course of the 48 hours, I learnt a few things that could be useful for other game projects and one that is a lot more universal.

Deadlines are useful

As well as game development and my day job, I also enjoy making music. Though I find myself a lot of the time being overwhelmed by choice and pressured to make a perfect track. In this event I only allotted myself two hours and was able to produce a track that was acceptable. Deadlines can make it a lot easier to cut scope and not worry about making something that is “perfect”. It can also lead to taking shortcuts that can be beneficial. Though I probably won’t give myself deadlines like “make a track in two hours”, I might try using deadlines over a longer period of time such as making 10 tracks in a week, or the approximate deadlines I have for the phases of The Pilgrimage and for my devlog posts.

Being prepared before the event is important

In previous jams, I was never prepared for the event. I usually forgot to even have an empty Unity project. This time I wanted to take the event a bit more seriously as I was working on it alongside my main project. First of all, I planned my scheduled for the 48 hours so it was easy to see sections I might want to move around or cut out and replace with different activities. I also had editor scripts from my other projects prepared that would quickly create animations from sprites. This was very helpful for the project as I could change sprites on the fly and they would work perfectly in the game. It really paid off as I wasn’t spending time messing around with tools and how they worked and instead could just develop the game and create its assets.

Unity Physics Components

As mentioned before, Unity no only has rigidbodies and colliders as part of the physics system but also effectors and other components that I was not really aware of until this jam. In particular, I ended up using the HingeJoint2D and the PlatformEffector2D components. The platform effector is nice as you can constrain colliders to a segment of a particular degree. In that case it’s easy to allow characters to jump from underneath platforms and on to them. The hinge component was used to have platforms that rotate around a point. In this case they did not rotate themselves but would be moved by the player. The video below shows both of the effectors in use for one platform.

A rotating platform in the game with the player interacting with it. Notice that the player can jump onto it from below. This is due to the PlatformEffector2D component.

Though the main game I’m working on isn’t a platformer, it will have physics at least concerning collisions and now I am more aware of the extent of the components that Unity already provides that may be useful.

I did enjoy this Ludum Dare event (as I usually do) and found that planning and having a clear idea from the beginning really help with developing a full (though simple game). I think for next time in April I want to try a more original/interesting idea like the initial resource management game, even at the cost of other elements of the game.