Differences and similarities of states and systems

(Thomas Schaller) #1

I wanted to create a similar discussion thread actually. I wanted to discuss how systems and states are even that different, because it seems systems are going into the same direction as states, given they’re now

  • pausable
  • have a start method (setup)
  • should have an end method
  • read events
  • have an update method
Request for comments: Simplified state machine
(W. Brian Gourlie) #2

I wanted to discuss how systems and states are even that different

Wouldn’t the distinction be that be that systems are stateless and states are stateful? It would seem that the natural direction would be to further enforce or encourage these distinctions.

(Thomas Schaller) #3

Yes, fully agreed @wbrian.

However, I think it’s worth looking into this some more.

I do think that Systems should ideally be completely stateless. In practice however, there are things that don’t make them stateless:

  • systems can be paused; if this is just a performance thing that’s okay, but I can very well imagine somebody uses this for different states
  • systems cache certain things, also for performance; that gives them some sort of state with all the side effects that come with that
  • systems handling input events also seems like something that’s not completely consistent, because it is dependent on the state

The goal of this thread is to work out general rules for how systems should work, what they may or may not do ideally (best practices) and what effects that knowledge could have on the ECS API.

Related discusions:

1 Like
(Thomas Schaller) #4

Also with regards to my comment on the states RFC, I think systems should not be fed from input events directly. Instead, the state should map those events somehow to trigger the appropriate action in a system.

So as an example, let’s say there is a pause menu and an in-game state. Both might even have different input bindings. Now, the states should emit a respective event to signal player movement (in-game) or widget selection (pause menu). This also effectively removes the need to pause systems (for logical reasons), because the movement system will simply not receive any event / updated data.

(W. Brian Gourlie) #5

After ruminating on this a bit, I definitely see your point.

The solution proposed in this PR seems nice, but isn’t generally applicable due to the Send + Sync constraint. It’s nice in the sense that it allows the System to remain technically stateless, although being technically stateless comes at the expense of making System-specific data available to other systems, the consequence of which is that some other system could in theory read another system’s events (or modify any other system-specific data shared as a resource).

So, I don’t think the goal should be to make things technically stateless, which in effect really just encourages making system-specific data shared, while still not solving for state that isn’t Send + Sync.

I think a good start would be to find a nice way to distinguish things that are technically state from things that are stateful in the sense that they break the abstraction, if only for communicating the distinction and discouraging the latter.

1 Like

This is a good idea. Having a key->action mapping for each state just makes sense. It does require an ergonomic way to pass actions into systems that require them.

Unfortunately it doesn’t. Something like a physics system is still going to require pausing when the pause menu state is active.

(Thomas Schaller) #7

I think that can be fit into this model, too. Basically the data the physics system processes is “time passed + objects + behaviour”. If no time passed, the output should be equal to the input.

1 Like

That would work and leave the system stateless, indeed.