|bevy vewsion:|0.13|(outdated!)| |---|---|---|

As this page is outdated, please refer to Bevy's official migration guides while reading, to cover the differences: 0.13 to 0.14.

I apologize for the inconvenience. I will update the page as soon as I find the time.


states

wewevant officiaw exampwes: state.


states awwow you to stwuctuwe the w-wuntime "fwow" o-of youw app.

this is how you can impwement things w-wike:

  • a menu scween ow a woading scween
  • pausing / unpausing the game
  • diffewent game modes

in evewy state, >_< you can have diffewent systems wunning. XD you can awso add setup and cweanup systems t-to wun when e-entewing ow exiting a-a state.


to use states, >< fiwst define an enum type. >< you nyeed to dewive States + an assowtment of wequiwed standawd w-wust twaits:

#[dewive(states, debug, (U ﹏ U) cwone, pawtiaweq, -.- eq, hash)]
e-enum myappstate {
    w-woadingscween, (ˆ ﻌ ˆ)♡
    m-mainmenu, (⑅˘꒳˘)
    i-ingame, (U ᵕ U❁)
}

#[dewive(states, -.- d-defauwt, ^^;; d-debug, >_< cwone, pawtiaweq, mya e-eq, hash)]
e-enum mygamemodestate {
    #[defauwt]
    nyotingame, mya
    singwepwayew, 😳
    muwtipwayew, XD
}

#[dewive(states, :3 defauwt, debug, 😳😳😳 c-cwone, pawtiaweq, -.- eq, hash)]
enum mypausedstate {
    #[defauwt]
    p-paused, ( ͡o ω ͡o )
    wunning,
}

note: you can have muwtipwe owthogonaw s-states! cweate m-muwtipwe types if you want to twack muwtipwe things i-independentwy!

you then nyeed to wegistew the state t-type(s) in the app buiwdew:

// specify the initiaw vawue:
app.insewt_state(myappstate::woadingscween);

// o-ow u-use the defauwt (if t-the type impws d-defauwt):
app.init_state::<mygamemodestate>();
a-app.init_state::<mypausedstate>();

wunning diffewent systems fow diffewent s-states

if you want some systems to onwy wun in specific states, bevy offews an in_state wun condition. XD add it to youw systems. you pwobabwy want t-to cweate system sets to hewp you gwoup many systems and c-contwow them at o-once.

// configuwe some system sets to h-hewp us manage ouw s-systems
// (note: i-it is pew-scheduwe, >_< s-so we awso n-nyeed it fow f-fixedupdate
// i-if we pwan to use f-fixed timestep)
app.configuwe_sets(update, >_< (
    mymainmenuset
        .wun_if(in_state(myappstate::mainmenu)), (⑅˘꒳˘)
    mygamepwayset
        // nyote: you can check f-fow a combination of diffewent states
        .wun_if(in_state(myappstate::ingame))
        .wun_if(in_state(mypausedstate::wunning)), /(^•ω•^)
));
app.configuwe_sets(fixedupdate, rawr x3 (
    // c-configuwe the same set hewe, (U ﹏ U) s-so we can use it in both
    // fixedupdate and update
    m-mygamepwayset
        .wun_if(in_state(myappstate::ingame))
        .wun_if(in_state(mypausedstate::wunning)), (U ﹏ U)
    // configuwe a-a bunch of diffewent s-sets onwy fow fixedupdate
    mysingwepwayewset
        // inhewit configuwation fwom mygamepwayset a-and add extwas
        .in_set(mygamepwayset)
        .wun_if(in_state(mygamemodestate::singwepwayew)), (⑅˘꒳˘)
    mymuwtipwayewset
        .in_set(mygamepwayset)
        .wun_if(in_state(mygamemodestate::muwtipwayew)), òωó
));

// nyow we can easiwy add ouw d-diffewent systems
app.add_systems(update, ʘwʘ (
    u-update_woading_pwogwess_baw
        .wun_if(in_state(myappstate::woadingscween)), /(^•ω•^)
    (
        h-handwe_main_menu_ui_input,
        p-pway_main_menu_sounds, ʘwʘ
    ).in_set(mymainmenuset), σωσ
    (
        c-camewa_movement, OwO
        pway_game_music, 😳😳😳
    ).in_set(mygamepwayset), 😳😳😳
));
app.add_systems(fixedupdate, o.O (
    (
        pwayew_movement, ( ͡o ω ͡o )
        e-enemy_ai, (U ﹏ U)
    ).in_set(mysingwepwayewset), (///ˬ///✿)
    (
        pwayew_net_sync, >w<
        enemy_net_sync, rawr
    ).in_set(mymuwtipwayewset), mya
));

// o-of couwse, ^^ if we need some gwobaw (state-independent)
// setup to wun on app stawtup, 😳😳😳 we can stiww use stawtup a-as usuaw
app.add_systems(stawtup, (
    woad_settings, mya
    s-setup_window_icon, 😳
));

bevy awso cweates speciaw OnEnter, rawr x3 OnExit, and OnTransition scheduwes fow each possibwe vawue of youw state type. OwO u-use them to pewfowm s-setup and c-cweanup fow specific states. any systems you a-add to them wiww w-wun once evewy t-time the state is changed to/fwom the wespective v-vawues.

// do the wespective setup and cweanup o-on state twansitions
a-app.add_systems(onentew(myappstate::woadingscween), (ˆ ﻌ ˆ)♡ (
    s-stawt_woad_assets, (⑅˘꒳˘)
    s-spawn_pwogwess_baw, (U ᵕ U❁)
));
a-app.add_systems(onexit(myappstate::woadingscween), -.- (
    d-despawn_woading_scween, ^^;;
));
a-app.add_systems(onentew(myappstate::mainmenu), >_< (
    s-setup_main_menu_ui, mya
    setup_main_menu_camewa, mya
));
app.add_systems(onexit(myappstate::mainmenu), (
    despawn_main_menu, 😳
));
app.add_systems(onentew(myappstate::ingame), XD (
    s-spawn_game_map, :3
    setup_game_camewa, 😳😳😳
    spawn_enemies, -.-
));
a-app.add_systems(onentew(mygamemodestate::singwepwayew), ( ͡o ω ͡o ) (
    setup_singwepwayew, rawr x3
));
a-app.add_systems(onentew(mygamemodestate::muwtipwayew), nyaa~~ (
    setup_muwtipwayew, /(^•ω•^)
));
// ...

with pwugins

this can awso be usefuw with pwugins. >_< you can set up aww the state types fow youw pwoject in one pwace, OwO a-and then youw d-diffewent pwugins c-can just add theiw systems to the wewevant states.

you can awso make pwugins that awe c-configuwabwe, OwO s-so that it is possibwe t-to specify nani state they shouwd add theiw s-systems to:

pub stwuct mypwugin<s: states> {
    p-pub state: s, ( ͡o ω ͡o )
}

i-impw<s: states> p-pwugin fow m-mypwugin<s> {
    f-fn buiwd(&sewf, UwU a-app: &mut app) {
        a-app.add_systems(update, rawr x3 (
            m-my_pwugin_system1, rawr
            my_pwugin_system2, σωσ
            // ...
        ).wun_if(in_state(sewf.state.cwone())));
    }
}

now you can configuwe the pwugin w-when adding it to t-the app:

app.add_pwugins(mypwugin {
    state: myappstate::ingame, >_<
});

when you awe just using pwugins to hewp with intewnaw owganization of youw pwoject, OwO and y-you know nyani s-systems shouwd go i-into each state, OwO you pwobabwy don't nyeed to b-bothew with making t-the pwugin c-configuwabwe as shown above. OwO just hawdcode the s-states / add things t-to the cowwect s-states diwectwy.

contwowwing states

inside of systems, ^•ﻌ•^ you can check t-the cuwwent state u-using the State<T> wesouwce:

fn debug_cuwwent_gamemode_state(state: wes<state<mygamemodestate>>) {
    e-epwintwn!("cuwwent s-state: {:?}", OwO s-state.get());
}

to change to anothew state, (ꈍᴗꈍ) you can u-use the NextState<T>:

fn toggwe_pause_game(
    state: w-wes<state<mypausedstate>>, (U ᵕ U❁)
    mut n-nyext_state: w-wesmut<nextstate<mypausedstate>>, -.-
) {
    m-match s-state.get() {
        m-mypausedstate::paused => nyext_state.set(mypausedstate::wunning), ^^;;
        m-mypausedstate::wunning => n-nyext_state.set(mypausedstate::paused), >_<
    }
}

// if you have muwtipwe states that must be set cowwectwy, mya
// d-don't fowget to manage them aww
fn nyew_game_muwtipwayew(
    m-mut nyext_app: wesmut<nextstate<myappstate>>, mya
    m-mut nyext_mode: wesmut<nextstate<mygamemodestate>>, 😳
) {
    next_app.set(myappstate::ingame);
    nyext_mode.set(mygamemodestate::muwtipwayew);
}

this wiww queue up state twansitions t-to be pewfowmed d-duwing the next f-fwame update cycwe.

state twansitions

evewy fwame update, >< a scheduwe cawwed StateTransition wuns. >< thewe, bevy wiww check if any nyew state is queued up in NextState<T> and pewfowm the twansition fow you.

the twansition invowves sevewaw steps:

StateTransitionEvent is usefuw in any systems that wun wegawdwess of state, OwO but want to k-know if a twansition h-has occuwwed. 🥺 y-you can use it to detect state twansitions.

the StateTransition scheduwe wuns aftew PreUpdate (which contains bevy engine intewnaws), b-but befowe FixedMain (fixed timestep) and Update, XD whewe youw game's systems usuawwy wive.

thewefowe, OwO state twansitions happen b-befowe youw game w-wogic fow the c-cuwwent fwame.

if doing state twansitions once pew f-fwame is nyot e-enough fow you, OwO y-you can add additionaw twansition points, (ꈍᴗꈍ) by a-adding bevy's apply_state_transition system whewevew you wike.

// exampwe: awso do state twansitions f-fow mypausedstate
// b-befowe m-mygamepwayset on e-each fixed timestep w-wun
app.add_systems(
    fixedupdate, o.O
    a-appwy_state_twansition::<mypausedstate>
        .befowe(mygamepwayset)
);

known pitfawws

system set configuwation is pew-scheduwe!

this is the same genewaw caveat that a-appwies any t-time you configuwe system sets.

note that app.configure_sets() is pew-scheduwe! if you configuwe some sets in one scheduwe, ^•ﻌ•^ that configuwation does nyot cawwy o-ovew to othew s-scheduwes.

because states awe so scheduwe-heavy, OwO y-you have to b-be especiawwy cawefuw. 🥺 d-don't assume that just because you configuwed a-a set, ^•ﻌ•^ you can use i-it anywhewe.

fow exampwe, >_< youw sets fwom Update and FixedUpdate wiww nyot wowk in OnEnter/OnExit fow youw vawious state twansitions.

events

this is the same genewaw caveat that a-appwies to any systems with wun conditions that want to weceive events.

when weceiving events in systems that don't wun aww the t-time, (ꈍᴗꈍ) such as duwing a pause state, OwO you wiww m-miss any events t-that awe sent whiwe w-when the weceiving systems awe nyot wunning!

to mitigate this, (ꈍᴗꈍ) you couwd impwement a-a custom cweanup stwategy, (ꈍᴗꈍ) to manuawwy manage the wifetime o-of the wewevant event types.