Blacksite/docs/editor/brp.md

6.4 KiB
Raw Permalink Blame History

Bevy Remote Protocol (BRP)

The editor enables Bevys 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:

cargo run -p editor --features dev

Default HTTP endpoint follows Bevy 0.19 remote defaults (port 15702, routes under /remote/).

Authoring-only mutation policy

BRP and durable 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, WorldAssetRoot, etc.) on the next frame. One deliberate editor-only exception exists for MaterialPropertyBlocks: trusted local tooling may inject this explicitly runtime-only component to preview or promote a transient override. It is still excluded from scene/prefab persistence and the Add Component registry.

Allowed (examples) Forbidden on level objects
Transform, Name, ActorKind PointLight, SpotLight, DirectionalLight
Primitive, StaticMeshRenderer, SkinnedMeshRenderer, brush-only legacy MaterialDesc, LightDesc Mesh3d, MeshMaterial3d, RigidBody, Collider
ModelRef, RigidBodyDesc, ColliderDesc, legacy PhysicsBody, gameplay markers WorldAssetRoot, generated static/skinned roots, internal visibility types
PostProcessVolumeDesc Runtime post-process components on cameras

shared::renderer_material::MaterialPropertyBlocks is a runtime diagnostic/tooling exception, not a durable authoring component. Use Promote to Material Instance in the exact Inspector slot when the variation should become project content.

Prefer:

  1. Editing LightDesc instead of SpotLight / DirectionalLight
  2. Editing the owning Primitive.surface or renderer MaterialSlotSet instead of StandardMaterial handles; MaterialDesc is limited to the brush/legacy fallback path
  3. Editing StaticMeshRenderer instead of child Mesh3d entities
  4. Editing SkinnedMeshRenderer instead of its hydrated joint/mesh hierarchy
  5. Editing ColliderDesc / RigidBodyDesc instead of runtime Avian components
  6. Version-controlled assets/levels/*.scn.ron for durable changes

See ADR 0009 — Authoring vs hydrated.

Example flows

List entities

curl -s http://127.0.0.1:15702/remote/world/entities | head

Get entity components

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)

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)

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

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 and prefab dependency graphs without the editor UI:

cargo validate-levels
# JSON for CI, packaging, or external tools
cargo validate-levels --json

This runs the shared scene::validate_project report used by the editor Diagnostics window. It validates authored levels and recursive prefab/composition graphs, emits an owner-attributed dependency manifest, reports blocking content references, and exits nonzero on errors. --project <path> validates another project root. The graph pass validates link paths, stable actor identity, cycles, anchors, and override payloads without starting the editor. The same report scans project settings and asset roots, registry/import dependencies, generated mesh manifests, material and shader documents, post effects, brush geometry, collider dimensions, Git LFS hydration, and platform requirements. Validation and packaging share one runtime-inclusion policy: hidden/editor trees, source formats such as PSD/Blend, symlinks, and unreadable traversal are blocking when a runtime dependency reaches them. asset.git_lfs_object_missing is blocking; run git lfs pull in the project checkout and rerun validation before building a package.

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.