ECS for turn based games

I’ve been fond of the ECS design pattern for years now, but I’m having trouble understanding how to use Unity’s version of it when it comes to turn based games. I have a scenario where one single user input can cause a chain reaction which would make the logic systems (as I imagine them) to take many frames to finish resolving, even though the math may be simple enough to finish in an instant.

Here’s an example, imagine a card based game (something like Hearthstone):

I play a minion, Card A
Card A dies due to another reactive card in play
Card A’s death creates x minions (special ability upon death)
The creation of the above minions trigger a different allied card effect, dealing x damage to enemies
The above damage ends up killing an enemy minion

Assuming there’s a damage system, a death system, a system for each unique card ability, etc and each system only runs once per frame, the above example may take as many as 5 frames to finish. I’m not making a card game, but one that is fundamentally similar yet much more complex, with many more consequences from a single user input. Waiting tens of frames for the logic to resolve is obviously unacceptable, I want to process all the math from any given user input, ASAP.

I know I can accomplish what I need to if I can update the game logic loop separate from the Unity main thread, but I’m not sure what the cleanest way would be to pull that off, because from what I’ve read, Systems aren’t intended to be manually updated. If I simply copy all the ECS data and work on it in a separate thread without using any Systems for the logic loop, then there’s almost no point in using Unity’s ECS in the first place.

If anyone has any suggestions for this problem, I’d appreciate any advice.

You can manually call one ComponentSystem.Update();
So you could take the relevant systems and run them in a loop until everything is resolved.

I’m sorry, I’m not sure what ComponentSystem.Update() does. The only one I can find documentation of is OnUpdate().

Does the one you mentioned also update the injected Components? Or do I need to feed it all the component data arrays myself?

Thanks for the help.

By default the player loop is responsible for ordering all updates to all systems and then executing them. Essentially for each system it calls ComponentSystem.Update().

Update does the necessary system setup / preparation / OnStartRunning / OnStopRunning, debug checks etc and invokes OnUpdate();

So you can simply call ComponentSystem.Update() yourself at any pointer in the frame. Maybe simplest is to do it from another system OnUpdate method.

Like so:
World.GetOrCreateManager ().Update();

1 Like