Replies: 2 comments 13 replies
-
I've already done a bottom-up rewrite of As for goal 2, I don't think commands being the primary way to interact with states is the right direction. Being able to mutate state values directly is convenient and would be a better direction IMO. For example: |
Beta Was this translation helpful? Give feedback.
-
Minor nitpick, I would use a custom enum for |
Beta Was this translation helpful? Give feedback.
-
Hey everyone, I've recently been contributing to the states machinery of Bevy.
We still had some refactors & features planned and in the meantime observers and required components landed.
This opened up a lot of possibilities, but also lots of breaking changes, hence I'm opening a discussion for
bevy_states
replacement.This crate will be developed separately and swapped into Bevy at some point in the future to do all the breaking changes at once.
Check out the prototype
States v3
States v3 proposal focuses on the following:
Something this proposal does not consider is keeping compatibility with the existing crate.
Internal Design
Storage Model
A single state machine is stored in a single entity.
Each state entity consists of one or more
StateData<S>
components with differentS: State
.Dependencies between states are enforced through required components.
The only difference between global and local state is the addition of
GlobalStateMarker
component.Multiple entites with
GlobalStateMarker
cannot exist.Top Level Reactivity
How states update each other.
State machines update through a similar system to existing
bevy_state
.The
StateTransition
schedule runs 3 system sets:AllUpdates
- Updates based ontarget
and dependency changes from root states to leaf states, sets theupdated
flag.AllExits
- TriggersStateExit<S>
observers from leaf states to root states, targeted for local state, untargeted for global state.AllEnters
- TriggersStateEnter<S>
observers from root states to leaf states, targeted for local state, untargeted for global state.Smaller sets are used to specify order in the grap.
Order is derived when specifying state dependencies, smaller value meaning closer to root.
Note that the
Exit
andEnter
events are called after the entire state machine was updated.Calling them while state machine is updating can lead to invalid arrangements, which we don't want to expose.
The previous and current values are available in
StateData<S>
.Based on those events, more user oriented events can be made such as
OnExit { previous, current }
andOnEnter { previous, current }
.There is no longer a
Transition
stage inbetweenExit
andEnter
.It wasn't that helpful, the order of calls was undefined and if it was, it could rely on
Exit
orEnter
instead.Bottom level reactivity
How states update themselves.
State change can be triggered from two sources:
target
has changed.When any condition is met, the
State::update
function is called.The return value of this function decides whether and how we update this state.
User Interface
Adding and modifying state
First, the
StatesPlugin
has to be added to the application.This plugin only adds the
StateTransition
schedule to both, startup and main schedules.All of the operations can happen immediatelly (with
World
,SubApp
,App
) or in a deferred manner (withCommands
).For global state, the entity gets created if it doesn't exist.
For immediate state transitions, running
StateTransition
is recommended.No helper method is provided due to the complications this can bring.
Future extensions
There are few harder and easier additions:
Beta Was this translation helpful? Give feedback.
All reactions