# WMO Runtime Mesh Finalizer ## Metadata | Field | Value | |---|---| | Status | Implemented extraction | | Target/work package | M03 / `M03-RND-WMO-RUNTIME-MESH-FINALIZER-001` | | Owners | Cached WMO runtime Mesh refresh version, surface iteration and material reconstruction | | Last verified | Worktree `work/sindo-main-codex/m03-wmo-runtime-mesh-finalizer`, 2026-07-18 | | Profiles/capabilities | Profile-independent cached WMO material refresh | ## Purpose Finalize stale cached WMO runtime Mesh materials outside `StreamingWorldLoader`: preserve exact Mesh identity, stamp the historical refresh version and reconstruct eligible surface materials through WMOBuilder. ## Non-goals - Traverse scene Nodes or own Mesh/MultiMesh attachment and lifetime. - Select WMO cache paths, poll ResourceLoader or schedule render build jobs. - Change WMOBuilder shaders, textures, blend rules or cache serialization. - Share an abstraction with the behaviorally different M2 finalizer. ## Context and boundaries ```mermaid flowchart LR Loader[StreamingWorldLoader traversal/build step] -->|Mesh plus extracted directory| Finalizer[WmoRuntimeMeshFinalizer] Finalizer -->|material definition plus compact texture paths| Builder[WMOBuilder material boundary] Builder -->|rebuilt Material| Finalizer Finalizer -->|same Mesh identity| Loader ``` The loader owns scene traversal and composition. The finalizer owns only the in-place Resource operation and depends on an injected WMO material builder. ## Public API | Symbol | Kind | Purpose | Thread/lifetime | Errors | |---|---|---|---|---| | `finalize_mesh(mesh, extracted_directory)` | Command/query | Stamp and refresh a stale Mesh in place | Renderer main thread; stateless between calls | Null returns null; unsupported Mesh returns exact identity | | `rebuild_cached_material(material, extracted_directory)` | Query/boundary | Reconstruct one metadata-bearing cached WMO Material | Renderer main thread; borrowed input | Null/unmarked/missing builder returns null | ## Inputs and outputs | Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime | |---|---|---|---|---|---| | Input | `Mesh` and refresh metadata | Cached WMO scene/render group | Finalizer | Borrowed Resource | Call duration; identity retained | | Input | Extracted content directory | Loader configuration | WMOBuilder | Borrowed String value | Call duration | | Input | Texture paths, WMO flags/shader/blend and cached colors | Surface Material metadata/parameters | Finalizer | Borrowed values | One surface rebuild | | Output | Compact texture-path array and material definition | Finalizer | WMOBuilder | Detached values | One builder call | | Output | Rebuilt Material | WMOBuilder | ArrayMesh surface | Surface adopts exact Resource | Mesh lifetime | | Output | Exact input Mesh | Finalizer | Loader traversal/build step | Caller retains ownership | Existing cache/scene lifetime | ## Data flow ```mermaid flowchart TD Mesh[Borrowed Mesh] --> Null{Null?} Null -->|yes| ReturnNull[Return null] Null -->|no| Current{Refresh version at least 10?} Current -->|yes| ReturnSame[Return exact Mesh] Current -->|no| Stamp[Stamp version 10] Stamp --> Array{ArrayMesh?} Array -->|no| ReturnSame Array -->|yes| Surface[Iterate surfaces] Surface --> Eligible{Material has texture0 metadata?} Eligible -->|no| Keep[Keep exact Material] Eligible -->|yes| Definition[Compact paths and copy metadata/colors] Definition --> Builder[WMOBuilder build material] Builder --> Result{Non-null result?} Result -->|yes| Adopt[Replace surface Material] Result -->|no| Keep Keep --> Surface Adopt --> Surface Surface -->|done| ReturnSame ``` ## Lifecycle/state ```mermaid stateDiagram-v2 [*] --> Stale: missing/version below 10 [*] --> Current: version at least 10 Stale --> Current: stamp before optional surface refresh Current --> Current: subsequent calls are identity-only ``` The version stamp is intentionally applied before type/material eligibility, as in the extracted loader behavior. The finalizer retains no Mesh or Material. ## Main sequence ```mermaid sequenceDiagram participant Loader as StreamingWorldLoader participant Finalizer as WmoRuntimeMeshFinalizer participant Mesh as ArrayMesh participant Builder as WMOBuilder Loader->>Finalizer: finalize_mesh(mesh, extracted_directory) Finalizer->>Mesh: read/stamp refresh metadata loop each stale ArrayMesh surface Finalizer->>Mesh: surface_get_material(index) alt cached WMO metadata exists Finalizer->>Builder: _build_material(definition, compact paths, directory) Builder-->>Finalizer: rebuilt Material or null Finalizer->>Mesh: surface_set_material when non-null end end Finalizer-->>Loader: exact Mesh identity ``` ## Dependency diagram ```mermaid flowchart TB Loader[StreamingWorldLoader] --> Finalizer[WmoRuntimeMeshFinalizer] Finalizer --> Engine[Mesh / ArrayMesh / Material] Finalizer --> Builder[Injected WMO material builder] Finalizer -. no dependency .-> Nodes[Node traversal/lifetime] Finalizer -. no dependency .-> RL[ResourceLoader] Finalizer -. no dependency .-> Queue[Build queue/scheduler] ``` ## Ownership, threading and resources - The renderer main thread serializes Mesh metadata and surface mutation. - The caller owns Mesh identity, scene traversal, attachment and destruction. - ArrayMesh surfaces adopt only non-null builder results; otherwise the exact cached Material remains attached. - The service retains no Resource, Node, RID, file, queue or per-path state. ## Errors, cancellation and recovery | Failure/state | Detection | Behavior | Diagnostic | Recovery | |---|---|---|---|---| | Null Mesh | Guard | Return null | Synthetic contract | Correct caller input | | Current Mesh | Version metadata | Return exact identity, no builder call | Identity/version contract | Version bump makes it stale | | Unsupported Mesh subtype | Type check after stamp | Return exact identity | PrimitiveMesh contract | No surface work required | | Null/unmarked Material | Metadata guard | Preserve exact surface value | Surface contract | Rebuild cache with metadata | | Missing builder/null result | Boundary guard/result | Preserve exact Material | Synthetic contract | Correct composition/retry after version bump | | Shutdown | Loader lifecycle | No retained work to cancel | Shutdown suite | New loader composes a new service | ## Configuration and capabilities Refresh version `10` and metadata key `wow_wmo_material_refresh_version` are the existing runtime compatibility boundary. No project setting, profile, permit or feature flag is introduced. ## Persistence, cache and migration The module writes only the existing runtime Mesh metadata stamp and serializes nothing. It does not change WMO scene/render cache formats or trigger rebakes. A future material-rule change must deliberately bump the refresh version. ## Diagnostics and observability The finalizer emits no logs and allocates no metrics. Existing `wmobuild` queue metrics and loader diagnostics remain the operational correlation surface. ## Verification - `verify_wmo_runtime_mesh_finalizer.gd`: null/current/non-ArrayMesh identity, version stamp, null/unmarked surface retention, compact path indices, flags/shader/blend/default and shader colors, exact builder adoption, missing-builder behavior, source ownership and 1,000 current calls under one second. - Adjacent WMO queue/cache/finalizer, shutdown, material and baseline regressions protect orchestration and visible output. - Fidelity evidence is exact behavior-preserving extraction; no private asset or original-client visual-parity claim is added. ## Extension points - Asset-backed WMO fixtures may compare reconstructed surface parameters without changing the service contract. - A deliberate material refresh change may bump the owned version with old/new fixtures and paired visual evidence. ## Capability status | Capability | Status | Evidence | Gap/next step | |---|---|---|---| | Runtime refresh admission | Implemented extraction | Identity/version/type contracts | Serialized cache fixture pending | | Cached material definition reconstruction | Implemented extraction | Path/metadata/color contracts | Asset-backed visual comparison pending | | Scene traversal/materialization | Loader-owned | Existing WMO regressions | Further safe extraction pending | ## Known gaps and risks - Surface mutation and WMOBuilder material construction remain synchronous main-thread work. - No proprietary WMO corpus, long leak run, GPU timing, traversal p95/p99 or paired build-12340 visual capture is included. ## Source map | Path | Responsibility | |---|---| | `src/render/wmo/wmo_runtime_mesh_finalizer.gd` | Refresh admission, surface iteration and material definition reconstruction | | `addons/mpq_extractor/loaders/wmo_builder.gd` | WMO shader/material construction semantics | | `src/scenes/streaming/streaming_world_loader.gd` | Composition, Node traversal, build jobs and lifetime | | `src/tools/verify_wmo_runtime_mesh_finalizer.gd` | Identity/version/material/source/timing regression | ## Related decisions and references - [`wmo-render-build-queue.md`](wmo-render-build-queue.md) - [`wmo-render-resource-finalizer.md`](wmo-render-resource-finalizer.md) - [`wmo-scene-resource-finalizer.md`](wmo-scene-resource-finalizer.md) - [`world-renderer.md`](world-renderer.md) - [`../../RENDER.md`](../../RENDER.md) - [`../../targets/roadmap/02-rendering-and-graphics.md`](../../targets/roadmap/02-rendering-and-graphics.md)