Category Archives: Devastro2

D2 log 025 – Game controller support

Devastro 2 is going to be a twin stick shooter, so I thought it would be appropriate to add support for game controllers.

I purchased the XBox One Wireless controller for testing. Also ordered the Steam Controller while it was on sale for $5, even though it has zero sticks.

My first implementation used the native game controller API built into macOS but later I switched to the SDL interface. The only major difference is that SDL doesn’t handle dead zones and gives raw readings. It wasn’t too hard to take care of that.

Controlling my game character using the gamepad works really well. I will tweak the button mapping (weapon switch, dash) after some more playtesting.

Menu navigation was a little tricky. All menu items are now linked with next / previous pointers to support DPAD navigation. I’m going to add left / right links as well to better support more complex menus, such as level selection.

D2 log 024 – Collision shape editor

Boxes, boxes everywhere. The only shape a game object could have was a box. Looking at some of the buildings and objects I’m going to be putting into the game, I thought it would be good to add support for arbitrary polygon shapes. With Box2D it should be easy, right?

First thing I had to do was refactor the way objects are added into the Box2D world. This was also a good opportunity to finally change the player and enemy shapes to circles. Sneaking around corners just got a lot smoother.

Second, I had to actually get some shapes. But how? Use the Blender models and generate the shapes by making cross-cuts? While technically an elegant solution, such a tight fit might not be ideal for gameplay.

So I made a shape editor. Each object gets a box by default. Click and drag on any edge to add a new vertex. Right click to remove a vertex. Vertices snap to a grid, holding CTRL turns snapping off for extra precision when needed.

Everything turned out nicely. Using the shape editor is fun.



D2 log 023 – Environment moodboards

It is time to start building the environments. I’ve been collecting lots of inspiration all over the web. I had folders with hundreds of images that I found interesting and wanted to keep as inspiration for the game.

Last week I sorted through it all and selected what’s going to become my template for making actual game art.

I was hesitant to invest time into this at first, given that none of the images will go into the game. It’s just stuff for inspiration, right? After a while though, the overall tone started getting under my skin and looking at the result, I felt very inspired and motivated.

Here’s a moodboard for the first environment. It is based on US rural areas of the 50s and 60s.

And part of a “nature” moodboard for trees & rocks:

I’m going to use those to make a list of models to create, do a first pass of blocking out the rough shapes and add them to the game for testing. Next step is to dial in the color palette and fill in the details and textures.

D2 log 022 – Character animations

I started learning basic character rigging & animation in Blender.

Even though it’s still a bit rough, it already looks quite nice at the scale I’m using in the game. Some finer details might be useful for promo materials & cutscenes.

The old clay stop-motion animations had only 5 frames of animation! Making those was fun but also a lot of work.

The rigged 3D model animation is super smooth thanks to interpolation. I’ll try to match the animation speed to movement. It’s never going to be 100% accurate but it should not look like ice-skating…


D2 log 021 – Input replay

New debug feature added to the game: recording inputs during gameplay and playing them back later.

This helps me reproduce a given scenario with a single button press. I can also do a Quake-style “timedemo” recording and use it as a performance benchmark.

To make replay work properly, I had to set a constant seed in my random number generator and make sure all entities were using it. The storage format is not optimal. Recording a long session would probably use more disk space than necessary. But we’re still talking a few kilobytes per minute, so it’s fine.

D2 log 020 – SDL port

I upgraded my home machine to macOS Catalina. Big mistake.

  • Zero interesting new features
  • Devastro 2 OpenGL renderer broken
  • Left 4 Dead unplayable (oh no!)

My OpenGL window went black. Was I using OpenGL wrong? How? On my quest for the answer, I ended up rewriting significant parts of the rendering core, updated all my shaders and created a new SDL port. It took several nights to get things working again.

The good thing is that switching to SDL was one of my mid-term goals anyway. I’m going to need it on Windows. To complete the port, I added SDL event handling and audio backend.

Event inspector for testing the SDL port. Blatantly copied from Sokol.

It was nice to get rid of the Cocoa boilerplate. One thing I missed in the SDL API was a function to set a fixed aspect ratio for my window. I had to do it like this:


#import <Cocoa/Cocoa.h>

void SetWindowRatio(void *window) {
    NSWindow *win = (__bridge NSWindow*) window;
    win.aspectRatio = NSMakeSize( 1280, 720 );


#include <SDL.h>
#include <SDL_syswm.h>

extern "C" void SetWindowRatio(void *window);

// and later..

SDL_SysWMinfo wmInfo;
SDL_GetWindowWMInfo(sdl.window, &wmInfo);

Fixing Left 4 Dead was easy. Add a new APFS volume, install Mojave, install Steam, move data files over, tell Steam to use them → no need to re-download everything. The nice thing about APFS volumes is that they share space, so I don’t have to think about how big each partition should be.

D2 log 019 – Level editor loose ends

I’ve been neglecting the level editor a little bit. It didn’t get fully updated with IMGUI, mainly because it was a mess. It had gone through the entity system development with only quick updates here and there and it showed.

Last night I decided it was finally time to dig in. After an hour or two of cleanup and refactoring, things started looking much better. I wrote new entity & variant selection lists and fixed a few bugs related to Box2D. Overall line count went down, which is always a good sign. So much for custom UI components!

D2 log 018 – Easing curve previews

During a recent rewrite of the menu system, it occurred to me it would be nice to have a visual preview of the various animation easing curves available in the engine.

So I made a tool to do that. Pick an easing function, see the curve and an animation showing its effect on alpha, scale and position. 20 minutes, 150 lines of code.

This will make it much easier to pick the right function when creating new UI and in-game animations.

Luckily I’m done with the menus for now. If I ever need to add more polish, I might attach this new interface directly to the actual element being animated. That would make this a real WYSIWYG tool.

D2 log 017 – Box2D integration

This was a big one. I switched to Box2D for collision detection & physics.

My old system was nothing fancy: axis-aligned bounding boxes, a “sliding” mechanism for collisions, sector based space subdivision. Worked well for Superforce. However there’s a lot more happening in Devastro 2. More bullets, more particles, more enemies, more complicated level design, player motion needs to be fluid around obstacles etc. Box2D seems like the right tool for that job.

First I had to rip out large amounts of old code both in the game and the editor. Everything was completely broken for over a week. Fortunately the Box2D integration went well and the game is now back up and running.

The Box2D API is nice and there’s plenty of documentation & example code.


D2 log 016 – Texture atlas inspector

To improve rendering performance the game builds a texture atlas from all the images. This process is quick enough to be done at load time. I wanted to have a clear idea about the atlas layout. Xcode does have some support for viewing OpenGL textures but it’s been crashing on me almost every time I used that feature. So I did what I usually do when a 3rd party tool fails me: I built my own inspection tool to look at the OpenGL textures directly in-game.

Even in its initial simple form it has already helped fix a few issues.

I’m planning to extend it with zoom & pan and a way to track usage of the individual images in the atlas.