Skip to main content

Blob Shader, Organs, and Singletons

·401 words·2 mins

Lots of progress on Recombobulation lately.

I refactored organs and mobs to use a combination of Godot Resources and the Composition Pattern so I can make more of them without ballooning code complexity.

As I refactored organs I added a handful of them to make sure the architecture was actually doing what I wanted. Had fun making new artwork, including a splash animation when a new organ matures.

The blob now animates as it moves. Passing the timestamp to the shader at each frame seemed wrong to me. I tried synchronizing the shader and engine times and did a bunch of research on the interwebs. Turns out that’s the accepted method so that’s where it stands.

Skeleton Mob Drawings
#

Now it’s time for new enemies. I learned about orthogonal design and I’m taking inspiration from some recent favourite games—oh, and the lore and concepting that’s been growing in my notebook. Time to draw.

I don’t know the last time I did this much drawing. If ever? I mean. Lots to learn and there’s probably even stuff I don’t realize I’m doing, er, poorly, but it’s pretty satisfying.

Registering Components Without Polluting Global State
#

When Components instantiate I need each one to call a method on some sort of component registry. That way I can query them and also give them access to level-wide data like the tile maps and the enemy positions or camera location. In Guerilla Gardeners I made sure all Components were in the subtree of a ComponentRoot class. When Components were _ready() they’d search scene tree ancestors for the ComponentRoot and then register themselves. Not bad. But for Recombobulation I came up with something better.

I’ve got a ComponentBus autoload singleton. I’m wary of singletons because I prefer that when a game level unloads, everything unloads. With singletons some unwanted or unexpected state could be retained between levels and cause problems that are hard to diagnose. But with ComponentBus there is no state. It just gives component and system classes somewhere to listen to events triggered when a Component is instantiated.

So my system classes instantiate and set up listeners on the ComponentBus, then Components are instantiated and trigger events on the ComponentBus and now they can talk to each other. No ComponentRoot required in the scene tree and even better, each system can decide which Components it cares about. Track those and ignore the rest.