Blacksite/docs/editor/README.md

27 KiB

Editor Framework Documentation

Docs for the in-process egui editor (crates/editor/). Update this index when adding editor subsystems.

Documents

Document Contents
roadmap.md Phased editor work and status
architecture.md Plugins, cameras, PIE, settings split
brp.md Remote protocol, authoring-only policy, commands
debt-audit.md Zero-debt phase gates and remaining items
rendering.md GI modes, post-process volumes, presets, post FX assets
brushes.md Brush authoring schema, hydration behavior, and MVP limits
operator-regression-testing.md Shared modal-tool commit/cancel/dirty/helper/undo invariants
session-recovery.md Versioned restart state, clean/crash behavior, and privacy boundary
project-launcher.md Pre-engine project selection, manifest identity, recents, and sandbox contract
build-and-package.md Non-blocking editor builds, headless profiles, runtime output, and metadata
multi-scene-composition.md Scene tabs, stable subscene references, ownership, validation, and recovery
prefab-authoring.md Stable nested overrides, source Apply/conflicts, variants, unpacking, and local conversion
audio-authoring.md Audio clip placement, source/listener controls, audition, buses, runtime parity, and validation
animation-authoring.md glTF rig/clip import, stable controller states, preview, runtime API, and validation
navigation-authoring.md Bounds, source geometry, deterministic bake, viewport path preview, and runtime query workflow
extensibility.md Static authoring component lifecycle registration, stable IDs, composition, and generic history
material-system.md Shared Material/Material Instance assets, static/skinned renderer slots, Surface ABI, Solari scope, and migration
collaborative-file-safety.md Exact authored-file revisions, Git/read-only status, conflict recovery, and optional ownership providers
native-dialogs.md Non-blocking file/folder/confirmation acquisition and main-thread result application
terrain.md Inline height-grid terrain, chunk hydration, collision, inspector workflow, and fixtures
physics-placement.md Transactional gravity placement, prerequisites, isolation, commit/cancel, and undo
collider-authoring.md Collider shape editing, shared health diagnostics, overlays, hydration status, and placement reuse
sample-regression-pack.md Five-area sample manifest, native workflow, visual composition, validation, and maintenance contract
evaluations/ Acceptance evidence records and native Gitea attachment publishing policy
evaluations/material-renderer-foundation/ Live screenshots and verification record for the renderer/material/component foundation
evaluations/material-library-targeted-drop/ Live screenshot and verification record for the docked Material Library and exact reversible surface drops
evaluations/collaborative-file-safety/ Live screenshot and verification record for source-control status and guarded external-change recovery
evaluations/native-dialog-responsiveness/ Live native-Wayland screenshot and verification record for non-blocking picker responsiveness
evaluations/terrain-foundation/ Live screenshot and verification record for height-grid terrain schema and chunk hydration
evaluations/terrain-sculpt-tools/ Live screenshot and verification record for modal sculpt controls, footprint, and stroke history
evaluations/terrain-material-layers/ Live screenshot and verification record for blended layers, assignment, painting, and history
evaluations/physics-placement/ Live screenshot and verification record for multi-prop settling, cancel, commit, undo, and redo
evaluations/collider-diagnostics/ Live screenshot and verification record for semantic collider overlays, health linking, shape switching, and placement reuse
evaluations/navigation-authoring/ Live screenshots and verification record for navigation authoring and runtime parity
evaluations/operator-invariants/ Source acceptance record for production operator lifecycle, rollback, cleanup, and undo/redo invariants
evaluations/sample-regression-pack/ Exact-implementation source and native acceptance evidence for the five-area editor regression pack
evaluations/guarded-shutdown-savepoints/ Source and native acceptance evidence for guarded editor exit and per-document clean checkpoints
evaluations/scoped-ui-actions/ Exact-implementation source and native acceptance evidence for actions invoked during scoped egui rendering
evaluations/deterministic-asset-fingerprints/ Source, fresh-checkout, hash-stability, and native acceptance evidence for imported-source fingerprints
evaluations/production-readiness/ Current #50 release-candidate matrix and required clean-checkout, soak, performance, limitation, and independent-signoff evidence

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
shared::components::TerrainDesc / shared::hydration::terrain / blacksite_surface Persisted height/layer grids, generated chunks, and raster blending terrain.md, ADR 0039, ADR 0040
viewport/physics_placement.rs / play/state.rs Paused Edit physics and transactional gravity placement physics-placement.md, ADR 0041
viewport/collider_diagnostics.rs / viewport/visualizers.rs / ui/inspector.rs Shared collider health, semantic overlays, and undoable shape authoring collider-authoring.md
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 / ui/material_library.rs / viewport/material_drop.rs / shared::renderer_material Shared material discovery, docked catalog/usage UI, exact reversible surface drops, 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/fingerprint.rs / shared::AssetSourceFingerprint Content-addressed imported-source identity and byte-preserving registry/manifest publication ADR 0043, evaluations/deterministic-asset-fingerprints/
assets/ Catalog, transactional import bundles, asset DB, static mesh artifacts, thumbnails/, materials.rs, prefab overrides v2 this file (below), prefab-authoring.md, ADR 0017, ADR 0027, ADR 0044
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/collaboration.rs Guarded authored writes, asynchronous Git status, and optional ownership providers collaborative-file-safety.md, ADR 0037
project/native_dialog.rs One-at-a-time native dialog worker and one-shot main-thread completions native-dialogs.md, ADR 0038
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
project/samples.rs / scene::sample_pack / xtask/src/validate_samples.rs Cached editor sample catalog, canonical pack contract, and deterministic headless release gate sample-regression-pack.md, ADR 0028
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. FBX source-material previews use the same sandboxed resolver as import and validation, expose one cached hover-visible dependency failure, and never enqueue known-missing texture paths; neutral model/mesh previews remain available. Asset details mark present/missing dependencies and identify missing textures intentionally ignored by Authoring Override. FBX bundle import preserves referenced sibling or .fbm/ layout transactionally. See ADR 0044.
  • Imported-source fingerprints use exact byte length plus lowercase BLAKE3 for model, texture, and audio registry records and for generated static-mesh/animation manifests. Filesystem timestamps are scan hints only; equivalent refresh preserves the exact committed RON bytes and registry publication order is normalized by project path. See ADR 0043 and the acceptance record.
  • Material Library is a dockable bottom-panel catalog for cross-folder Material and direct-base Material Instance authoring. It provides search, type and scene-usage filters, grid/list thumbnails, dependency health, usage counts, creation, guarded details editing, and first-class drag sources. Viewport drops resolve an exact renderer slot, primitive, or brush face under the pointer, preview transiently, reject incompatible/read-only targets explicitly, restore on target change/cancel, and commit one typed undo step on release.
  • 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.
  • 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 and ADR 0031.
  • 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 and ADR 0032.
  • Brush authoringActorKind::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.
  • Draw BrushB, 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 and health — imported mesh collision lives in a separate ColliderDesc::StaticMesh plus optional RigidBodyDesc; renderer slots own only render visibility, shadows, mesh, and material references. Inspector, viewport, Diagnostics, and physics placement share one authored/runtime health result; see collider-authoring.md.
  • 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. The property-block schema is runtime-only and persistence-excluded, while renderer application/promotion remains #53. 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 #54 adds deformed BLAS updates. See material-system.md, ADR 0035, and ADR 0036.
  • 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 and ADR 0027.
  • 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.
  • 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.
  • RenderingGiMode + post-process volumes; see 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 and ADR 0034.
  • 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.
  • Guarded shutdown and clean savepoints route native close, File > Quit, project switching, and programmatic exit through one non-blocking Save All / Discard / Cancel coordinator. Each tab's dirty marker is reconciled against its canonical last-loaded-or-saved authored projection after undo/redo. See ADR 0042.
  • Collaborative file safety records exact content revisions for loaded scenes, prefab source operations, editable materials, and Project Settings, then rechecks them immediately before atomic publication. External changes, create races, read-only files, and optional ownership locks keep the existing bytes intact and open Reload/Compare Metadata/Save As/Cancel recovery. Git status is asynchronous, observational, and absent without noise outside a repository. See collaborative-file-safety.md and ADR 0037.
  • 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.