How do I make my turn based battle system scalable?

I’m currently working on a turn based battle system for my game. The game is in unity coded with c#.

The turns are based off of an initiative system determined by each characters speed. Right now I have a turn manager that got a queue of all the characters. Then to increment the turns I enqueue the current active character, then dequeue and set them as active.

All of the tutorials I see online use an enum to make a basic battle state system. I am thinking about implementing this next but I am wondering if this is the best approach or if there is different systems that are more scalable.

• "All of the tutorials I see online use a Enum to make a basic battle state system" Could you link to one or two of these tutorials, because I don't know what this means. Feb 21, 2021 at 22:54
• youtube.com/… this is a good example of what I'm talking about. Seeing similar systems in many videos. Feb 21, 2021 at 23:05
• Please note that there is rarely a "best" approach, but rather ones that suit your needs. It appears that you need something scalable, so I tweaked the title to mention this. Feb 21, 2021 at 23:27
• When you say you want to make the battle system "scalable", then the question is "scalable in which direction"? More states? More characters? More complex turn order mechanic? Note that different priorities can sometimes conflict with each other. So the more you write about your eventual goals, the better the answers. Feb 22, 2021 at 10:56
• And by the way, my favorite architecture pattern for handling all the different states in a JRPG-style turn-based combat systems is a stack-based hierarchical state machine. Feb 22, 2021 at 10:58

I don't know if this is "best", but the system I set up for turn-based RPGs I'm working on is certainly one flexible way to architect turn-based combat. It leans heavily on some Unity-specific features, but then you are tagging this question Unity.

I have the entire main gameplay loop encapsulated in a method called AdvanceTurn(). That method first gets the active unit's action (it tells the GUI to ask for the player's choice, or it runs AI for enemies), executes that action, and finally checks if anyone has died/the combat ended.

This method is a coroutine, and I use WaitUntil() between each step in the coroutine to pause it until ready to proceed to the next step. For example, after requesting the player's choice, it'll WaitUntil(gui.PlayerMadeChoice). Or when executing actions, it'll WaitUntil(scene.AnimationsComplete).

AdvanceTurn() is itself being run in a loop within a coroutine, looping until the combat is over, something like this:

while (!combatEnded) {
if (combatants.Count == 0) {
SetupInitiative(players, enemies, combatants);
}