sschmid / Entitas

Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
MIT License
7.03k stars 1.11k forks source link

Do ReactiveSystems work in Pure C# Entitas? #985

Closed aunymoons closed 1 year ago

aunymoons commented 2 years ago

Hi all!

I've been trying to get a simple game i wrote to work on Pure C# Entitas, so far i havent encountered any issues when setting up the .Net app and overall initialization of my systems seem to be working well.

However, my problem happens as soon as i try to use a reactivesystem.

Currently i'm running my own game loop in my Program.cs, looks like this:


_gameController.Start();

for (int i = 0; i < 50; i++)
{
    _gameController.UpdateSystems();
}

_gameController.TearDown();

The "50" is just temporary ( eventually ill add proper logic in a while loop ), but its enough so that my game throws some console text to let me know its working. I've gotten rid of features, since i understand they are Unity-Only, so i separate all my systems like this on the _gameController.Start():


public void Start(){

_turnSystems = new Systems()
    .Add(new TurnInitializeSystem(_contexts))
    .Add(new TurnReactiveSystem(_contexts))
    .Add(new ProcessMeterReactiveSystem(_contexts))
    .Add(new LogSystem(_contexts));

_actionSystems = new Systems()
    .Add(new ActionInitializeSystem(_contexts))
    .Add(new ProcessContextReactiveSystem(_contexts))
    .Add(new ProcessAbilitiesReactiveSystem(_contexts))
    .Add(new ProcessNeedsReactiveSystem(_contexts))
    .Add(new AIReactiveSystem(_contexts));

_turnSystems.Initialize();
_actionSystems.Initialize();

}

Then on _gameController.UpdateSystems(); i just execute them, The profiler is confirming that the systems are indeed registered inside _turnSystems and _actionsystems variables:

public void UpdateSystems(){

_turnSystems.Execute();
_actionSystems.Execute();

_turnSystems.Cleanup();
_actionSystems.Cleanup();

}

But according to every single breakpoint i put on a ReactiveSystem is never hit, meaning any:

protected override void Execute(List<GameEntity> entities)...

of any of my ReactiveSystems is never called.

However, as soon as i tried adding one normal ExecuteSystem instead of a Reactive one, Execute gets called flawlessly.

Am i missing something? Because if its an incompatibility, is not specified anywhere in the documentation, I want to know if that's the case, or an error on my side before i start the incredibly long task of refactoring every system i wrote become an execute system. I get no exceptions whatsoever, not even wrapping the .Execute() calls in try-catch blocks.

I've also attempted to call the reactiveSystems individually, by not putting them inside a "Systems" variable, but same result. Execute is never called.

itayalper commented 2 years ago

Do you happen to use an AllOf/NoneOf matcher combined with other components?

From my experience ReactiveSystems only work with a single component

sschmid commented 2 years ago

@aunymoons Your setup seems fine. ReactiveSystem.Execute() is only called if the trigger and filter passes. Can you share a Trigger() and Filter() so we can double check if they are set up correctly? Also, how do you change component values? You need to either use the generated methods or e.ReplaceComponent(), otherwise changes will not be registered and reactive systems cannot pick up the change

aunymoons commented 2 years ago

@sschmid Im a complete fool, indeed, as you said:


// Inside TurnReactiveSystem.cs

    protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
    {
        return context.CreateCollector(
            GameMatcher.NextTurn.Added<GameEntity>()
            );
    }

    protected override bool Filter(GameEntity entity)
    {
        return entity.isNextTurn;
    }

When refactoring i completely forgot to add the NextTurn component on initialization, and since most of those systems kinda "cascade" one from another then if the first one didnt initialize then the rest wouldnt trigger at all.

Just tested it again and works flawlessly, thanks for the quick reply <3