You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Batch / Group: Batch 2.1 — Foundations from RFC-0005, Group A
Runbook spec:docs/src/runbook/phases/phase-2.md (committed with the roadmap)
Summary
Replace the FxHashMap<u32, T> object/mesh/light/material/model tables in Renderer3D with dense Vec-backed slot arrays addressed by generation-checked handles, per the RFC-0005 storage decision.
goud_engine/src/libs/graphics/renderer3d/render/mod.rs — frame scan currently iterates &self.objects (hash map); must iterate the new dense slots.
Every renderer3d/core_*.rs file that inserts/removes/looks up by u32 id (models, instances, primitives, static batch) — update to the new handle type.
Boundary constraints (only those that apply):
Raw GPU calls stay in libs/graphics/backend/ — no wgpu:: outside it.
Pattern to follow: RFC-0005 (ENG2-P0-09) storage decision; existing generational-handle patterns in ecs/ (Handle<T>) and assets/ (Handle<T>) — mirror the index+generation scheme, do not invent a third one.
Scope
Design and implement dense Vec-backed slot arrays with generation-checked handles for objects, instanced meshes, lights, materials, models, model instances, particle emitters, skinned meshes, animation players.
Replace every FxHashMap<u32, _> lookup/insert/remove call site in renderer3d/ with the new handle API.
Stale-handle lookups must fail validation (return None/error), never alias a reused slot.
Tests: spec test at goud_engine/tests/spec/ + unit/isolation coverage for the new code paths.
Docs/rules updates if this invalidates .agents/rules/graphics-patterns.md or docs/src/*.
Acceptance Criteria
Zero FxHashMap<u32, _> fields remain in renderer3d/core/mod.rs for the migrated collections (grep-gated).
Frame scan iterates dense slots directly (no hash lookups on the hot path).
A stale/reused handle test proves generation mismatch is detected, not aliased.
PERF (area:performance): cull_scaling bench (from ENG2-P0-03) shows no regression from the storage swap alone (informational baseline for later Phase 2 issues that build on this).
None — additive/internal. The u32 handle values returned to callers keep their external shape (still u32-based FFI ids); only internal storage changes. If the handle representation must change externally, treat as breaking and name the Throne follow-up in a rebased body before merge.
Blocked By
ENG2-P0-09 (RFC-0005 must decide dense-slot storage shape before this executes).
renderer3d/core/mod.rs:54-93 — objects, instanced_meshes, particle_emitters, lights, materials, object_materials, skinned_meshes, models, model_instances, animation_players are all FxHashMap<u32, _> fields (verified in current source at these lines).
The frame scan iterates these hash maps directly (for (&id, obj) in &self.objects in render/mod.rs) — this is the O(total) cost this issue targets, though the culling decision itself moves upstream in ENG2-P2-02. This issue is about storage shape; P2-02 is about when culling runs.
This is the RFC-0005 (P0-09) foundation — do not start until that RFC lands; it decides dense-slot vs other storage shapes.
Parent
eng2-p2-render-core)docs/src/runbook/phases/phase-2.md(committed with the roadmap)Summary
Replace the
FxHashMap<u32, T>object/mesh/light/material/model tables inRenderer3Dwith dense Vec-backed slot arrays addressed by generation-checked handles, per the RFC-0005 storage decision.Architecture Context
Layer: Layer 2 (Libs) —
libs/graphics/renderer3d/(seetools/lint_layers.rs— downward-only deps).Modules/types touched:
goud_engine/src/libs/graphics/renderer3d/core/mod.rs— replaceobjects,instanced_meshes,particle_emitters,lights,materials,object_materials,skinned_meshes,models,model_instances,animation_playersfields (allFxHashMap<u32, _>) with dense slot storage.goud_engine/src/libs/graphics/renderer3d/render/mod.rs— frame scan currently iterates&self.objects(hash map); must iterate the new dense slots.renderer3d/core_*.rsfile that inserts/removes/looks up byu32id (models, instances, primitives, static batch) — update to the new handle type.Boundary constraints (only those that apply):
libs/graphics/backend/— nowgpu::outside it.Pattern to follow: RFC-0005 (ENG2-P0-09) storage decision; existing generational-handle patterns in
ecs/(Handle<T>) andassets/(Handle<T>) — mirror the index+generation scheme, do not invent a third one.Scope
FxHashMap<u32, _>lookup/insert/remove call site inrenderer3d/with the new handle API.None/error), never alias a reused slot.goud_engine/tests/spec/+ unit/isolation coverage for the new code paths..agents/rules/graphics-patterns.mdordocs/src/*.Acceptance Criteria
FxHashMap<u32, _>fields remain inrenderer3d/core/mod.rsfor the migrated collections (grep-gated).cull_scalingbench (from ENG2-P0-03) shows no regression from the storage swap alone (informational baseline for later Phase 2 issues that build on this).cargo check && cargo fmt --all -- --check && cargo clippy -- -D warningsclean;cargo testgreen;./codegen.sh && git diff --exit-code(drift gate)Breaking Change & Throne Follow-up
None — additive/internal. The
u32handle values returned to callers keep their external shape (stillu32-based FFI ids); only internal storage changes. If the handle representation must change externally, treat as breaking and name the Throne follow-up in a rebased body before merge.Blocked By
ENG2-P0-09 (RFC-0005 must decide dense-slot storage shape before this executes).
Files Likely Touched
goud_engine/src/libs/graphics/renderer3d/core/mod.rs,renderer3d/core_primitives.rs,renderer3d/core_models/,renderer3d/core_model_instances.rs,renderer3d/core_static_batch.rs,renderer3d/render/mod.rsAgent Notes
renderer3d/core/mod.rs:54-93—objects,instanced_meshes,particle_emitters,lights,materials,object_materials,skinned_meshes,models,model_instances,animation_playersare allFxHashMap<u32, _>fields (verified in current source at these lines).for (&id, obj) in &self.objectsinrender/mod.rs) — this is the O(total) cost this issue targets, though the culling decision itself moves upstream in ENG2-P2-02. This issue is about storage shape; P2-02 is about when culling runs.Verification