Bevy Forge 0.1.0: visual scene editor for Bevy 0.20 BSN
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
# ◆ 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.
|
||||
|
||||
## Two viewports
|
||||
|
||||
| 2D scene editing | 3D wireframe preview |
|
||||
|---|---|
|
||||
|  |  |
|
||||
|
||||
## Features
|
||||
|
||||
- **Project-aware editor.** Opens a directory containing a `Cargo.toml` with a `bevy` dependency,
|
||||
indexes its `assets/` folder and lists its `scenes/*.forge.ron` files.
|
||||
- **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` / `info` severities.
|
||||
- **Persistence.** Human-readable `.forge.ron` scenes, atomic writes, optional autosave.
|
||||
- **Two export formats.** Bevy 0.20 BSN (`bsn!` / `bsn_list!`) and imperative Rust with
|
||||
`Commands::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 same `eframe` backend 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-smoke` crate.
|
||||
- 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
1. Select an entity in the hierarchy and edit it in the inspector.
|
||||
2. Switch the viewport between 2D and 3D with `2` / `3`.
|
||||
3. Press `Ctrl+E` (Cmd+E on macOS) to open the export dialog and copy the generated BSN.
|
||||
4. Press `Ctrl+S` to save the scene to `scenes/<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:
|
||||
|
||||
```bash
|
||||
# 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):
|
||||
|
||||
```bash
|
||||
# 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.
|
||||
|
||||
```bash
|
||||
# From the game project's root: write the generated module into src/.
|
||||
forge export scenes/garden.forge.ron --format bsn -o src/garden.rs
|
||||
```
|
||||
|
||||
```rust
|
||||
// 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` / `materials` parameters (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 with
|
||||
`commands.spawn_scene_list(...)`.
|
||||
- Custom components are emitted as `<type_path> { field: <raw expression> }`. The component type
|
||||
must derive `Component` plus either `Default + Clone` or `FromTemplate`, 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](docs/bsn-export.md).
|
||||
|
||||
## 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](docs/format.md) - every field and component variant, versioning,
|
||||
identity and forest invariants, asset paths, save/autosave and validation.
|
||||
- [Architecture](docs/architecture.md) - crates, data flow, key types and the panel/action model.
|
||||
|
||||
## Project layout
|
||||
|
||||
```text
|
||||
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 `.bsn`
|
||||
asset 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
|
||||
`rustc` on exported code.
|
||||
- **Material asset caveat.** There is no `StandardMaterial` asset loader by default. Generated BSN
|
||||
uses inline `materials.add(StandardMaterial { ... })`, so it does not need a registered material
|
||||
loader; hand-referenced material assets such as `materials/cube.toml` do 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_ui` editor, 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
|
||||
|
||||
1. Read [the architecture notes](docs/architecture.md) and [the scene format](docs/format.md).
|
||||
Public model APIs are small and should stay stable.
|
||||
2. Keep the dependency rule: `bevy_forge_core` and `bevy_forge_editor` never depend on Bevy; the
|
||||
excluded `compat/bsn-smoke` crate is the only Bevy-dependent crate.
|
||||
3. Format with `cargo fmt` and keep `cargo check --workspace` warning-free for the crates you
|
||||
touch. Do not add dependencies without agreement.
|
||||
4. Tests live next to the code (`#[cfg(test)]` modules) and under `crates/*/tests/`; CLI tests run
|
||||
the real binary with `CARGO_BIN_EXE_forge`. The generated-code gate compiles exported BSN in
|
||||
`compat/bsn-smoke`.
|
||||
5. 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):
|
||||
|
||||
```bash
|
||||
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](LICENSE-MIT) and [LICENSE-APACHE](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.
|
||||
Reference in New Issue
Block a user