From 9a67a25a15c3f6cbfde4e6afe5cb576797b75c9a Mon Sep 17 00:00:00 2001 From: Rbanh Date: Sun, 12 Jul 2026 23:01:02 -0400 Subject: [PATCH] Clarify renderer foundation follow-ups --- ...r_foundation_acceptance_2026-07-12.plan.md | 25 +++++++++++++++++++ README.md | 4 +-- ...ared-material-assets-and-renderer-slots.md | 4 ++- docs/editor/README.md | 2 +- .../material-renderer-foundation/README.md | 7 +++--- .../production-readiness/README.md | 8 +++--- docs/editor/material-system.md | 10 ++++++-- 7 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 .cursor/plans/renderer_foundation_acceptance_2026-07-12.plan.md diff --git a/.cursor/plans/renderer_foundation_acceptance_2026-07-12.plan.md b/.cursor/plans/renderer_foundation_acceptance_2026-07-12.plan.md new file mode 100644 index 0000000..2b22393 --- /dev/null +++ b/.cursor/plans/renderer_foundation_acceptance_2026-07-12.plan.md @@ -0,0 +1,25 @@ +# Renderer Foundation Acceptance Split - 2026-07-12 + +Issue: Gitea #51 (`BS-JD-207`) + +## Outcome + +Accept the shipped renderer/material/Surface foundation without claiming two independent future +systems. Preserve the existing safe raster/Forward behavior and track each remaining boundary with +its own implementation and acceptance contract. + +## Decisions + +- #51 owns stable static/skinned slots, shared Material/Instance assets, Surface ABI parity for + eligible geometry, transactional migration, and the honest exclusion of deformed Solari meshes. +- #53 owns actual runtime Material Property Block application and promote-to-instance UX. The + existing component schema/persistence exclusion is not represented as runtime completion. +- #54 owns dynamic post-morph/post-skin buffers and instance BLAS updates. It is a documented P2 + Solari enhancement, not a raster/Forward production blocker. + +## Work + +- [x] Audit #51 scope and repository evidence against current runtime behavior. +- [x] Create focused Gitea follow-ups with independent acceptance criteria. +- [x] Correct ADR, material guide, README checklist, evaluation, and production matrix claims. +- [x] Run documentation/diff gates, commit, push, and close #51 with exact follow-up links. diff --git a/README.md b/README.md index e864106..2b72765 100644 --- a/README.md +++ b/README.md @@ -447,7 +447,7 @@ crates/ - [x] Editor lib/bin split + `EditorPluginGroup`; game EditorPlugin dogfood panel - [x] FBX/glTF model import + normalized static/skinned renderer routing; explicit generic scene-instance load via `bevy_ufbx` / `ModelRef` - [x] Asset browser model thumbnails (unified `assets/thumbnails/` pipeline; `ThumbnailState` cache; FBX via `FbxThumbnailSource`) -- [x] Shared Material/Material Instance assets, stable static/skinned renderer material slots, imported-source fallback, orphan preservation, and runtime-only property blocks ([ADR 0035](docs/adr/0035-shared-material-assets-and-renderer-slots.md), [material-system guide](docs/editor/material-system.md)) +- [x] Shared Material/Material Instance assets, stable static/skinned renderer material slots, imported-source fallback, orphan preservation, and a persistence-excluded property-block schema; runtime block application/promotion remains tracked in [Gitea #53](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/53) ([ADR 0035](docs/adr/0035-shared-material-assets-and-renderer-slots.md), [material-system guide](docs/editor/material-system.md)) - [x] Docked Material Library with cross-folder type/usage filters, resolved Material Instance thumbnails, shared guarded editors, and exact reversible viewport Material/Texture drops for renderer slots, primitives, and brush faces ([material-system guide](docs/editor/material-system.md); [Gitea #16](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/16), [Gitea #18](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/18)) - [x] Prefab v2 core: shared stable nested override paths, property/component/structural scopes, recursive graph validation, linked-root variants, conflict recovery, transactional source Apply, and undoable unpack/convert ([ADR 0027](docs/adr/0027-stable-prefab-ownership-and-variants.md)) - [x] Prefab v2 production acceptance: committed base/nested/variant fixtures pass workspace tests, recursive headless validation, packaged release startup, and live editor placement/inspection regression coverage ([Gitea #43](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/43)) @@ -491,7 +491,7 @@ crates/ **Unpack Layer** preserves nested links; **Convert to Local** recursively removes them. Current authoring UI coverage and production-acceptance gaps are tracked in [prefab-authoring.md](docs/editor/prefab-authoring.md). -- Material and direct-base Material Instance assets live under `assets/materials/`; shader schemas live under `assets/shaders/`. **Window > Material Library** provides cross-folder creation, editing, usage filters, and drag sources. Viewport Material drops target one exact renderer slot, primitive, or brush face and use reversible preview plus one-step history; loose Textures target primitives/brush faces and are rejected on renderer slots. Shared edits propagate through live-updated handles without reloading skinned geometry. Custom Surface evaluators share one constrained ABI between raster and Solari-eligible non-deformed geometry. Dynamic skinned/morph Solari geometry and a persisted property-block authoring workflow remain future work; see the [material-system guide](docs/editor/material-system.md). +- Material and direct-base Material Instance assets live under `assets/materials/`; shader schemas live under `assets/shaders/`. **Window > Material Library** provides cross-folder creation, editing, usage filters, and drag sources. Viewport Material drops target one exact renderer slot, primitive, or brush face and use reversible preview plus one-step history; loose Textures target primitives/brush faces and are rejected on renderer slots. Shared edits propagate through live-updated handles without reloading skinned geometry. Custom Surface evaluators share one constrained ABI between raster and Solari-eligible non-deformed geometry. Runtime property-block application/promotion is tracked in [#53](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/53); dynamic skinned/morph Solari geometry is tracked in [#54](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/54). See the [material-system guide](docs/editor/material-system.md). - 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. diff --git a/docs/adr/0035-shared-material-assets-and-renderer-slots.md b/docs/adr/0035-shared-material-assets-and-renderer-slots.md index 154e941..cf895b7 100644 --- a/docs/adr/0035-shared-material-assets-and-renderer-slots.md +++ b/docs/adr/0035-shared-material-assets-and-renderer-slots.md @@ -55,6 +55,8 @@ from its draw or skeleton representation. user decision to reassign or discard. - Legacy primitive/actor `MaterialDesc` paths remain compatibility paths until their consumers move to renderer slots; new mesh-renderer work uses shared references. -- Runtime property blocks have no editor promotion workflow yet. +- `MaterialPropertyBlocks` currently define the runtime-only schema and persistence exclusion, but + renderer application and the editor promote-to-instance transaction are not implemented. Gitea + #53 owns that complete workflow; callers must not treat the component as visibly applied yet. - Material graph authoring, nested instances, blended/transmissive materials, and a generalized per-renderer property-block inspector are outside this decision. diff --git a/docs/editor/README.md b/docs/editor/README.md index 8628b2e..b310bc7 100644 --- a/docs/editor/README.md +++ b/docs/editor/README.md @@ -93,7 +93,7 @@ Docs for the in-process egui editor (`crates/editor/`). Update this index when a - **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 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](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. 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). +- **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](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. diff --git a/docs/editor/evaluations/material-renderer-foundation/README.md b/docs/editor/evaluations/material-renderer-foundation/README.md index 514b7c5..7c1a785 100644 --- a/docs/editor/evaluations/material-renderer-foundation/README.md +++ b/docs/editor/evaluations/material-renderer-foundation/README.md @@ -65,7 +65,7 @@ Additional captures: | Dedicated static/skinned ownership | Pass | Separate authored/hydrated renderer types; rigged/animated manifests are rejected by static hydration | | Pose lifecycle | Pass | Explicit stable default clip; transform and morph-weight baseline restore on stop, controller removal, preview reset, and PIE exit | | Renderer material slots | Pass | Stable named IDs, imported fallback, explicit assignment, orphan retention, and in-place material patching | -| Material assets/instances | Pass | Versioned shared assets, direct-base sparse instances, transient property blocks, Apply/Revert/Create Instance | +| Material assets/instances | Pass | Versioned shared assets, direct-base sparse instances, Apply/Revert/Create Instance; property-block runtime application/promotion is isolated in #53 | | Texture parameters | Pass | Project-wide picker includes imported texture subassets; base/schema/stored/instance slots share browse, drop, reject, and clear behavior | | Component lifecycle | Pass | Stable registry IDs, reflected transactions/history, persistence allowlist, independent active state, and compatible composition | | Surface raster/Solari semantics | Pass for eligible geometry | Shared ABI packing, evaluator, textures, normal/emissive/unlit values, and cutout predicate | @@ -92,5 +92,6 @@ Additional captures: Bevy 0.19's maintained Solari path does not expose dynamic post-morph/post-skin vertex buffers and BLAS updates. Skinned and morph-deformed actors therefore remain visible in raster but are omitted from ray tracing with an actionable diagnostic. This is safer than tracing a stale bind-pose ghost; -dynamic deformed BLAS support remains future work and the corresponding Gitea acceptance item stays -open. +dynamic deformed BLAS support is the independently scoped Gitea #54. Runtime property-block +application and promotion are independently scoped in #53; this foundation record does not claim +either follow-up. diff --git a/docs/editor/evaluations/production-readiness/README.md b/docs/editor/evaluations/production-readiness/README.md index 60403a8..2a2be69 100644 --- a/docs/editor/evaluations/production-readiness/README.md +++ b/docs/editor/evaluations/production-readiness/README.md @@ -31,13 +31,13 @@ another commit, a dirty worktree, or an older package do not transfer to the can | ID | Requirement | State | Current evidence and gap | |----|-------------|-------|--------------------------| | G1 | Project create/open/resume, scene authoring, autosave/recovery, hierarchy, prefab, and asset integrity pass | Partial | Project/recovery/session/multi-scene/prefab implementations are documented in [project launcher](../../project-launcher.md), [session recovery](../../session-recovery.md), [multi-scene composition](../../multi-scene-composition.md), and [prefab authoring](../../prefab-authoring.md). Collaborative file safety `#49` and non-blocking native dialogs `#52` passed live acceptance. Candidate-specific end-to-end reruns remain. | -| G2 | Brush, material, terrain, physics placement, animation, audio, navigation, PIE, and build/package samples pass | Fail | Animation, audio, navigation, Material Library, targeted material drops, terrain `#22`-`#24`, physics placement `#25`, and build foundations are implemented with source/live fixtures. Renderer foundation `#51` and brush acceptance `#37` remain incomplete. Packaged testing is owner-deferred. | +| G2 | Brush, material, terrain, physics placement, animation, audio, navigation, PIE, and build/package samples pass | Fail | Animation, audio, navigation, renderer/material foundation `#51`, Material Library, targeted material drops, terrain `#22`-`#24`, physics placement `#25`, and build foundations are implemented with source/live fixtures. Brush acceptance `#37` remains incomplete. Packaged testing is owner-deferred. | | G3 | Undo/redo/cancel invariants and helper cleanup cover every production mutation path | Partial | The reusable harness and current tool coverage are documented in [operator regression testing](../../operator-regression-testing.md). Terrain stroke and physics settle/cancel/undo fixtures now exist; Gitea `#33` remains open for full mutation-path coverage. | | G4 | Representative project completes an eight-hour soak without unbounded memory/target growth or unrecoverable failure | Missing | No candidate soak log, resource timeline, failure ledger, or target-growth measurement exists. | | G5 | Cold start, scene open/save, asset refresh, common manipulation, and package-build budgets are documented and measured | Missing | Gitea `#34` is open; no ratified budgets or candidate measurement record exists. | | G6 | Headless content validation and CI are green from a clean checkout | Missing | [CI configuration](../../../../.github/workflows/ci.yml) exists and local source/headless checks have passed during feature work, but no clean-checkout candidate run is linked. The current Gitea server does not expose an Actions run endpoint for this repository. | | G7 | First-hour UX and recovery QA are signed off by someone other than the implementer | External | No independent sign-off exists. Gitea `#36` remains open; historical H1-H6 implementation-pass notes do not count. | -| G8 | Known limitations have severity/workaround and no P0 blocker remains | Fail | Limitations are distributed across feature docs rather than one candidate ledger. Open P0 work includes `#32`, `#33`, and `#51`; `#50` cannot close while a gate-relevant P0 remains. Roadmap audit `#35`, Material Library `#16`, targeted drops `#18`, collaborative safety `#49`, and dialog responsiveness `#52` are closed. | +| G8 | Known limitations have severity/workaround and no P0 blocker remains | Fail | Limitations are distributed across feature docs rather than one candidate ledger. Open P0 work includes `#32` and `#33`; `#50` cannot close while a gate-relevant P0 remains. Renderer foundation `#51`, roadmap audit `#35`, Material Library `#16`, targeted drops `#18`, collaborative safety `#49`, and dialog responsiveness `#52` are closed. Property-block application `#53` is P1; dynamic deformed Solari geometry `#54` is a documented P2 limitation with Forward/raster fallback. | ## Deliverables @@ -56,8 +56,8 @@ another commit, a dirty worktree, or an older package do not transfer to the can | Hierarchy parenting and prefab structure | Implemented | Not rerun | | Multi-scene composition | Implemented | Not rerun | | Brush blockout/edit/CSG | Implemented foundation; `#37` open | Not signed off | -| Material catalog and assignment | Material Library and exact targeted drops accepted; `#51` open only on deformed Solari geometry | Not rerun as one candidate | -| Terrain authoring | `#22`-`#24` open | Blocked | +| Material catalog and assignment | Renderer/material foundation `#51`, Material Library, and exact targeted drops accepted; optional property-block promotion is `#53` | Not rerun as one candidate | +| Terrain authoring | `#22`-`#24` source/live acceptance complete; M3 closed | Pass; packaged-runtime acceptance owner-deferred | | Physics placement | `#25` source/live acceptance complete | Pass; packaged-runtime acceptance owner-deferred | | Collider authoring and diagnostics | `#26` source/live acceptance complete | Pass; packaged-runtime acceptance owner-deferred | | Animation | Implemented | Not rerun | diff --git a/docs/editor/material-system.md b/docs/editor/material-system.md index 1661a2a..ffa8823 100644 --- a/docs/editor/material-system.md +++ b/docs/editor/material-system.md @@ -13,12 +13,17 @@ and [ADR 0036](../adr/0036-surface-abi-and-solari-parity.md). | Material instance | Overrides over one direct base material | Yes, under `assets/materials/` | | Renderer material slot | A stable reference on one static or skinned renderer | Yes, in scenes/prefabs | | Imported source material | Read-only default supplied by model import | Yes, as the slot fallback | -| Material property block | Temporary per-renderer/per-slot runtime overrides | No | +| Material property block | Reserved runtime-only per-renderer/per-slot override schema; application/promotion tracked by Gitea #53 | No | A renderer slot stores a `MaterialRef`, not a copy of the material. The registry UUID and subasset ID identify the target; the cached path is only a loading hint. A material instance may reference a material, but may not reference another instance. +`MaterialPropertyBlocks` are excluded from authored persistence, but they are not yet consumed by +renderer binding. Runtime application and the transactional **Promote to Material Instance** +workflow are tracked by Gitea #53. Use an ordinary direct-base Material Instance for reusable +variations until that issue closes. + ## Assign materials Open **Window > Material Library** for the cross-folder Material/Material Instance catalog. It @@ -130,7 +135,8 @@ The standard material path remains unchanged for materials without a custom eval Skinned meshes and morph-deformed meshes are currently excluded from Solari. This prevents rays from tracing their undeformed source/bind pose while raster shows the animated pose. They remain visible in raster, and Rendering diagnostics report the deformed exclusion. Dynamic deformed -vertex/BLAS updates are future work. +vertex/BLAS updates are tracked independently by Gitea #54 with animation, ray-hit, fallback, +memory, and update-cost acceptance. Surface ABI v1 does not support blended transparency, transmission/refraction, custom vertex displacement, or arbitrary pipeline stages.