Search Unity

[Basic design] How to handle a end of game situation ?

Discussion in 'Entity Component System' started by Kamalen, Jun 7, 2018.

  1. Kamalen

    Kamalen

    Joined:
    Dec 27, 2012
    Posts:
    29
    Hi,

    I am new at this ECS thing. It seems very natural to write many gameplay features and I am starting to use it more widely.

    I am doing a small minigame to get into the pattern. From a design perspective, I have trouble to handle the ending of a game. Lets say a simple Whack a mole game with sessions of 3 minutes. During that time, mobs spawns, player kill them to get points or they disappears after 5 seconds. I have those systems :
    - EnemySpawnSystem
    - EnemyLifeSpanSystem
    - EnemyDeathSystem
    - ScoreSystem
    - TimeLeftSystem.

    I want the game state to freeze when the time ends in order to display a final score screen. Should I use a sort of "Manager" entity that will store the state of the game (InProgress, Ended) and check its state in every systems ? But in this case, all system would eventually run to check game state instead of just be greyed out.

    Is there some way to end the run of all systems and leave the game state as is ? I can't figure a way in the documentations available.

    Thanks for any tips !
     
  2. Afonso-Lage

    Afonso-Lage

    Joined:
    Jul 8, 2012
    Posts:
    70
    I don't know if is possible to disable all systems in a world, but you can disable any system you want by just calling:
    World.Active.GetOrCreateManager<EnemySpawnSystem>().Enabled = false
    or from whitin a system, you coud just inject it:

    Code (CSharp):
    1. public class TargetSystem : ComponentSystem
    2. {
    3.     [Inject] private EnemySpawnSystem m_enemySpawnSystem;
    4.     [Inject] private EnemyLifeSpanSystem m_enemyLifeSpanSystem;
    5.     [Inject] private EnemyDeathSystem m_enemyDeathSystem;
    6.     [Inject] private ScoreSystem m_scoreSystem;
    7.     [Inject] private TimeLeftSystem m_timeLeftSystem;
    8.  
    9.     protected override void OnUpdate()
    10.     {
    11.         if (GameHasEndedForSomeReason)
    12.             {
    13.                 m_enemySpawnSystem.Enabled = false;
    14.                 m_enemyLifeSpanSystem.Enabled = false;
    15.                 m_enemyDeathSystem.Enabled = false;
    16.                 m_scoreSystem.Enabled = false;
    17.                 m_timeLeftSystem.Enabled = false;
    18.             }
    19.     }
    20. }
    Please note that I didn't tested the above code, is just for illustration purpose.
     
  3. avvie

    avvie

    Joined:
    Jan 26, 2014
    Posts:
    74
    I didnt test either, but looks like this should work like a charm as well as disabling the world (which sounds extremely ominous :D)
     
  4. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    In my humble opinion, you should never have to disable systems in the normal flow of the game. Sounds like a bad design.

    Instead, you can create an entity with a
    GameIsRunning
    component when the game starts. Then in the systems that you only want to run during the game is running, add a simple if check to see if the
    GameIsRunning
    component exists, and act accordingly. And when the game ends, simply destroy the entities that have
    GameIsRunning
    components.

    I am no expert on ECS however. You should probably do what feels more natural to you.
     
    zulfajuniadi likes this.
  5. Afonso-Lage

    Afonso-Lage

    Joined:
    Jul 8, 2012
    Posts:
    70
    But what if your game has some stages? Let's say your game has a Lobby and a Match stage, which require different systems. If you have enabled all systems that are used only on Lobby stage during the Match stage, I think this would be a waste of resources, since even if your
    Update
    isn't called when there are no entity with required components, there is a
    PreUpdate
    process with needs to check it, every frame. So in this case it would be valid to map which systems are used in which stages of game and enable/disable it according to.

    Of course you can also handle those stages as worlds, and active/deactive the entire world depending on what stage is.
     
  6. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    When the topic is performance, we should almost always talk with data from the profiler. Speculations often lead to premature optimization.
     
  7. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    You got any reasoning to offer for this claim?

    In the old way of doing things with Unity, this could happen a lot while pooling items but ECS is technically making spawning and destroying things fast so this isn't all that much needed nowadays. But there could still be some systems you'd want to straight up disable without building the same logic yourself everywhere.
     
  8. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Can you stop the World, as that would be interesting as you could have a Menu World and GameOver World?
     
  9. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    I don't claim anything, it is a mere opinion. But for the sake of argument, here is the reasoning:

    Disabling a system means you cannot solely rely on the composition of components in order to make sure a system will process the entity. You have to also make sure the system is enabled. In my opinion, this is an unnecessary friction and complication in the workflow.