There’s a critical combat feature that I haven’t brought up yet. Stasis.
When you control a whole cabal, you cannot keep your eye on everything. I love the RTS genre, but a momentary pause mechanic can make the game much more strategic than purely tactical.
FTL used this to a great extent to give the feeling of being Captain Kirk barking orders after analyzing precisely what needed to be done to save the ship.
I want the lead of the cabal to have a similar feeling, so a Stasis mechanic (to theme it properly for fantasy) makes a lot of sense. However, I have a few considerations:
- How should this be handled in multiplayer? Should it just be outright disabled? Limited?
- Should the Stasis be tied to the chronomancer ability or unlockable via an upgrade?
Regardless of my future answer to those questions, it basically requires me to be able to freeze all game systems except user input processing and rendering. That is non-trivial to program. If I don’t implement it early and test it throughout development, I suspect it will never work properly.
Stasis Implementation
In order to get this to properly work, there were a few CommandSystems that I had to refactor and separate. My cast system handled spell input and created spells, but if I had to pause half the system, I should just separate them instead.
Currently, I have an InputSystem
that handles turning user key/mouse/etc into Commands, which are stored in an InputComponent
.
(Yes, player input is a component and it belongs to a player entity). If I can disable all Systems that aren’t involved in either
input/commands or my RenderSystem
, that should pause the game but allow the user to continue to interact and plan.
I created a StasisPauseCommandSystem
and a StasisPaused
interface. I decided that Systems should declare whether they should
be paused or not, that way I’ll make sure to update it as I go along.
The actual system ended up being incredibly simple. Here’s a sample of pausing:
public class StasisPauseCommandSystem extends EntitySystem {
/** whether paused or not */
public boolean isStasisPaused = false;
public void stasisPause() {
// disable anything that says it can be paused
for (EntitySystem system : engine.getSystems()) {
if (system instanceof StasisPaused) {
system.setProcessing(false);
}
}
}
// function to handle command to stasis pause or not
}
And it really did just work.
Sometimes ECS can be clunky, but for this problem, it worked perfectly.
Now, I still need to show intent in my UI better - intended targets and intended movement.
That should be as simple as adding effects to my UiRenderSystem
as an underlay based on
the Commands that are active.