Skip to main content

Revamping the Action Economy

·508 words·3 mins

Right now I’m using a strict turn-based approach. All the units take one action per turn.

That works well for strategic games with longer turns but this is a faster-paced, lower strategy game. Not a hack ’n’ slash but definitely in that direction.

Here, three consumer organs gain their +3 biomass all at once. Similarly all enemy units move at the same time and all the pseudopods and tentacles attack at the same time.

It looks very robotic. Inorganic. And I’m not sure it makes sense for the direction this is going. Time to try a different approach.

Right off the bat, an issue with using Timers. My simulation class is data only. It’sn’t a Node so I don’t have a way to add timers to the scene tree. That’s pretty funny.

I could make some kinda utility class that creates timers and puts them on the scene tree and passes a reference so they can be used for … whatever they need to be used for. But that’s working against the engine instead of working with it.

I do think I’ve over-engineered this implementation to some extent. Separation of the model and view works great in some cases but I feel like it’s slowing down my prototyping. This might not be the right time to address that, though.

Maybe a better option is to just put the Sim on the Scene Tree. Make it a Node so I can use Timers. That’d be straightforward and wouldn’t require refactoring.

…except the actual model classes like Cell and Mob wouldn’t be Nodes. I’d have to change all those, too. Hrm. Maybe it does make sense to keep steps but make steps shorter (and probably rename to tick()).

I ended up going with a tick every 100 ms. Pretty happy with the little cooldown class that I implemented. It’s used like so:

var _move_cooldown: Cooldown = Cooldown.new(10).with_randomize_initial_value()

...

func tick() -> void:
	if !_move_cooldown.tick():
		return
	
	...move code here...

The basic behaviour just delays using the skill until after the required number of ticks. But there’s some randomization added to make units move more naturally.

The first move will happen after anywhere between 0 and 10 ticks. After that it’ll happen roughly every ten ticks. There’s a set of modifiers inspired by Gloomhaven that increase or decrease the number of ticks on a given cooldown.

const DEFAULT_MODIFIERS: Array[int] = [-2, -1, -1, 0, 1, 1, 2]

Always wanted to do that. (-:

I had a lot of parameters repeating across organs, for example health, maturation age, attack cooldown. I picked the ones that seem like they’ll be most common and extracted them into a new Resource called OrganDef. That allowed me to get rid of a bunch of wet code.

I’m not using an explicit component architecture in this project. But I can still package logic that gets used by multiple organs into classes of their own.

Now I have a better platform for expanding into other types of organs. There are a lot I’d like to try!