334 lines
24 KiB
Markdown
334 lines
24 KiB
Markdown
# Bevy FPS Foundation
|
||
|
||
A modular first-person game foundation and in-process editor built on **Bevy 0.18** and
|
||
**Avian 0.6** physics.
|
||
|
||
The runtime game provides a high-fidelity PBR stack (HDR, procedural atmosphere + image-based
|
||
lighting, cascaded shadows, SSAO, TAA, bloom, fog, ACES tonemapping) plus Hybrid Auto Solari
|
||
raytraced indirect lighting where supported, and local input/presentation glue for a fixed-step
|
||
kinematic FPS simulation. The editor provides dockable egui panels, a
|
||
filtered scene hierarchy, click selection, transform gizmos, undo/redo, asset import/placement,
|
||
native Bevy scene save/load, and BRP support for external tooling.
|
||
|
||
## Requirements
|
||
|
||
- Rust (stable; pinned via `rust-toolchain.toml`)
|
||
- Git LFS for binary game/source assets: run `git lfs install` once, then `git lfs pull` after clone.
|
||
- A Vulkan-capable GPU + drivers (developed against an NVIDIA RTX 3080 Ti)
|
||
- Linux build deps for `winit`/`wgpu` (ALSA, udev, etc.) if not already present
|
||
|
||
## Running
|
||
|
||
```bash
|
||
# Check everything
|
||
cargo fmt --check
|
||
cargo check --workspace
|
||
cargo clippy --workspace
|
||
cargo clippy -p game -p shared -p protocol -p sim -- -D warnings
|
||
cargo test -p game --lib
|
||
cargo test -p sim
|
||
|
||
# Runtime game
|
||
cargo run -p game
|
||
cargo run -p game --features dev
|
||
|
||
# In-engine editor
|
||
cargo run -p editor
|
||
cargo run -p editor --features dev
|
||
```
|
||
|
||
### Hot reload (gameplay iteration)
|
||
|
||
`--features dev` turns on Bevy **dynamic linking** for faster rebuilds (recommended day-to-day).
|
||
|
||
Add `--features hot-reload` for **in-process hot reload** of [`game_hot`](crates/game_hot) (sim movement, player input/camera, world bootstrap). The editor process stays open; only gameplay system bodies swap when the dylib rebuilds.
|
||
|
||
**Two-terminal workflow (hot reload):**
|
||
|
||
```bash
|
||
# Terminal 1 — rebuild the hot dylib on save
|
||
cargo watch -w crates/game_hot -w crates/sim -x "build -p game_hot --features dylib"
|
||
|
||
# Terminal 2 — run the editor once
|
||
cargo run -p editor --features dev,hot-reload
|
||
```
|
||
|
||
Or use the VS Code task **watch game_hot (hot reload)** alongside **run editor (dev fast-link)** (enable the `hot-reload` feature on the editor run task when using dylib iteration).
|
||
|
||
| Input | Action |
|
||
|-------|--------|
|
||
| Save `game_hot` / `sim` gameplay code | Dylib rebuilds; status bar shows **building…** then **reloaded** |
|
||
| **Ctrl+Shift+R** | Manual refresh (`on_hot_reload` bootstrap: camera FX, ambient light) |
|
||
|
||
**Safe to hot reload:** system logic, movement tuning in code, input mapping.
|
||
|
||
**Requires full editor restart:** new/changed component fields, new components, plugin schedule changes, editor UI code.
|
||
|
||
> Note: the workspace uses the `mold` linker via `clang` (see `.cargo/config.toml`) for fast link times.
|
||
|
||
### Target Cache Cleanup
|
||
|
||
Cargo/Bevy debug artifacts can grow quickly. Use the workspace cleanup task before reaching for a full `cargo clean`:
|
||
|
||
| Command | Effect |
|
||
|---------|--------|
|
||
| `cargo clean-target` | Dry run: prints reclaimable `target/` cache. |
|
||
| `cargo clean-target --apply` | Safe cleanup: removes incremental and rust-analyzer flycheck cache. |
|
||
| `cargo clean-target --include-artifacts --days 3 --apply` | Deeper cleanup: also removes stale hashed `deps`, `build`, `.fingerprint`, and example artifacts older than 3 days. Cargo will rebuild anything still needed. |
|
||
|
||
VS Code tasks: **target cleanup (dry run)** and **target cleanup (safe apply)**.
|
||
|
||
### Launch Troubleshooting
|
||
|
||
- The native game/editor windows force an opaque Wayland surface and opaque camera clears to avoid compositor alpha issues on mixed HDR/SDR desktops.
|
||
- If the window maps but appears transparent on Hyprland or another Wayland compositor, launch with `BEVY_FPS_HDR=0` to force the SDR camera path while debugging monitor/compositor behavior.
|
||
- The workspace patches `bevy_render` locally so transient Linux swapchain acquire timeouts skip one frame instead of panicking in `prepare_windows`.
|
||
- Debug launch configs and run tasks set `WGPU_VALIDATION=0` to quiet the known wgpu/Vulkan validation-layer warning `VUID-StandaloneSpirv-MemorySemantics-10871`. This only disables the Vulkan validation layer for those launches; Rust panics and application errors still surface normally.
|
||
- If **CodeLLDB / mold** fails with hundreds of `undefined symbol` linker errors, the incremental `target/` cache is stale. Run the VS Code task **clean build editor (dev)** or `cargo clean -p editor && cargo build -p editor --features dev`, then launch **Debug editor** again. Use `cargo run -p editor --features dev` from the terminal if you need `libbevy_dylib` on `LD_LIBRARY_PATH` automatically.
|
||
|
||
## Editor Controls
|
||
|
||
| Input | Action |
|
||
|-------|--------|
|
||
| `F5` | Toggle Edit / Play in the same viewport |
|
||
| `F6` | While playing: pause / resume simulation (stay in Play mode) |
|
||
| `F8` | While playing: possess player / eject to editor camera |
|
||
| `G` | Toggle clean game-view overlay (hide editor widgets/proxies/gizmos) |
|
||
| `Ctrl+G` | Toggle viewport grid |
|
||
| `F` | Focus editor camera on selection |
|
||
| `Ctrl+Shift+1` / `Ctrl+Shift+2` | Save / recall viewport camera bookmark |
|
||
| RMB + mouse | Editor camera look; cursor hides while held |
|
||
| RMB + `W` `A` `S` `D` | Editor camera fly |
|
||
| RMB + `Q` / `E` | Editor camera down / up |
|
||
| Mouse wheel | Dolly editor camera |
|
||
| MMB + mouse | Pan editor camera |
|
||
| Click authored object, actor root icon, or visualizer in viewport | Select source entity |
|
||
| Click empty viewport / `Esc` | Deselect |
|
||
| `Delete` / `Backspace` | Delete selection |
|
||
| `Ctrl+D` | Duplicate selection |
|
||
| `Ctrl+Z` / `Ctrl+Shift+Z` / `Ctrl+Y` | Undo / redo |
|
||
| `F2` in Hierarchy | Rename selection |
|
||
| `W` / `E` / `R` | Translate / rotate / scale gizmo |
|
||
| `X` | Toggle world/local gizmo orientation |
|
||
| `B` | Enter Draw Brush mode |
|
||
| Draw Brush: LMB / `Enter` / `Esc` / `Backspace` | Place floor points / create brush / cancel / remove last point |
|
||
| Brush selected: `1` / `2` / `3` / `4` | Vertex / edge / face / clip edit modes |
|
||
| Brush edit mode: LMB / `Shift+LMB` / `Esc` | Select element / toggle element selection / return to object mode |
|
||
| Viewport toolbar (sun / brush / box icons) | Shading: Lit, Unlit (albedo), Colliders (mesh off) |
|
||
| Viewport eye/options | Toggle actor root icon categories, adjust icon/gizmo size, and control colliders, lights, spawns, prefab/model anchors, and runtime player/camera visualizers |
|
||
| `Tab` in viewport | Cycle selection through overlapping objects at last click |
|
||
| Click Player visualizer in Edit mode | Select or create the authored `PlayerSpawn` (`Player Start`) |
|
||
| Select Project Sun | Inspect project default lighting; create a scene sun override |
|
||
| Asset Browser project/file views | Browse `assets/`, search/filter/sort, switch grid/list, expand model subassets with generated thumbnails, inspect staged import/material settings, drag assets/submeshes into the viewport |
|
||
| Asset Browser context/details actions | Apply textures/materials, regenerate thumbnails, reimport models, place assets/submeshes, or move file assets to `assets/.trash/` |
|
||
| `Ctrl+P` | Command palette; type to filter, use arrow keys to select, Enter to run (`scene.reset_lighting`, `selection.group`, `selection.focus`, `selection.reset_transform`, play commands) |
|
||
| `F7` | While paused in Play: advance one sim tick |
|
||
| Shift/Ctrl + click (Hierarchy) | Additive selection |
|
||
| Hierarchy context | Reparent to other selection / Unparent |
|
||
| File menu | New, Open, Save, Save As, Import Assets, Export Selection, Save Selection As Prefab, Recent Scenes |
|
||
| Inspector component card | Collapse with caret, toggle active with status dot, or use triple-dot menu for reset/copy/paste/move/remove actions |
|
||
| Inspector footer → Add Component | Expands an inline search shelf for registered authoring, rendering, physics, gameplay, and volume components with descriptions, availability hints, and undo |
|
||
| Edit → Project Settings… | Edit `assets/project.ron` (rendering, physics, input) |
|
||
|
||
Viewport shortcut keys require the pointer to be in the viewport and are suspended while typing in egui text fields or actively using camera navigation. `Delete`, `Backspace`, duplicate, and undo/redo also defer to text-field focus.
|
||
|
||
### Play Mode
|
||
|
||
- Press **F5** (or Play menu) to run the **real game** in-process: same `GamePlugin`, player,
|
||
fixed-step `sim`, and rendering stack as the standalone `game` binary.
|
||
- The unified **Viewport** stays in place on play enter. The editor fly camera and player camera
|
||
render to the same offscreen HDR texture depending on Edit/Play possession state.
|
||
- While editing, gameplay simulation and input are disabled (`SimEnabled` / `GameInputEnabled`).
|
||
Entering Play enables simulation; **F6** pauses/resumes the sim without leaving Play; **F8** toggles **possess** (player input + camera) vs **eject**
|
||
(editor fly camera while sim keeps running).
|
||
- Transport controls (Play, Pause, Stop, Eject) live on the **main toolbar** below the menu bar.
|
||
- The viewport uses the full project rendering stack from **`assets/project.ron`**
|
||
(Edit → Project Settings…). Only one 3D camera carries that stack at a
|
||
time (editor fly cam while editing/ejected, player cam while possessed) so GPU bind limits are
|
||
respected.
|
||
- Add a `PlayerSpawn` marker component (via Inspector) on a level object to choose where Play
|
||
starts; otherwise the default game spawn `(0, 1.5, 10)` is used.
|
||
- Actor root icons draw over scene meshes, stay screen-sized while zooming, and are prioritized when clicked.
|
||
- Clean game-view overlay (`G`) hides editor widgets, actor root icons, visualizers, selectable proxies, gizmos,
|
||
selection outlines, and grid without changing the active camera.
|
||
- **F5** stops Play and restores **player sim state** only; authored scene edits made during PIE
|
||
are kept. **Esc** frees the cursor mid-play.
|
||
|
||
## Game Controls
|
||
|
||
| Input | Action |
|
||
|-------|--------|
|
||
| `W` `A` `S` `D` | Move |
|
||
| Mouse | Look |
|
||
| `Space` | Jump (coyote-time + buffered) |
|
||
| `Left Shift` | Sprint |
|
||
| `Left Ctrl` | Crouch |
|
||
| `Esc` | Release / re-grab mouse cursor |
|
||
|
||
## Scene Workflow
|
||
|
||
- Levels are saved as native Bevy dynamic scenes under `assets/levels/`.
|
||
- Editable entities use reflectable authoring components from `crates/shared`.
|
||
- The editable player start is an authored `PlayerSpawn`; moving it with the transform gizmo changes
|
||
where Play mode boots the runtime player.
|
||
- Project settings provide default ambient/sun lighting. A scene-authored directional `LightDesc`
|
||
acts as a per-scene sun override and disables the project sun contribution.
|
||
- Hydration systems turn authoring data into runtime meshes, GLTF scenes, materials, lights, and
|
||
Avian colliders. Persisted `ActorId` / `ComponentInstanceId` values are stable; raw Bevy `Entity`
|
||
IDs are runtime-only.
|
||
- Inspector component active toggles are saved in `InspectorOrder`. Inactive authoring components
|
||
keep their data but do not hydrate runtime meshes, lights, physics, or post-process effects.
|
||
- Dragging glTF/GLB/FBX assets creates `StaticMeshRenderer` actors by default from normalized
|
||
artifacts in `assets/meshes/generated/`. Renderer slots reference imported content-browser mesh
|
||
and material assets, while generated collision is stored separately in `ColliderDesc` plus
|
||
`RigidBodyDesc`. Switch a model asset's placement mode to **Scene Instance** in Asset Browser
|
||
details when you need full `SceneRoot` loading for animation/skinning/scene data. Expanding a
|
||
model in the Asset Browser exposes normalized mesh/material/texture subassets; dragging a mesh
|
||
subasset places that part through the same static mesh renderer path.
|
||
- Brush actors are persisted as `ActorKind::Brush + BrushDesc`; the MVP hydrates additive convex
|
||
cube brushes into generated preview meshes while face/edge/CSG editing remains roadmap work.
|
||
- Draw Brush mode (`B` or toolbar pencil) places snapped floor points and commits an additive
|
||
prism brush with `Enter`; `Esc` or right-click cancels without changing the scene.
|
||
- Runtime-only handles/colliders are not serialized directly, keeping scenes stable and portable.
|
||
- Editor-only cameras and helper roots are filtered from selection, hierarchy, and scene save.
|
||
- **PIE restores player sim only** (transform, velocity, jump state) when you stop Play; authored
|
||
`LevelObject` edits made during PIE **remain** in the scene (the level may show as dirty).
|
||
- Play mode swaps the unified viewport between the player camera (possessed) and editor fly camera
|
||
(ejected).
|
||
- Gameplay movement runs in a fixed timestep in `crates/sim`. Raw keyboard/mouse input is translated
|
||
by `crates/game` into `protocol::PlayerInputIntent` before it mutates simulation state.
|
||
|
||
## Troubleshooting
|
||
|
||
### Viewport is black or wireframe-only
|
||
|
||
1. Check the **mode badge** (bottom-right of the viewport). **Collider** hides meshes — click the **sun** toolbar icon for **Lit** shading.
|
||
2. **Window → Rendering → Active Camera**: check **Runtime lights** (directional/point/spot counts), scene vs project sun status, and contributing post-process volumes. Scene directionals override the project sun; use **Scene → Lighting → Use project sun** to restore project defaults.
|
||
3. **Solari requested but not visually changing**: check **Window → Rendering → Active Camera** for requested/effective GI, fallback reason, tagged meshes, Solari-compatible mesh assets, render instances, bind-group readiness, and compatible lights. Effective Solari forces an HDR camera target because Bevy Solari writes through a storage texture; imported/custom meshes need TriangleList geometry, POSITION/NORMAL/UV_0/TANGENT attributes, and U32 indices for Bevy 0.18 Solari.
|
||
4. **Lighting changes do nothing in Solari**: Bevy 0.18 Solari samples directional lights and emissive meshes, not point/spot lights. Use Directional lights or emissive materials in Solari; switch to Forward PBR for point/spot light authoring.
|
||
5. **GiMode Auto shows Forward**: Solari RT wgpu features are unavailable on this GPU. Dev RT override: `BEVY_FPS_FORCE_SOLARI=1`.
|
||
6. **Volume overrides ignored**: confirm camera is inside volume AABB; check priority in Rendering → Volumes tab.
|
||
7. **Custom post FX**: RON under `assets/post_fx/`; assign path in volume inspector (see [docs/editor/rendering.md](docs/editor/rendering.md)).
|
||
8. Scene **Open** / **Recent** runs hydration immediately; **zero runtime lights** after load usually means missing `LightDesc` on light actors (see Rendering panel).
|
||
|
||
### Hierarchy sort jumps when clicking
|
||
|
||
**Sort: Name** / **Type** now use stable tie-breakers (duplicate names like several `Pillar` rows stay put). Use **Sort: Manual** and drag-and-drop for explicit sibling order.
|
||
|
||
### Hierarchy scrolls during drag
|
||
|
||
Scroll-to-drag is disabled while dragging actors. Release the mouse to finish or cancel the drag.
|
||
|
||
## Cursor / VSCode Setup
|
||
|
||
The `.vscode/` folder is preconfigured:
|
||
|
||
- `extensions.json` recommends rust-analyzer, Even Better TOML, CodeLLDB, crates, and Error Lens.
|
||
- `settings.json` runs `clippy` on save, enables proc-macro/build-script support, formats on save,
|
||
and excludes `target/` from search/watch.
|
||
- `tasks.json` provides workspace check/clippy plus game/editor build/run tasks.
|
||
- `launch.json` provides CodeLLDB launch configs for the editor and game.
|
||
- `.github/workflows/ci.yml` mirrors local formatting, check, clippy, test, and binary build verification.
|
||
|
||
## Architecture Decisions
|
||
|
||
- [Documentation index](docs/README.md)
|
||
- [Mission — editor framework & principles](docs/mission.md)
|
||
- [Editor framework docs](docs/editor/README.md)
|
||
- [ADR 0001: Roadmap Architecture](docs/adr/0001-roadmap-architecture.md)
|
||
- [ADR 0002: Bevy Version And Migration Policy](docs/adr/0002-bevy-version-and-migration-policy.md)
|
||
- [ADR 0003: Editor Framework Mission](docs/adr/0003-editor-framework-mission.md)
|
||
- [ADR 0014: Unified Viewport Model](docs/adr/0014-unified-viewport-model.md)
|
||
- [ADR 0016: Unified Rendering Contract](docs/adr/0016-unified-rendering-contract.md)
|
||
- [ADR 0017: Normalized Static Mesh Assets](docs/adr/0017-normalized-static-mesh-assets.md)
|
||
|
||
## Project Layout
|
||
|
||
```
|
||
crates/
|
||
protocol/ Shared tick, input intent, command, and message/event protocol types
|
||
sim/ Fixed-step gameplay simulation and determinism test scaffolding
|
||
shared/ Reflectable authoring components + hydration systems
|
||
game/ Runtime FPS game library + standalone game binary
|
||
editor/ In-process egui editor binary
|
||
```
|
||
|
||
## Implementation Checklist
|
||
|
||
- [x] Workspace: `game`, `shared`, `editor`, `protocol`, `sim`
|
||
- [x] Shared authoring components + hydration
|
||
- [x] Protocol tick, input intent, command, and basic message/event types
|
||
- [x] Fixed-step deterministic sim crate for player movement/controller state
|
||
- [x] Runtime game refactored into `GamePlugin`
|
||
- [x] Raw game input translated into protocol intent before simulation
|
||
- [x] Docked egui editor scaffold
|
||
- [x] Editor fly camera
|
||
- [x] Mesh picking selection + highlights
|
||
- [x] Transform gizmos
|
||
- [x] Editor-side scene visualizers for colliders, lights, player spawns, prefab/model anchors, and runtime player/cameras
|
||
- [x] Selectable, screen-sized actor root icons in the 3D viewport with per-category visibility controls
|
||
- [x] Filtered hierarchy, inspector, viewport, toolbar, asset browser, and status panels
|
||
- [x] Delete, duplicate, rename, and structural/material undo-redo
|
||
- [x] Native Bevy scene New/Open/Save/Save As with dirty title tracking
|
||
- [x] Asset import, static mesh/prefab placement, texture assignment, and selection export
|
||
- [x] PIE player-only snapshot/restore (authored `LevelObject` edits persist on stop)
|
||
- [x] Unified viewport render-to-texture target + Play session bootstrap
|
||
- [x] `PlayerSpawn` authoring marker for editor Play start location
|
||
- [x] BRP enabled in the editor
|
||
- [x] Cursor/VSCode workspace tasks + launch configs
|
||
- [x] Opaque Wayland window launch defaults + SDR/HDR runtime toggle
|
||
- [x] CI workflow for format, check, clippy, tests, and binary builds
|
||
- [x] ADRs for roadmap architecture and Bevy migration policy
|
||
- [x] Determinism harness: same inputs over same ticks produce the same state summary/hash
|
||
- [x] Verify: `cargo fmt --check` / `cargo check --workspace` / `cargo clippy --workspace` / strict foundation clippy / `cargo test -p sim`
|
||
- [x] Stable asset registry with UUIDs + import settings in asset browser details
|
||
- [x] Asset Browser expandable model subasset shelves, independent mesh/material/texture thumbnails, staged import/material details with shader-schema parameters, context actions, and trash-first file removal
|
||
- [x] Prefab instances (`PrefabInstance`) + save-as-prefab + unpack
|
||
- [x] Unsaved-scene confirm on New/Open/Recent
|
||
- [x] Hierarchy multi-select, reparent undo, multi-entity gizmo transform
|
||
- [x] Typed inspector undo (light, rigid body, collider, primitive, material, static mesh renderer) + registry-driven Add Component footer
|
||
- [x] Gameplay authoring markers + visualizers (`WeaponSpawn`, `TriggerVolume`, etc.)
|
||
- [x] Command palette execution; PIE sim step (F7); `xtask validate-levels`
|
||
- [x] ADRs 0005–0012 (prefab/registry, scene schema, EditorPlugin, editor structure, authoring/hydration, ActorKind, sun policy, zero-debt)
|
||
- [x] `ActorInspectorSection` registry + game demo section (`game::editor_ext`)
|
||
- [x] Command palette: reset lighting, group selection, focus selection
|
||
- [x] CI: `cargo test -p shared`, scene authoring-only check on repo level, `cargo check -p editor --features dev`
|
||
- [x] `scene` crate schema stamp/migrate/validate on save/load + CI `validate-levels`
|
||
- [x] Project Settings draft + Apply (HDR/swapchain safe); File → Project New/Open
|
||
- [x] Editor lib/bin split + `EditorPluginGroup`; game EditorPlugin dogfood panel
|
||
- [x] FBX/glTF model import + normalized `StaticMeshRenderer` placement; explicit scene-instance load via `bevy_ufbx` / `ModelRef`
|
||
- [x] Asset browser model thumbnails (unified `assets/thumbnails/` pipeline; `ThumbnailState` cache; FBX via `FbxThumbnailSource`)
|
||
- [x] Material assets (`assets/materials/*.ron`, inspector picker, drag-drop to selection)
|
||
- [x] Prefab instance overrides v2 (transform/material/child visibility apply-revert groups)
|
||
- [x] Advanced rendering: `GiMode`, post-process volumes, Rendering panel, requested/effective render stack, Solari integration, emissive materials, post FX assets ([ADR 0013](docs/adr/0013-rendering-tiers-and-post-process-volumes.md), [ADR 0016](docs/adr/0016-unified-rendering-contract.md), [rendering guide](docs/editor/rendering.md))
|
||
- [x] Static mesh renderer component, generated normalized mesh artifacts, source/one-actor hierarchy placement, and inspector renderer slots ([ADR 0017](docs/adr/0017-normalized-static-mesh-assets.md))
|
||
- [x] Componentized actor inspector, unified component cards, thumbnail static mesh slots, imported asset Browse/Locate/Clear refs with inherited source defaults, collider split, shader-aware actor material data, and texture picker/drop refs ([ADR 0018](docs/adr/0018-componentized-actor-inspector-and-materials.md))
|
||
- [x] Brush authoring schema MVP with `ActorKind::Brush`, cube `BrushDesc`, generated mesh hydration, scene migration, and inspector Add Component support ([ADR 0021](docs/adr/0021-brush-authoring-schema.md))
|
||
|
||
## Notes / Future Work
|
||
|
||
- Crouch lowers the camera and movement speed; the collider stays full-height for stability.
|
||
- The editor asset browser is filesystem-backed with folder/tree navigation, grid/list views,
|
||
texture and model thumbnails (glTF albedo fast-path; offscreen render studio for FBX and
|
||
untextured models), material sphere thumbnails, search/filter/sort controls, expandable model
|
||
subasset shelves, and a staged details pane. **File → Import Assets**
|
||
accepts glTF/GLB and **FBX** (binary; copies sibling `.fbm` texture folders when present).
|
||
Model assets generate normalized static mesh manifests under `assets/meshes/generated/`; drag/drop
|
||
uses `StaticMeshRenderer` by default with imported asset refs and optional separate static mesh
|
||
collider components. Expanded mesh subassets generate independent thumbnails and can be placed independently. Asset details can switch
|
||
placement to **Scene Instance** for `ModelRef`/`SceneRoot` playback, shared material assets can be
|
||
edited from the browser, and delete actions move files to `assets/.trash/`. Skeletal animation
|
||
playback is not supported by the static mesh path yet.
|
||
- Prefab instances use stable asset IDs (`PrefabInstance` + registry) with serialized `PrefabOverrides` (transform, material, per-child visibility by name). Inspector **Apply/Revert** per field group; **Unpack** removes the instance link.
|
||
- Material assets are RON files under `assets/materials/`; shader schemas live under `assets/shaders/`. `MaterialDesc` stores shader kind, typed parameters, texture bindings, and StandardMaterial fields. The Asset Browser material details editor can apply shader schemas, edit typed parameters/textures, and regenerate sphere thumbnails. Actor inspector material edits live on the actor `MaterialDesc`; static mesh source-material refs remain imported defaults and shared material assets are edited from the Asset Browser.
|
||
- Per-field reflect undo for all components remains future work; typed `shared` inspectors cover the common authoring path.
|
||
- The authoring/hydration layer is intentionally small so richer asset workflows (terrain,
|
||
material graphs, lighting profiles) can be added without changing the scene format foundation.
|
||
- The M2 sim split keeps camera pitch as local presentation state; body yaw and movement are
|
||
fixed-step intent consumers. M3 should map the existing protocol envelopes onto Lightyear and add
|
||
server-authoritative snapshots/prediction rather than broadening the local input path ad hoc.
|
||
- The editor renders egui on a dedicated full-window `Camera2d` (`PrimaryEguiContext`,
|
||
`RenderLayers::none()`, `auto_create_primary_context = false`) so the 3D viewport camera can be
|
||
cropped to the viewport panel without cropping egui itself. Attaching egui to a viewport-cropped
|
||
3D camera makes `egui_dock` lay out into a NaN rect and panics in `advance_cursor_after_rect`.
|