Entitas-csharp: Unload unnecessary systems

Created on 8 Apr 2018  路  4Comments  路  Source: sschmid/Entitas-CSharp

Hi,

I wonder if we have some sort of functionality that some of the systems can be turned off during runtime.

Take tower defense as an example. The players can first build their bases, then start the game to defeat the enemies. Apparently those building related systems are not needed during the fight.

Most helpful comment

you can separate systems into different sets.

_systemsAlwaysToExecute = new Feature("Systems")
            .Add(new ConfigSystem(contexts))
            .Add(new InputSystems(contexts));

_systemsExecuteWhenCondtionIstrue = new Feature("Building Systems")
            .Add(new BuildingSystem(contexts));

_systemsAlwaysToExecute.execute();
if(GameStateService.condition== true)
  _systemsExecuteWhenCondtionIstrue.execute();

All 4 comments

you can separate systems into different sets.

_systemsAlwaysToExecute = new Feature("Systems")
            .Add(new ConfigSystem(contexts))
            .Add(new InputSystems(contexts));

_systemsExecuteWhenCondtionIstrue = new Feature("Building Systems")
            .Add(new BuildingSystem(contexts));

_systemsAlwaysToExecute.execute();
if(GameStateService.condition== true)
  _systemsExecuteWhenCondtionIstrue.execute();

I see 3 common ways to do this:

  1. Systems know themselves when to execute
class MySystem {

   void Execute() {
        if (context.isInBattle) {
             // Battle logic
        }
    }
}

  1. Systems are managed by the parent system
public sealed class UpdateSystems : Feature {

    readonly Contexts _contexts;

    public UpdateSystems(Contexts contexts) {
        _contexts = contexts;

        Add(new MySystem(contexts));
        // add other systems
    }

    public override void Execute() {
        if (_contexts.game.isInBattle) {
            base.Execute();
        }
    }
}

Instead of hardcoding the condition you can also create a GuardSystem which takes a function to check a condition, so the GuardSystem can be reused for multiple scenarios.

  1. What @surferau suggested

I just place the System Initialize and Update calls in a separate GameObject / MonoBehaviour.

That can then be easily enabled or disabled.

It also improves testability in some scenarios, you just plunk the "subsystem" object into a scene you are working on and you do not have to worry about the other systems.

I highly recommend the first solution that simon wrote, because it's not necessary to turn off and on a system if it's only executed if the required conditions are met. It's really helpful to see in what condition the system is executed by trigger/filter, instead of debugging down the road to know which system is which enabling or disabling or worse execution is dependent on some unity monobehaviour state. Especially if you have a big game. Furthermore enabling/disabling systems would mean some sort of state. That means it should be part of the data and therefore components. Like you said in your example I could imagine some kind of BuildPhaseComponent or FightPhaseComponent and so on.
It's not a big deal to have many thousand systems at the same time if they are reactive and not getting executed all at the same time.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CuriousHub picture CuriousHub  路  5Comments

jakovd picture jakovd  路  3Comments

Stals picture Stals  路  4Comments

angelotadres picture angelotadres  路  5Comments

yuchting picture yuchting  路  4Comments