# Editor Framework Documentation Docs for the in-process egui editor (`crates/editor/`). Update this index when adding editor subsystems. ## Documents | Document | Contents | |----------|----------| | [roadmap.md](roadmap.md) | Phased editor work and status | | [architecture.md](architecture.md) | Plugins, cameras, PIE, settings split | | [brp.md](brp.md) | Remote protocol, authoring-only policy, commands | | [debt-audit.md](debt-audit.md) | Zero-debt phase gates and remaining items | | [rendering.md](rendering.md) | GI modes, post-process volumes, presets, post FX assets | | [brushes.md](brushes.md) | Brush authoring schema, hydration behavior, and MVP limits | | [operator-regression-testing.md](operator-regression-testing.md) | Shared modal-tool commit/cancel/dirty/helper/undo invariants | | [session-recovery.md](session-recovery.md) | Versioned restart state, clean/crash behavior, and privacy boundary | | [project-launcher.md](project-launcher.md) | Pre-engine project selection, manifest identity, recents, and sandbox contract | | [build-and-package.md](build-and-package.md) | Non-blocking editor builds, headless profiles, runtime output, and metadata | | [multi-scene-composition.md](multi-scene-composition.md) | Scene tabs, stable subscene references, ownership, validation, and recovery | | [prefab-authoring.md](prefab-authoring.md) | Stable nested overrides, source Apply/conflicts, variants, unpacking, and local conversion | | [audio-authoring.md](audio-authoring.md) | Audio clip placement, source/listener controls, audition, buses, runtime parity, and validation | | [animation-authoring.md](animation-authoring.md) | glTF rig/clip import, stable controller states, preview, runtime API, and validation | | [navigation-authoring.md](navigation-authoring.md) | Bounds, source geometry, deterministic bake, viewport path preview, and runtime query workflow | | [extensibility.md](extensibility.md) | Static authoring component lifecycle registration, stable IDs, composition, and generic history | | [material-system.md](material-system.md) | Shared Material/Material Instance assets, static/skinned renderer slots, Surface ABI, Solari scope, and migration | | [evaluations/material-renderer-foundation/](evaluations/material-renderer-foundation/) | Live screenshots and verification record for the renderer/material/component foundation | | [evaluations/navigation-authoring/](evaluations/navigation-authoring/) | Live screenshots and verification record for navigation authoring and runtime parity | ## Subsystems (code → doc) | Code module | Responsibility | Doc | |-------------|----------------|-----| | `lib.rs` / `EditorPluginGroup` | Ordered plugin bundle, lib/bin split | ADR 0008, architecture.md | | `shared::components::BrushDesc` / `shared::hydration::brushes` | Persisted brush authoring data and generated runtime mesh hydration | brushes.md, ADR 0021 | | `scene/` | Level I/O, tabs, composition materialization, schema, viewport render-target setup | architecture.md, multi-scene-composition.md, ADR 0026 | | `viewport/` | Camera, selection, gizmos, render views | architecture.md | | `play/` | PIE session, editor mode state | architecture.md | | `play/audio_preview.rs` / `game::audio` | Non-dirty editor audition and authored runtime playback/bus adapter | audio-authoring.md, ADR 0030 | | `assets/animation.rs` / `ui/animation_inspector.rs` / `game::animation` | Generated animation manifests, controller authoring/preview, and runtime state adapter | animation-authoring.md, ADR 0031 | | `ui/navigation_inspector.rs` / `scene::navigation` / `game::navigation` | Navigation authoring, deterministic bake artifacts, viewport preview, and runtime path queries | navigation-authoring.md, ADR 0032 | | `assets/materials.rs` / `shared::renderer_material` / `shared::hydration::{static_meshes,skinned_meshes}` | Shared material discovery, stable renderer slots, and draw binding | material-system.md, ADR 0035 | | `blacksite_surface` / `game_hot::rendering::solari` / `third_party/bevy_solari` | Surface ABI packing, raster composition, Solari evaluator dispatch, and deformation eligibility | material-system.md, rendering.md, ADR 0036 | | `assets/` | Catalog, asset DB, static mesh artifacts, `thumbnails/`, `materials.rs`, prefab overrides v2 | this file (below), prefab-authoring.md, ADR 0017, ADR 0027 | | `shared::prefab_overrides` | Versioned stable override schema and editor-independent runtime application | prefab-authoring.md, ADR 0027 | | `project/` | Workspace, settings UI, user prefs, support diagnostics | roadmap Phase 1 | | `project/session.rs` | Versioned XDG session document, clean marker, and safe resume | session-recovery.md, ADR 0024 | | `project/diagnostics_bundle.rs` | Privacy-bounded transactional support report export | session-recovery.md, ADR 0024 | | `project/launcher.rs` | Strict project inspection, CLI activation, recent filtering, and sandbox scaffolding | project-launcher.md, ADR 0025 | | `ext/` | Command palette, BRP, game panel adapters | ADR 0007 | | `ui/mod.rs` | Dock layout, unified viewport, menus | README controls | | `ui/scene_tabs.rs` | Main-toolbar scene tabs and composition controls | multi-scene-composition.md, ADR 0026 | | `ui/component_registry.rs` | Stable authoring component identities, lifecycle metadata, save policy, and inspector callbacks | extensibility.md, ADR 0034 | | `ui/asset_browser/` | Asset Browser tree, grid/list, details | roadmap Phase 4b | | `history/` | Undo/redo command stack | README controls | | `crates/scene` | Schema stamp/migrate/validate (shared) | ADR 0006, ADR 0008 | | `ext/extensibility.rs` | Command registry, `ActorInspectorSection`, palette | Phase 6 | | `operators.rs` / `operators/test_harness.rs` | Operator lifecycle/status bridge and reusable regression invariants | operator-regression-testing.md, BS-JD-502 | | `ext/game_inspector.rs` | Game-registered inspector sections | Phase 6 | ## Design intentions (stable) - **EditorOnly** helper entities never appear in hierarchy or saved scenes. Visualizer proxies are editor-only but selectable; selection resolves to their source entity. - **Jackdaw-inspired roadmap work** follows ADR 0020: use Jackdaw as design/API inspiration only unless a ticket explicitly marks code-derived work with source, license, and upstream commit notes. Clean-room implementation is preferred for geometry, terrain, operator, and extension systems. - **Dedicated egui `Camera2d`** at full window — never attach `PrimaryEguiContext` to a viewport-cropped 3D camera (NaN layout panic). - **Unified viewport** uses one render-to-texture target for both the editor fly camera and the possessed player camera so HDR/atmosphere is not broken by sub-viewport cropping. - **PIE:** F8 possess/eject while sim runs; **F6** pauses/resumes simulation in Play; project settings drive shared rendering for the active viewport camera. - **Asset browser** mirrors the on-disk `assets/` directory with project tree, breadcrumb, search/filter/sort, grid/list views, texture/model/material thumbnails, a details pane, and context-aware row/menu actions; narrow docks prioritize content, keep the root panel fixed, switch list view to a compact single-column layout, and hide tree/details panes when they would crowd the content area. The footer stays pinned while only the project tree, asset content, and details panels scroll. **Built-ins** holds spawnable primitives and lights. **Materials** folder scans `assets/materials/*.ron`, renders material thumbnails on a sphere using `MaterialDesc`, and exposes shader-schema-driven parameters/textures in the details editor; **Shaders** holds shader schema RON files. **Audio** accepts Bevy-supported Ogg/Vorbis and Speex (`.ogg`, `.oga`, `.spx`), WAV, MP3, and FLAC clips under `assets/audio/`, with a dedicated filter, waveform icon, format/file details, and stable registry-backed references that retain a runtime source path. glTF/GLB/FBX rows can expand into a shelf of normalized embedded mesh, material, and texture subassets with independent generated thumbnails. Mesh subassets can be selected, dragged into the viewport, or placed from details/context menus; material subassets render source-material spheres; texture subassets can be applied to the selected actor. Model import settings are staged with **Apply** / **Revert**, asset context menus can regenerate thumbnails, material asset details edit shared `MaterialAsset` fields, and file asset deletion moves sources/generated artifacts into `assets/.trash/`. Before thumbnail loading, glTF sources preflight local external buffers/images and show a stable non-retryable failure state when a dependency is missing instead of repeatedly invoking the asset loader. - **Static/skinned renderer split** — model drag/drop uses normalized artifacts under `assets/meshes/generated/`. Unrigged, non-animated sources create `ActorKind::StaticMesh + StaticMeshRenderer`; skin-bound or animated sources create `ActorKind::SkinnedMesh + SkinnedMeshRenderer` and preserve the imported hierarchy. Static slots never contain marked skinned primitives or geometry from animated sources. `SceneInstance` placement keeps `ImportedModel + ModelRef` for generic full-source scenes. See [ADR 0033](../adr/0033-dedicated-skinned-mesh-renderer.md). - **Animation authoring** — glTF/GLB imports generate UUID-keyed rig/clip manifests and expandable skeleton/clip shelves. Clip drag creates a skinned actor or adds one exact-signature-compatible state to a selected skinned actor through typed history. `AnimationControllerDesc` exposes named states, ranges, loop/speed, default/crossfade, and non-dirty runtime-backed preview; project validation resolves the same stable refs and blocks animated/skinned FBX with conversion guidance. Production acceptance completed in Gitea #46. See [animation-authoring.md](animation-authoring.md) and [ADR 0031](../adr/0031-animation-authoring-runtime-contract.md). - **Navigation authoring** — bounds, obstacles, areas, and links use typed history and viewport visualizers. Rerecast produces a versioned fingerprinted artifact; Polyanya powers both editor path preview and the game-owned runtime API. The existing horizontal toolbar path button creates or bakes bounds, while Scene > Navigation exposes the complete workflow. See [navigation-authoring.md](navigation-authoring.md) and [ADR 0032](../adr/0032-versioned-navigation-bake-and-runtime-query.md). - **Brush authoring** — `ActorKind::Brush + BrushDesc` stores persisted convex blockout faces, validates authored geometry in the inspector and Window → Brush Diagnostics, and hydrates active valid brushes into generated mesh children. See [brushes.md](brushes.md). - **Draw Brush** — `B`, toolbar pencil, or command `brush.draw` enters a floor-polygon draw mode. LMB places snapped points, Backspace removes the last point, Enter locks the outline for height editing, mouse up/down adjusts height, and Enter/LMB creates additive prism brushes through history. Esc/right-click cancels. Simple concave outlines decompose into convex brush parts; self-intersections remain blocked. - **Brush edit modes** — with a brush selected, `1`/`2`/`3`/`4` enter vertex, edge, face, and clip element modes. Element modes show brush handles in the viewport, own LMB picking, support Shift multi-select, show a mode badge, and Esc returns to object mode. Vertex/edge/face selections use the standard `W`/`E`/`R` gizmo at the element pivot and commit undoable `SetBrush` edits. Clip previews a bounds-based half-brush and commits with Enter; command-palette intersect, convex merge, and subtract operations use the same preview/commit lifecycle for conservative cuboid/prism blockout. - **Collider split** — imported mesh collision lives in a separate `ColliderDesc::StaticMesh` plus optional `RigidBodyDesc`; renderer slots own only render visibility, shadows, mesh, and material references. - **Material assets and renderer slots** — Material and direct-base Material Instance documents are shared assets. `StaticMeshRenderer` and `SkinnedMeshRenderer` each own stable material slots with imported source defaults and explicit shared assignments; Clear returns to the source default, while reimported missing slots retain overrides as orphans instead of matching by name. Runtime-only property blocks never mutate or persist into the shared asset. Custom Surface evaluators use the same constrained ABI for raster and Solari-eligible non-deformed geometry; skinned/morph geometry is deliberately excluded from Solari until deformed BLAS updates exist. See [material-system.md](material-system.md), [ADR 0035](../adr/0035-shared-material-assets-and-renderer-slots.md), and [ADR 0036](../adr/0036-surface-abi-and-solari-parity.md). - **Prefab authoring** — shared `PrefabOverrides` targets generated actors by nested anchor chain plus stable `ActorId`, and applies reflected property/component plus same-layer structural operations in editor and game hydration. The editor supports scoped Revert and transactional **Apply to source** with three-way conflict checks, exact-file undo guards, and recoverable changed/broken/conflict states. `HydratedPrefabMember` keeps generated content out of owner serialization; linked-root saves retain local structure as variants. **Unpack Layer** preserves nested links, while **Convert to Local** recursively removes them. See [prefab-authoring.md](prefab-authoring.md) and [ADR 0027](../adr/0027-stable-prefab-ownership-and-variants.md). - **Visual language** uses a near-black industrial shell, a compact Blacksite identity mark, restrained amber actions/primary selection, cyan secondary selection, semantic status colors, stable grouped controls, and shared elevated viewport chips. Primary/secondary selection roles remain consistent across hierarchy rows, viewport x-ray shells/corner brackets, the selection HUD, and transform interactions. See [visual-language.md](visual-language.md). - **Hierarchy** shows authored objects plus useful runtime context (`Player`, `PlayerCamera`, Project Sun). Ordinary runtime rows remain read-only; generated prefab rows expose override-aware inspection and same-layer remove/reparent actions while rejecting cross-instance/layer and composition-boundary drops. Locks prevent selection, gizmos, drag participation, structural targets, and mutating context actions. Authored reparenting preserves world placement and records parent/local-transform/manual-order changes as one undoable command. - **Player placement** is authored through `PlayerSpawn`; selecting the runtime player in Edit mode redirects to a saved `Player Start`. - **World lighting** has two layers: project default sun/ambient settings, and optional scene-authored directional `LightDesc` overrides. **Scene → Lighting** menu and **Rendering** panel (Window) restore project sun or bake a scene directional from project settings. **Apply** in Project Settings updates ambient and sun illuminance live. - **Rendering** — `GiMode` + post-process volumes; see [rendering.md](rendering.md). **Window → Rendering** shows requested/effective active-camera stack, fallback reason, Solari eligibility, viewport GI badge, and volume HUD. - **Inspector** shows a responsive header, **Transform**, registered authoring component cards, and an Add Component footer (`actor_inspector`) that expands an inline search shelf above the button; only the component body scrolls. Rows wrap or stack inside narrow docks instead of forcing the panel wider, and legacy authoring sections use the same component-card shell. Component card carets collapse/expand for the current editor session, status dots toggle persisted `AuthoringComponentStates`, and triple-dot menus provide registry-backed reset, copy/paste values, move, remove, and documentation slots. `InspectorOrder` controls presentation only. The Add Component shelf is registry-driven with persistent search, category groups, descriptions, hydration hints, duplicate/conflict disabled states, and recommendation hints. Static game/editor extensions register reflected lifecycle metadata and their inspector together; see [extensibility.md](extensibility.md) and [ADR 0034](../adr/0034-registry-driven-authoring-components.md). - **Command palette** (`Ctrl+P`): opens centered, clears and focuses the filter, selects the first result, searches both human-facing labels and stable command IDs, and supports arrow-key selection and Enter to run. Commands include `scene.reset_lighting`, `brush.draw`, `brush.subtract`, `brush.intersect`, `brush.merge_convex`, `rendering.create_volume`, `rendering.select_volumes_at_camera`, `rendering.focus_active_volumes`, `selection.group`, `selection.focus`, `selection.reset_transform`, and play commands. - **Editor input routing** gives egui text fields first claim on keyboard input. Viewport shortcut keys require viewport pointer focus and are suspended while RMB/MMB camera navigation is active. - **ActorKind** remains required as a saved compatibility/display hint, is repaired from primary components on load and component transactions, and does not prohibit compatible composition such as renderer plus light. Component validation owns requirements and geometry-source conflicts. - **Scene persistence and recovery** use transactional same-directory writes for authored scenes and bounded user-local recovery snapshots for dirty saved scenes. Recovery runs every 120 seconds by default, keeps five generations, never marks the scene clean, and appears as a status/File-menu restore or discard action when newer than the authored file. Restore leaves the original scene dirty until manually saved. See [ADR 0023](../adr/0023-transactional-scene-persistence-and-recovery.md). - **Scene visualizers** expose actor root icons, colliders, lights, player spawns, gameplay markers, volumes, prefab/model anchors, Project Sun, and runtime player/camera markers without changing saved scene data. Spot lights show inner/outer cones and cameras show near/far frusta. Viewport options independently gate visualizer categories and include actor icon and transform-gizmo size sliders. - **Clean game-view overlay** (`G`) hides editor chrome, grid, selection outlines, transform gizmos, actor root icons, visualizers, and selectable proxies without changing camera ownership; `Ctrl+G` toggles grid. - **Viewport shading** (toolbar): **Lit** (default WYSIWYG), **Unlit** (base-color debug), **Colliders** (hide meshes, emphasize collider gizmos). The viewport combines active shading/render path in one bottom-right chip, draws a camera-relative X/Y/Z orientation widget, identifies the primary selection in a responsive top-right HUD, and previews asset placement with a pointer card, placement reticle, corner brackets, and highlighted drop boundary. - **Hierarchy** sort modes (**Manual**, **Name**, **Type**) use stable tie-breakers so duplicate names (e.g. several `Pillar` rows) do not reorder on every click. Actor drags use the full remaining row width as an attach target, show a pointer-following action card, preserve world transforms, reject cycles, keep selected subtrees intact, auto-expand the new parent, and commit one undoable hierarchy command. **Manual** mode additionally exposes between-row reorder targets and the drag-only **Scene Root** unparent target. - **Viewport picking**: click selects nearest object, generated mesh child resolved to its authored actor, actor root icon, or visualizer hit, with actor icons preferred when clicked over meshes; **Tab** cycles overlapping targets at the last click. The selection HUD reports the current overlapping-pick position, and additive selections use an amber primary plus cyan secondary treatment. All unlocked selected actors participate in the grouped transform gizmo and one undoable transform command. - **Settings data** lives in `crates/settings`; **settings UI** lives in `settings_ui.rs`. When implementing or changing any of the above, update this file and the root README in the same change.