- load .forge.ron through bevy_forge_core into the live ECS (3D components) - Ctrl+S syncs and saves the document; custom components are preserved - transform undo/redo for inspector sliders and gizmo drags (Ctrl+Z/Y) - F focus, Delete subtree, Ctrl+D duplicate; camera subtrees are guarded - 66 runtime tests; workspace 412 passed; garden demo docs/screenshots
5.2 KiB
Bevy Forge v2 — M1 Core
Status: M1 Core complete and independently verified (pass_with_risks). M0 is committed at
59212c9; M1 turns the M0 spike into a scene-editing slice that reads and writes the existing
bevy_forge_core .forge.ron format.
1000×640 variant: m1-core-1000x640.png.
What M1 adds
- Real scene load:
FORGE_PROJECT+FORGE_SCENEload a.forge.ronscene throughbevy_forge_coreinto the live ECS. The garden demo is the reference scene. - Save: Ctrl+S syncs edited transforms/names/visibility back into the scene document and writes
a
.forge.ronfile (FORGE_SAVE_PATH, defaultscenes/edited.forge.ron). - Transform undo/redo: Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y for inspector-slider and gizmo-drag edits.
- Hotkeys: Ctrl+S save, F focus camera, Delete delete the selected subtree, Ctrl+D duplicate the selected subtree.
- Focused tests: 66 runtime tests (scene 6, shortcuts 6, history 8, inspector 13, gizmo 10, plus the M0 suite), all green.
- Independent verification: V11 pass_with_risks (
.swarm/m1/reviews/V11.md), including a post-review delta after the camera guard. Runtime 66 tests, workspace 412 passed, 2 ignored. - Interactive checks done: load 9/7, slider edit → Ctrl+Z → Ctrl+Shift+Z, Ctrl+S with a valid saved RON (garden source untouched), Ctrl+D duplicate, Delete, F focus, camera delete/duplicate refusal, no panic.
Run
cd bevy-forge
FORGE_PROJECT=examples/demo-project \
FORGE_SCENE=scenes/garden.forge.ron \
cargo run -p bevy_forge_runtime --example editor_live
| Variable | Default | Meaning |
|---|---|---|
FORGE_PROJECT |
examples/demo-project |
project root with a Cargo.toml containing bevy |
FORGE_SCENE |
scenes/garden.forge.ron |
scene to load, relative to the project root |
FORGE_SAVE_PATH |
scenes/edited.forge.ron |
Ctrl+S output, relative to the project root |
The scene plugin loads when at least one of FORGE_PROJECT/FORGE_SCENE is set; the command above
sets both. The garden scene has 9 entities / 7 roots (Camera, Sun, Ground, Shrub, Flower Stem, Flower Bloom,
Orbit Crystal, Lantern Post, Lantern Glow). The custom forge_demo::Orbit component is skipped in
the live ECS with a warning; all 3D meshes, lights, camera, names, transforms and visibility load.
Controls
| Input | Action |
|---|---|
| F1 / Editor (F1) | Toggle the editor UI |
| Click hierarchy row | Select entity |
| Drag inspector Translation X/Y/Z | Move selected entity |
| Drag gizmo axis | Move selected entity |
| Right/middle drag, wheel | Orbit / pan / zoom camera |
| Ctrl+S | Save .forge.ron |
| Ctrl+Z | Undo transform edit |
| Ctrl+Shift+Z / Ctrl+Y | Redo transform edit |
| F | Focus camera on selected entity |
| Delete | Delete selected subtree |
| Ctrl+D | Duplicate selected subtree |
Delete/duplicate are structural edits and are not undoable in M1; undo/redo is Transform-only.
Architecture
crates/bevy_forge_runtime/
├── src/scene.rs .forge.ron load, ECS spawn, save/sync, delete/duplicate helpers
├── src/shortcuts.rs Ctrl+S / F / Delete / Ctrl+D
├── src/history.rs transform command stack + Ctrl+Z/Y
├── src/inspector.rs M0 reflection inspector + history capture
├── src/gizmo.rs M0 camera/gizmo + history capture
├── src/hierarchy.rs M0 live tree
└── examples/editor_live.rs
The runtime now depends on bevy_forge_core (Bevy-free model/persistence). Core Transform uses
XYZ Euler degrees; the bridge converts to/from Bevy quaternions with
bevy_forge_core::math::{quat_from_euler_deg, quat_to_euler_deg}.
Limits (M1)
- 3D only in the live bridge; Sprite/Text2d/Camera2d components are skipped (M2).
- Custom components are skipped in ECS but preserved in the document on save.
- Delete/duplicate are not undoable; multi-select/docking/terminal/play mode are out of scope.
- Deleting or duplicating a
Camera3dsubtree is refused with a warning in M1: the editor camera is adopted from the scene, and a second active camera would break the viewport. - V11 residual: a synthetic portal drag can be shorter than one Bevy frame, so the live gizmo drag → Ctrl+Z path and the inspector click/snap finalizer remain unit/helper-tested rather than scripted end-to-end. Slider-drag undo is interactively verified.
- The garden
Camera3dis adopted by the editor camera; do not add a second active camera. - Saving must be explicit (Ctrl+S); there is no autosave loop yet.
- Hover styling and screenshot determinism: park the pointer outside the window for byte-stable screenshots (M0 caveat).
- A synthetic portal drag can be shorter than one Bevy frame, so the live gizmo-drag → Ctrl+Z path is covered by transform helper/unit tests and the unchanged M0 drag code, not by a scripted mouse hold; the slider undo path is interactively verified.
Verification
M0 acceptance is in m0-spike.md. M1 was independently verified by V11:
.swarm/m1/reviews/V11.md (initial and post-fix delta). The exact commands are in
.swarm/m1/plan.md; the final report with actual spend is in the local M1 coordination dir.
