Reviewed-on: #1
◆ Bevy Forge
A native visual scene editor for the Bevy engine, built around Bevy 0.20's BSN scene notation.
Bevy Forge opens a Bevy project, lets you lay out a 2D or 3D scene with a hierarchy, inspector,
viewports and asset browser, then exports the result as paste-ready BSN Rust code (primary)
or imperative Commands::spawn code. Everything is editable by hand: scenes are plain RON files
and generated code is ordinary Rust.
Status: early alpha (0.1.0). The 0.1 feature set is implemented: the workspace tests, formatting check, CLI and generated-BSN compile gate are green on this checkout. This is not a tagged release, so expect rough edges and API churn before 0.1.0 is published.
Why a standalone editor?
Bevy Forge does not link Bevy. The editor and core crates build without pulling Bevy into the dependency graph and are not affected by Bevy's release cadence; they target Bevy 0.20 through generated code. The scene format is an editor-owned RON file, and export produces source code that your game compiles. That keeps the tool independent of Bevy's runtime scene serialization and makes the output easy to review, diff and check in.
Live in-game editing (a Bevy plugin with a remote protocol) is a roadmap item, not part of this editor.
v2 live editor (M0 spike)
The v2-live-editor branch moves editing into the game as a Bevy 0.20 plugin with native Bevy
UI and official bevy_ui_widgets — no egui in the runtime crate. M0 ships the EditorPlugin, a
fixed editor shell, live hierarchy, reflection inspector, translate gizmo, editor camera and
deterministic screenshots at 1440×900 / 1000×640.
cargo run -p bevy_forge_runtime --example editor_spike
See docs/m0-spike.md for controls, architecture and M0 limits. The v1 standalone editor below remains the current released workflow.
M1 Core — real scene load/save + undo
M1 loads a real .forge.ron scene through bevy_forge_core, saves edits with Ctrl+S, adds
Transform undo/redo (Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y) and the F focus, Delete and Ctrl+D duplicate
hotkeys.
FORGE_PROJECT=examples/demo-project \
FORGE_SCENE=scenes/garden.forge.ron \
cargo run -p bevy_forge_runtime --example editor_live
See docs/m1-core.md for the garden demo, hotkeys and M1 limits.
M2 Live — play mode, assets, export, hot reload
M2 adds Play/Pause/Stop with transform snapshot/restore, a project asset browser, BSN/Rust export
and a .forge.ron transform watcher.
FORGE_PROJECT=examples/demo-project \
FORGE_SCENE=scenes/garden.forge.ron \
cargo run -p bevy_forge_runtime --example editor_live
See docs/m2-live.md for controls and M2 limits.
Two viewports
| 2D scene editing | 3D wireframe preview |
|---|---|
![]() |
![]() |
Features
- Project-aware editor. Opens a directory containing a
Cargo.tomlwith abevydependency, indexes itsassets/folder and lists itsscenes/*.forge.ronfiles. - Hierarchy panel. Create empty entities, sprites, text, cameras, lights and primitive meshes; rename inline; duplicate; delete; reparent and reorder by dragging (cycles rejected); lock and hide entities; search the tree.
- Inspector. Name and Transform editing (translation, Euler rotation, scale, reset); add/remove components; asset pickers for images and meshes; colour and numeric editors; mesh primitive parameters and material presets; validation issues for the selected entity.
- 2D viewport. Textured sprites, text and camera/light glyphs, grid and axes, pan and cursor-anchored zoom, click selection, grid-snapped dragging, X/Y translate gizmo, drag-and-drop of images from the asset browser, fit view.
- 3D viewport. egui-painted wireframe preview (no GPU renderer): orbit/pan/zoom camera, grid, primitive and sprite proxies, camera/light glyphs, click selection, ground-plane dragging, fit.
- Asset browser. Recursive index of the Bevy
assets/directory with kind filters, search, lazy thumbnails, double-click assignment and drag payloads for viewports. - Undo/redo. Snapshot-based history (100 steps by default) for every structural and property edit, including a single undo entry per gizmo drag.
- Validation. Structural, asset-reference and numeric range checks surfaced in the UI and by
the CLI, with
error/warning/infoseverities. - Persistence. Human-readable
.forge.ronscenes, atomic writes, optional autosave. - Two export formats. Bevy 0.20 BSN (
bsn!/bsn_list!) and imperative Rust withCommands::spawn+.with_children. - Command line.
forge new,forge validate,forge export,forge info,forge scenes. - Editor chrome. Dark theme, menu bar, status bar, command palette, toasts, welcome screen, keyboard-shortcut reference and unsaved-changes protection.
Requirements
- Rust stable, 1.85 or newer (the workspace sets
rust-version = "1.85") and Cargo. - A desktop session with a working GPU/windowing stack for
eframe/egui: Linux (X11 or Wayland), macOS, or Windows. Linux/Wayland is the primary development platform; macOS and Windows go through the sameeframebackend but are less exercised. - No Bevy installation is needed to build the editor or the CLI. Bevy 0.20 is only needed when
you compile exported code inside a game, or when you check the excluded
compat/bsn-smokecrate. - A network connection the first time Cargo fetches dependencies, unless they are already cached.
In the prepared development environment, prefix routine builds with
CARGO_NET_OFFLINE=true.
Quick start
# 1. From this repository checkout.
cd bevy-forge
# 2. Run the editor on the bundled demo project.
cargo run -p bevy_forge_editor -- examples/demo-project
# 3. Or open a single scene directly (the project is discovered by walking up
# to the nearest Cargo.toml).
cargo run -p bevy_forge_editor -- examples/demo-project/scenes/garden.forge.ron
The editor binary is named bevy-forge. Launched without an argument it shows the welcome screen;
open a project by path (for example examples/demo-project), then pick a scene. Passing a project
or scene path on the command line opens it directly. From there:
- Select an entity in the hierarchy and edit it in the inspector.
- Switch the viewport between 2D and 3D with
2/3. - Press
Ctrl+E(Cmd+E on macOS) to open the export dialog and copy the generated BSN. - Press
Ctrl+Sto save the scene toscenes/<name>.forge.ron.
A new scene can be started from File > New scene (empty, 2D starter or 3D starter) or scaffolded together with a Bevy project from the CLI.
CLI
forge is the command-line companion. Run it through Cargo, or install the binary from this
repository:
# Run from the workspace root without installing:
cargo run -p bevy_forge_cli -- --help
# Optional: install the `forge` binary into ~/.cargo/bin.
cargo install --path crates/bevy_forge_cli
Common commands (all paths are examples):
# Scaffold a new Bevy 0.20 project. The target must not exist or must be empty.
forge new my-game --name my_game --template 3d
# Validate a scene; --project is discovered from the scene path when omitted.
forge validate examples/demo-project/scenes/garden.forge.ron
forge validate examples/demo-project/scenes/garden.forge.ron --json
# Export BSN (default) or imperative Rust.
forge export examples/demo-project/scenes/garden.forge.ron --format bsn -o /tmp/garden.rs
forge export examples/demo-project/scenes/platformer.forge.ron --format rust --function platformer
# Summarise a scene and list a project's scenes.
forge info examples/demo-project/scenes/garden.forge.ron
forge scenes examples/demo-project
forge new --template accepts empty, 2d (default) or 3d. It writes a complete Bevy 0.20
project: Cargo.toml, src/main.rs, assets/ (generated textures where the template needs them),
scenes/demo.forge.ron, .gitignore and a README.md.
Exit codes follow the CLI contract:
| Command | 0 |
1 |
2 |
|---|---|---|---|
forge new |
project created | - | target exists and is not empty, I/O error |
forge validate |
no validation errors | validation errors found | I/O, RON parse or usage error |
forge export |
code generated | codegen error (empty scene, invalid function name, non-finite value, bad custom component) | I/O, RON parse or usage error |
forge info |
printed | - | I/O, RON parse or usage error |
forge scenes |
listed | - | not a project or I/O error |
--help and --version are available on every command level. Human-readable output goes to
stdout; user errors go to stderr with a non-zero exit.
Getting BSN into a Bevy app
Export BSN from the editor (File > Export > BSN scene) or the CLI. The result is a Rust module, not a runtime asset: put it next to your game code and call the generated function from a startup system.
# From the game project's root: write the generated module into src/.
forge export scenes/garden.forge.ron --format bsn -o src/garden.rs
// src/main.rs of a Bevy 0.20 game
use bevy::prelude::*;
mod garden; // the exported file; its function is `garden::scene(..)`
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, spawn_garden)
.run();
}
fn spawn_garden(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// The generated signature includes only the asset parameters the scene needs.
commands.spawn_scene(garden::scene(&mut meshes, &mut materials));
}
- A scene without meshes generates
pub fn scene() -> impl Scene- call it with no arguments. - A scene with meshes generates
meshes/materialsparameters (only the ones it uses). Pass&mut Assets<Mesh>/&mut Assets<StandardMaterial>from your systems. - A scene with several roots generates
pub fn scene() -> impl SceneList; spawn it withcommands.spawn_scene_list(...). - Custom components are emitted as
<type_path> { field: <raw expression> }. The component type must deriveComponentplus eitherDefault + CloneorFromTemplate, and must be in scope where the generated code is compiled.
The full template reference, derive requirements, material caveats and a troubleshooting table are in the BSN export guide.
Scene format
Scenes are human-readable RON files named *.forge.ron, stored in the project's scenes/
directory. They are Bevy Forge's own format - not Bevy's .scn.ron dynamic-scene serialization -
and contain no generated code.
- Scene format reference - every field and component variant, versioning, identity and forest invariants, asset paths, save/autosave and validation.
- Architecture - crates, data flow, key types and the panel/action model.
Project layout
bevy-forge/
Cargo.toml workspace (core, editor, CLI)
crates/
bevy_forge_core/ scene model, project, undo, assets, validation, codegen
bevy_forge_editor/ eframe/egui desktop app; binary `bevy-forge`
bevy_forge_cli/ `forge` command line
examples/demo-project/ Bevy 0.20 demo project with garden (3D) and platformer (2D) scenes
compat/bsn-smoke/ excluded crate that compiles generated BSN against Bevy 0.20
docs/ architecture, scene format, BSN export
scripts/ generated-code verification helpers
Keyboard shortcuts
Ctrl means Cmd on macOS. Shortcuts that mutate the scene are ignored while a text field has
keyboard focus.
| Shortcut | Action |
|---|---|
Ctrl+S |
Save the current scene |
Ctrl+Shift+S |
Save the scene as... |
Ctrl+O |
Open a project... |
Ctrl+K |
Command palette |
F1 |
Keyboard-shortcut reference |
Ctrl+Z |
Undo |
Ctrl+Shift+Z, Ctrl+Y |
Redo |
Ctrl+D |
Duplicate selection |
Delete |
Delete selection |
Ctrl+E |
Export BSN scene |
Ctrl+Shift+E |
Export imperative Rust |
F |
Fit the active viewport to the scene |
G |
Toggle the grid |
2 / 3 |
Switch to the 2D / 3D viewport |
Ctrl+B |
Toggle the asset browser |
Ctrl+Shift+L |
Toggle the hierarchy panel |
Esc |
Clear the selection (while not typing) |
Command palette: type to filter, Up/Down to move, Enter to run, Esc to close.
Mouse and pointer interactions:
| Context | Input | Action |
|---|---|---|
| Hierarchy | click / Ctrl+click / Shift+click |
Select / toggle / extend selection |
| Hierarchy | double-click, right-click | Rename inline, context menu (rename, duplicate, delete, focus, lock) |
| Hierarchy | drag | Reparent or reorder (cycle-creating drops are rejected) |
| 2D viewport | middle mouse, or Space+left mouse |
Pan |
| 2D viewport | mouse wheel | Zoom around the cursor |
| 2D viewport | click / Shift+click |
Select topmost / toggle |
| 2D viewport | drag selection, X/Y gizmo handles | Move (grid-snapped when enabled) |
| 3D viewport | middle mouse, or Alt+left mouse |
Orbit |
| 3D viewport | Shift+middle mouse |
Pan |
| 3D viewport | mouse wheel | Zoom |
| 3D viewport | click, drag | Select, move on the ground plane |
Locked entities ignore viewport transforms; hidden entities are skipped by picking. Pan, zoom, orbit and fit never modify the document.
Limitations and roadmap
Bevy Forge is deliberately focused. Current limitations:
- No live editing. The editor is standalone; there is no in-game plugin, remote protocol or hot reload of a running Bevy app.
- BSN is source code, not an asset. Export writes Rust that your game compiles. Runtime
.bsnasset loading/caching is not implemented. - Custom components are raw expressions. The editor does not parse your Rust types, so custom component fields are stored as raw Rust/BSN expressions with only basic identifier and non-empty-expression checks.
- Validation is static. It checks structure, asset references and value ranges; it does not run
rustcon exported code. - Material asset caveat. There is no
StandardMaterialasset loader by default. Generated BSN uses inlinematerials.add(StandardMaterial { ... }), so it does not need a registered material loader; hand-referenced material assets such asmaterials/cube.tomldo need one in your game. - 3D preview, not a renderer. The 3D viewport paints wireframes and proxies with egui. There is no PBR preview, shadow preview or GPU scene rendering.
- Editor features out of scope for 0.1: animation editor,
bevy_uieditor, material graph, terrain tools, collaboration, asset import pipeline. - Bevy 0.20 only. Generated code targets Bevy 0.20.0 BSN. Legacy dynamic-scene (
.scn.ron) syntax and broad multi-version support are out of scope. - No native file dialogs. Paths are typed into in-app dialogs.
- Undo history is in-memory (100 steps by default) and is cleared when a scene is opened.
Roadmap direction: in-game live editing over a plugin/remote protocol, runtime scene assets, richer asset previews and a plugin-facing API. Roadmap items are not implemented yet.
Contributing
- Read the architecture notes and the scene format. Public model APIs are small and should stay stable.
- Keep the dependency rule:
bevy_forge_coreandbevy_forge_editornever depend on Bevy; the excludedcompat/bsn-smokecrate is the only Bevy-dependent crate. - Format with
cargo fmtand keepcargo check --workspacewarning-free for the crates you touch. Do not add dependencies without agreement. - Tests live next to the code (
#[cfg(test)]modules) and undercrates/*/tests/; CLI tests run the real binary withCARGO_BIN_EXE_forge. The generated-code gate compiles exported BSN incompat/bsn-smoke. - Update the relevant page in
docs/when behaviour or a template changes.
Useful verification commands (run them in your checkout; no claim is made that they are green at every commit):
cargo check --workspace
cargo test --workspace
cargo fmt --all --check
cargo run -p bevy_forge_cli -- validate examples/demo-project/scenes/garden.forge.ron
cd compat/bsn-smoke && cargo check
License
Bevy Forge is dual-licensed under the MIT OR Apache-2.0 license, at your option. See LICENSE-MIT and LICENSE-APACHE. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be dual-licensed as above, without any additional terms or conditions.

