Bevy Mod Scripting
Script your Bevy game: hot-reloadable Lua & Rune with full ECS access
BMS (bevy_mod_scripting) runs Lua and Rune scripts inside a Bevy app. Scripts reach the world through reflection, so any Reflect type, including ones from other crates, can be used from scripts without writing glue code.
- Update game logic without recompiling, with hot reloading of script assets
- Let modders add content through the same bindings your own scripts use
- Bindings are written once in Rust and work in every supported language
- Scripts can add their own systems, components and events
- Generated docs and Lua language server definitions for your bindings
How a script runs
Loading a script asset runs nothing. A script runs code when it is attached, reloaded or detached, which the script pipeline handles, and when one of its callbacks is invoked by name. The schedule each one runs in is in italics.
flowchart TB
COMP(["ScriptComponent added / removed"]) -- "<i>PreUpdate</i>" --> PIPE[["script pipeline"]]
CMDS(["AttachScript / DetachScript"]) -- "<i>immediately</i>" --> PIPE
PIPE --> LIVE((attached))
subgraph CALLBACKS ["callbacks, run by name"]
direction LR
EH["event_handler<br/><i>your schedule</i>"] ~~~ CMD["RunScriptCallback<br/><i>on command flush</i>"] ~~~ SYS["script systems<br/><i>their schedule</i>"]
OBS["observers<br/><i>on trigger</i>"] ~~~ OTHER["other scripts<br/><i>immediately or queued</i>"]
end
LIVE <--> CALLBACKS
LIVE -. "asset modified, <i>PreUpdate</i>" .-> PIPE
click PIPE href "#the-script-pipeline"
The script pipeline
flowchart LR
subgraph PRE ["script pipeline"]
direction LR
A(["attached"]) --> L["context initializers<br/>top level code<br/>on_script_loaded"]
M(["asset modified"]) --> R["on_script_unloaded<br/>top level code<br/>on_script_loaded<br/>on_script_reloaded"]
D(["detached"]) --> U["on_script_unloaded<br/>context removed<br/>with its last script"]
end
- The attachment (entity + script, or a static script) is the script’s identity, see Managing Scripts. Scripts sharing a context share globals.
- Callbacks run the function passed to
register_callback, else the top level function of that name, see Running Scripts and Calling Other Scripts. on_script_*are the core callbacks.on_script_unloadedcan return state, whichon_script_reloadedreceives.- Ordering and budgeting are covered in Script Pipeline.
Where to start
| You are | Read |
|---|---|
| Adding scripting to a Bevy game | Installation, then the User Guide |
| Writing scripts or mods | The Scripting Reference |
| Upgrading BMS | The Release Notes |
| Contributing to BMS | Developing BMS |