133 lines
4.6 KiB
Markdown
133 lines
4.6 KiB
Markdown
# Bevy Remote Protocol (BRP)
|
||
|
||
The editor enables Bevy’s built-in **Remote Plugin** over HTTP for automation, CI, and future tooling interop. BRP is **editor-only** — the shipped `game` binary does not expose a port.
|
||
|
||
## Enablement
|
||
|
||
`BrpPlugin` in `crates/editor/src/ext/brp.rs` adds:
|
||
|
||
- `RemotePlugin` — core remote API
|
||
- `RemoteHttpPlugin` — HTTP transport
|
||
|
||
Launch the editor with dev features as usual:
|
||
|
||
```bash
|
||
cargo run -p editor --features dev
|
||
```
|
||
|
||
Default HTTP endpoint follows Bevy 0.18 remote defaults (port **15702**, routes under `/remote/`).
|
||
|
||
## Authoring-only mutation policy
|
||
|
||
**BRP and automation must mutate authoring components only** — the same allowlist used on scene save in `scene_io.rs`. Hydration rebuilds runtime ECS (`Mesh3d`, Bevy lights, physics, `SceneRoot`, etc.) on the next frame.
|
||
|
||
| Allowed (examples) | Forbidden on level objects |
|
||
|--------------------|----------------------------|
|
||
| `Transform`, `Name`, `ActorKind` | `PointLight`, `SpotLight`, `DirectionalLight` |
|
||
| `Primitive`, `StaticMeshRenderer`, `MaterialDesc`, `MaterialOverride`, `LightDesc` | `Mesh3d`, `MeshMaterial3d`, `RigidBody`, `Collider` |
|
||
| `ModelRef`, `RigidBodyDesc`, `ColliderDesc`, legacy `PhysicsBody`, gameplay markers | `SceneRoot`, generated static mesh children, internal visibility types |
|
||
| `PostProcessVolumeDesc` | Runtime post-process components on cameras |
|
||
|
||
Prefer:
|
||
|
||
1. Editing `LightDesc` instead of `SpotLight` / `DirectionalLight`
|
||
2. Editing `MaterialDesc` instead of `StandardMaterial` handles
|
||
3. Editing `StaticMeshRenderer` instead of child `Mesh3d` entities
|
||
4. Editing `ColliderDesc` / `RigidBodyDesc` instead of runtime Avian components
|
||
5. Version-controlled `assets/levels/*.scn.ron` for durable changes
|
||
|
||
See [ADR 0009 — Authoring vs hydrated](../adr/0009-authoring-vs-hydrated.md).
|
||
|
||
## Example flows
|
||
|
||
### List entities
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:15702/remote/world/entities | head
|
||
```
|
||
|
||
### Get entity components
|
||
|
||
```bash
|
||
curl -s -X POST http://127.0.0.1:15702/remote/world/get \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"entity":4294967296,"components":["bevy_transform::Transform"]}'
|
||
```
|
||
|
||
### Mutate authoring transform (automation smoke)
|
||
|
||
```bash
|
||
curl -s -X POST http://127.0.0.1:15702/remote/world/mutate \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"entity":4294967296,"component":"bevy_transform::Transform","value":{"translation":[0,2,0]}}'
|
||
```
|
||
|
||
Replace `entity` with a live id from the list call while the editor is running.
|
||
|
||
### Mutate `LightDesc` (not runtime lights)
|
||
|
||
```bash
|
||
curl -s -X POST http://127.0.0.1:15702/remote/world/mutate \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"entity":ENTITY_ID,"component":"shared::components::LightDesc","value":{...}}'
|
||
```
|
||
|
||
Hydration applies the change to viewport lighting after the next update.
|
||
|
||
### Mutate `PostProcessVolumeDesc`
|
||
|
||
```bash
|
||
curl -s -X POST http://127.0.0.1:15702/remote/world/mutate \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"entity":ENTITY_ID,"component":"shared::components::PostProcessVolumeDesc","value":{...}}'
|
||
```
|
||
|
||
Overrides use `None` = inherit project; `Some(v)` = local override per field.
|
||
|
||
## Editor command palette bridge
|
||
|
||
Registered commands in `extensibility.rs` are invokable via **Ctrl+P** and `PendingEditorCommands`:
|
||
|
||
| Command | Action |
|
||
|---------|--------|
|
||
| `play.toggle` | Edit / Play |
|
||
| `play.toggle_pause` | Pause / resume sim in Play |
|
||
| `play.toggle_possession` | Possess / eject (Play only) |
|
||
| `scene.reset_lighting` | Remove all authored `LightDesc`; use project sun/ambient |
|
||
| `selection.group` | Spawn empty group; reparent selection |
|
||
| `selection.focus` | Frame editor camera on selection (same as **F**) |
|
||
| `rendering.create_volume` | Spawn post-process volume at editor camera |
|
||
| `rendering.select_volumes_at_camera` | Select highest-priority volume at camera |
|
||
| `rendering.focus_active_volumes` | Select + frame volumes at camera |
|
||
|
||
External automation can enqueue the same names through the editor command queue when integrated.
|
||
|
||
## CI / headless validation
|
||
|
||
Validate committed levels without the editor UI:
|
||
|
||
```bash
|
||
cargo run -p xtask --bin validate-levels
|
||
```
|
||
|
||
This runs `scene::validate_level_file` (schema migrate + **authoring-only** component check).
|
||
|
||
```bash
|
||
cargo test -p shared
|
||
cargo test -p scene
|
||
cargo check -p editor --features dev
|
||
```
|
||
|
||
## Safety
|
||
|
||
- Run BRP only in trusted local dev environments.
|
||
- Do not enable `BrpPlugin` in production game builds.
|
||
- Scene files remain the source of truth; prefer version-controlled `assets/levels/*.scn.ron` over live mutation for durable changes.
|
||
|
||
## Related
|
||
|
||
- [Editor architecture](architecture.md)
|
||
- [Debt audit checklist](debt-audit.md)
|
||
- [Mission — BRP-aligned tooling](../mission.md)
|
||
- [Release notes](release-notes.md)
|