Doing Ludum Dare

I participated in Ludum Dare 45 this year.

Ludum Dare is a semi-annual competition where you attempt to make a game over a single weekend. There are two flavours. The first is the “Compo”, where you have 48 hours to make everything as a single individual (no teams). You must release your source code and all art must be your own (or, properly derived from existing assets that you have rights to use). The second is the “Jam”, where you have 72 hours, can work in a team, and enjoy slightly more relaxed rules.

I chose the Compo because it’s meant to be the ultimate test of your game development skills: 48 hours to develop everything yourself. The result of my work was Robo-Fort, shown here:

robofort-shot-1-compressed.gif

The theme for the competition was “start with nothing”. My application of this theme was that you started with nothing by having to push boxes and build a fort to defend precious cargo. You started with no fort, so you had to build one.

(Some folks, however, took this entirely to the next level: some entries had no graphics, resources, or even levels, and you had to find/build/buy them yourself in order to make the game playable. Now that’s creative! You should check them out.)

Before I started, I set a few ground rules for myself. I would still eat, shower, and sleep. I would also allocate a lot of time at the beginning to sort through my ideas and decide what I wanted to do. It turned out, this wasn’t a problem. When the event started, I was already an hour’s drive away from home and out with friends for a social obligation. That gave me plenty of time to let ideas marinate in my head after the theme was released. When I finally arrived at home, the event was already 3 hours underway and I had a fully formed idea of the mechanics and game play.

A rough timeline of my progress looks something like this:

ludum-dare-45-timeline.png

Here are some personal tips I embraced that contributed to my success in being able to finish Robo-Fort on time.

  1. I intentionally gave myself a ton of time at the beginning to sort through ideas. The 3-hour delay before I got home didn’t concern me in the slightest. That time to think before coding is required.
  2. My morning routine (breakfast, shower, coffee, etc.) helps me focus, so I made sure to still do that.
  3. Test continuously. I would periodically stop at natural breakpoints and just play the game.
  4. Slept 8 hours each night to keep me from writing bad code or (worse) making bad decisions.
  5. My goal was to have a minimum playable version done by Saturday evening (after about 32 hours).
  6. If I got stuck on a non-technical idea, I immediately set the project aside and did something different (like washing the dishes) to let me think. The worst thing I could do was waste valuable time coding when I didn’t have anything to code.
  7. Lastly, I allocated the final hours on Sunday for music, since I knew that this was my weakest “skill”.

Ultimately, the Compo is not just a test of game development skills. It is also a test of self-knowledge, because in order to complete your game, you must force yourself to be the best version of yourself you can be. Even if it’s only for 48 hours. Plus, the skills you apply for the Compo (e.g., think and plan before you code, know what you have time for and what you don’t, etc.) apply to regular game development, too.

Robo-Fort (LD45 Submission by Geoff Nagy) Sun, Oct 6 2_18_45 pm.png

Games are judged on the Ludum Dare website by the other participants over the following several weeks after submission according to a “karma” scheme: in order to get your game judged by other players, you also have to judge others’ games. This was a ton of fun and I played about 60 over the course of the next several days. It was really something to immerse yourself in so many different fun worlds, and in each game, the developers’ passion shone through. I played one of the games that ended up winning, and the winning title was well-deserved.

Robo-Fort ended up scoring 360th overall, out of 2613 submissions. That’s within the top 14%, so not bad. (And top 6% in the “Graphics” category!) Some folks had difficulty seeing my (rather broad, in hindsight) interpretation of the theme (“start with nothing”), so that’s something to keep in mind for next time. Overall, Ludum Dare 45 was a fun experience that I’d recommend to any reasonably experienced programmer or developer looking to challenge themselves and test their skills.

GN

Making My Models

Game art is really not one of my strong suits. I mean, don’t get me wrong – I think Hypergate looks pretty good. But first and foremost, I consider myself a programmer, not an artist.

Here’s a 3D model I built back around 6 years ago at the beginning of Hypergate’s development. (I couldn’t find the original textures.)

old-model-1

This was originally an enemy fighter.

 

Not bad, but I think my more-recent Hypergate art looks better:

ship-render

The Validor A, a new fighter in a future update.

Now, having worked previously with some truly talented game artists during my brief time in the VR industry, I know that my art skills don’t come close to theirs. But, I recognize that my improvements were only possible through lots of practice. And you can learn too.

The goal of this post is to provide a brief outline of my workflow for building and texturing 3D models for my games, including Hypergate. It’s a relatively simple, methodical approach that works for me.

Our case study will be the Validor A, the new fighter shown above that will be part of a future Hypergate Content Update. The focus here will be on high-level steps, not artistic design. This is also not a technical tutorial on modelling.

So, let’s get started.

1. Build the Model Shape

The first step – and really, the hardest – is shaping the model. Blender is my tool of choice. It’s free, has great community support, and is regularly updated.

I usually start with a cube and extrude. I’ll sub-divide a few faces and add loop cuts here and there. My approach is to first focus on the large details. My space ships tend to have big wings, gun turrets underneath, a cockpit, and a few greebles on top or below. I’ll start with the large pieces like wings and the nose to get the shape figured out. As always, I’m prepared to use Ctrl-Z as I iterate. The Mirror modifier in Blender is a great way to ensure that my design is symmetrical.

bare-model

Once the wings and nose are worked out, I’ll shape the cockpit. I’ll add greebles on the wings to aid the appearance of appropriate scale. This can be done using the Extrude command. I’ll extrude cylinders for turrets or antennae, and shape boxes into fins. Cylinders work great for rear thrusters, too.

2. Add Seams

Seams define edges where you want to cut your mesh when performing texture unwrapping. Think of it like slicing up a stuffed animal or an orange with scissors: if you wanted to paint each segment of the animal or fruit on a flat canvas, where would you cut to get the flattest and easiest-to-paint segments? The red lines in the wireframe image below show the seams.

seams-model

A rough starting guideline is that I’ll usually want to add seams on the natural sharp edges of my model. This minimizes the texture distortion and provides a bit of robustness if I’m going to use a lower-resolution texture. Of course, there are exceptions, and I always end up adding seams elsewhere as required.

3. Unwrap

Unwrapping is an iterative process. After adding seams, I make sure I’ve done it right by doing a simple unwrap and viewing the resulting UV islands.

uv-islands-model

Enabling “Stretch” for “Angles” in the right-hand Properties toolbox helps to visualize distortion.

Chances are, I may need to add a few more seams here and there and repeat the unwrap process to eliminate distortion. I miss seams accidentally on my first try all the time.

4. Adjust UV Islands

After I’ve unwrapped the model, I’ll apply a simple diffuse texture of a checkerboard with lorem ipsum text to my model. The checkerboard helps visualize scale and the text indicates direction. (Often my textures will include text like safety stickers.)

I’ll now translate, scale, and rotate the UV islands until I get the appropriate levels of detail for each component of the ship. Often I’ll group related UV islands together to make texturing easier later on.

In rare cases, I might need to go back and add more seams and do some re-unwrapping. “Pinning” UV vertices is very useful for ensuring that vertices I know to be correct won’t change during subsequent unwraps.

5. Exporting UV Layout and Texturing

My image editor of choice is GIMP. For small fighters in Hypergate, I’ll usually export a 2048×2048 image of my UV islands from Blender for texturing, although the final in-game textures end up smaller than this for reasons I’ll explain later. For larger objects like cruisers, I’ll usually export 4096×4096-sized UV layouts.

In GIMP, I start by adding a base colour layer (off-white, in the case of the Validor A). I colour individual UV islands, add some panelling, warning stripes, service panels, warning stickers, arrows, some text, vents, rivets, LEDs, and engine glow. I also add dirt and scratch layers. The “Layer Mask” feature in GIMP is a great way to add the appearance of worn-out paint or labels. This becomes the diffuse texture of the model.

uv-texture-mapping

I’ll also export emission, specular, and normal maps. These are just exported versions of the diffuse texture with the appropriate layers turned on or off, and further separately tweaked. The “Normal Map” plugin for GIMP is how I build my normal maps.

6. Applying Final Textures

By now, I’ve got diffuse, emission, specular, and normal maps for my model. In Blender, I’ll replace the original checkerboard material with a new one that uses these four textures. I’ll create four “Image Textures” in the “Texture” tab, setting their “Influences” appropriately.

7. Final Optimizations

2048×2048 is a pretty large texture size for a 10 meter fighter travelling at a couple hundred meters per second. This can eat up valuable GPU memory, takes longer to load from file, and is simply just an unnecessary level of detail. For small fighters in Hypergate, I usually export the following image textures:

  • Diffuse: 512×512 RGB PNG
  • Emission: 256×256 Greyscale PNG
  • Specular: 256×256 Greyscale PNG
  • Normal: 512×512 Greyscale PNG

This generally gives good results in terms of both level-of-detail and image sizes. Larger or slower objects are assigned larger textures to maintain good visual quality.

The model itself is exported as a Wavefront .OBJ file. I’ll export several levels of detail for each object. (The Decimate modifier is really useful here.) The small fighters typically have the following levels of detail, although it varies on the model:

  • High quality: 4,000 – 6,000 triangles
  • Medium quality: 2,000 – 4,000 triangles
  • Low quality: 1,000 – 2,000 triangles or less (I just set the Decimate modifier to the bare minimum that maintains the general model shape)

So how long does this entire process take? It depends. When I rush myself with this kind of work, it usually results in poor quality and more mistakes. A ship like the Validor A might take me about 2-3 days’ worth of full-time work, from start to finish.

I hope that this guide has been somewhat useful. Like I said, it is rather high-level. Comments are more than welcome if you have suggestions or would like more details on a particular step.

GN