Files
open-wc/docs/modules/m2-runtime-mesh-finalizer.md
T

10 KiB

M2 Runtime Mesh Finalizer

Metadata

Field Value
Status Implemented extraction
Target/work package M03 / M03-RND-M2-RUNTIME-MESH-FINALIZER-001
Owners Stale Mesh refresh version, rebuild classification, M2Builder rebuild and fallback
Last verified Worktree work/sindo-main-codex/m03-m2-runtime-mesh-finalizer, 2026-07-17
Profiles/capabilities Static cached and prototype M2 runtime material preparation

Purpose

Finalize an extracted static M2 Mesh for runtime use by accepting already-loaded raw M2 data, preserving material refresh version 2, rebuilding only billboard/ UV-rotation cases and returning the historical original-Mesh fallback.

Non-goals

  • Read raw .m2 files or call ClassDB/FileAccess/ResourceLoader.
  • Own request/finalize queues, Mesh/missing/prototype caches or MultiMeshes.
  • Select cache paths or extract a Mesh from the originally loaded Resource.
  • Change classifier predicates, builder materials, refresh version or profiles.

Context and boundaries

flowchart LR
    Extractor[M2MeshResourceExtractor] --> Loader[StreamingWorldLoader]
    Loader -->|is raw data required?| Finalizer[M2RuntimeMeshFinalizer]
    Loader --> Raw[M2RawModelRepository]
    Raw --> Finalizer
    Finalizer --> Classifier[M2RuntimeMeshRebuildClassifier]
    Finalizer --> Builder[M2Builder]
    Builder --> Subtree[M2MeshResourceExtractor]
    Finalizer -->|prepared Mesh| Cache[M2MeshResourceCacheState]

The finalizer may use Mesh metadata, raw value Dictionaries, M2Builder and the two existing scene-free M2 services. Raw-file I/O, cache state, render permits, Nodes outside temporary rebuild roots and other application layers are forbidden.

Public API

Symbol Kind Purpose Thread/lifetime Errors
requires_raw_data_for_refresh(mesh) Query Tell loader whether stale Mesh needs raw-file lookup Renderer main thread Null/current false
finalize_mesh(path, mesh, raw_data, extracted_directory) Command/query Return current, marked, rebuilt or fallback Mesh Renderer main thread; one finalize operation Null Mesh returns null; invalid rebuild falls back
clear() Command Clear memoized classifier decisions Map reset/final shutdown Idempotent
cached_rebuild_decision_count() Diagnostic query Expose memoized path-decision count Tests/diagnostics None

Inputs and outputs

Direction Contract/data Producer Consumer Ownership Thread/lifetime
Input Extracted Mesh and normalized M2 path Loader/extractor adapter Finalizer Borrowed Mesh reference/String copy One call
Input Already-loaded raw M2 Dictionary M2RawModelRepository through loader adapter Classifier/M2Builder Caller-owned value container One call
Input Extracted directory path Loader configuration M2Builder texture resolution Copied String One rebuild
Output Original or rebuilt current Mesh Finalizer Cache/prototype adapter Borrowed/new Resource reference Cache may retain

Side effects are Mesh refresh metadata, classifier memoization and temporary M2Builder prototype creation/destruction during required rebuilds.

Data flow

flowchart TD
    Mesh[Extracted Mesh] --> Current{Refresh version >= 2?}
    Current -->|yes| ReturnOriginal[Return original unchanged]
    Current -->|no| NeedRaw[Repository supplies raw M2 data through loader]
    NeedRaw --> HasData{Raw data available?}
    HasData -->|no| Mark[Mark original version 2]
    HasData -->|yes| Classify{Billboard or UV rotation?}
    Classify -->|no| Mark
    Classify -->|yes| Build[M2Builder temporary prototype]
    Build --> Extract[M2MeshResourceExtractor first Mesh]
    Extract --> Rebuilt{Rebuilt Mesh exists?}
    Rebuilt -->|yes| ReturnRebuilt[Return rebuilt Mesh]
    Rebuilt -->|no| Mark
    Mark --> ReturnOriginal

Lifecycle/state

stateDiagram-v2
    [*] --> Current: Mesh metadata >= 2
    [*] --> Stale: Mesh metadata < 2
    Stale --> Current: empty/ordinary data marks original
    Stale --> Rebuilding: classifier requires rebuild
    Rebuilding --> Current: rebuilt Mesh returned
    Rebuilding --> Current: failure marks original fallback
    Current --> Current: later preparation is no-op

Classifier decisions are memoized per normalized path until either existing map/reset clear site calls clear().

Main sequence

sequenceDiagram
    participant Loader as StreamingWorldLoader
    participant Finalizer as M2RuntimeMeshFinalizer
    participant Raw as M2Loader boundary
    participant Classifier as RebuildClassifier
    participant Builder as M2Builder
    Loader->>Finalizer: requires_raw_data_for_refresh(mesh)
    alt current Mesh
        Finalizer-->>Loader: false; reuse Mesh
    else stale Mesh
        Finalizer-->>Loader: true
        Loader->>Raw: load static raw Dictionary
        Loader->>Finalizer: finalize_mesh(path, mesh, raw, extracted dir)
        Finalizer->>Classifier: needs_runtime_mesh_rebuild(path, raw)
        opt rebuild required
            Finalizer->>Builder: build(raw, extracted dir)
            Finalizer->>Finalizer: extract first Mesh; free prototype
        end
        Finalizer-->>Loader: rebuilt or marked fallback Mesh
    end

Dependency diagram

flowchart TB
    Loader[StreamingWorldLoader] --> Finalizer[M2RuntimeMeshFinalizer]
    Finalizer --> Classifier[M2RuntimeMeshRebuildClassifier]
    Finalizer --> Extractor[M2MeshResourceExtractor]
    Finalizer --> Builder[M2Builder]
    Loader --> Raw[M2RawModelRepository]
    Loader --> Cache[M2MeshResourceCacheState]
    Finalizer -. no dependency .-> Raw
    Finalizer -. no dependency .-> Cache

Ownership, threading and resources

  • Renderer main thread executes metadata changes and M2Builder work.
  • M2RawModelRepository owns raw M2 file/native calls; loader supplies its value result.
  • Finalizer owns classifier memoization and temporary rebuild prototype lifetime.
  • M2Builder owns construction rules; extractor selects the first rebuilt Mesh.
  • Cache/prototype adapters decide where the returned Mesh reference is retained.

Errors, cancellation and recovery

Failure/state Detection Behavior Diagnostic Recovery
Null Mesh Guard Return null Contract verifier Caller marks missing
Current Mesh Metadata query Return exact reference; no raw load Contract verifier None needed
Raw file/parse unavailable Empty Dictionary from loader Mark/reuse original Existing renderer behavior Source/cache repair
Ordinary stale Mesh Classifier false Mark/reuse original Classifier verifier None needed
Builder produces no Mesh Extractor null Mark/reuse original Finalizer fallback fixture Source/builder repair
Reset/shutdown Loader lifecycle Clear classifier decisions Source/clear verifier Recompute next session

Configuration and capabilities

MATERIAL_REFRESH_VERSION remains 2 and is now owned by this finalizer. Finalize permits, cache paths, extracted directory configuration and quality profiles remain unchanged in the loader.

Persistence, cache and migration

No new format is serialized. Existing Mesh metadata key wow_m2_material_refresh_version, M2Builder MATERIAL_FORMAT_VERSION == 2 and .tscn/.glb caches are unchanged; no migration or rebake is introduced.

Diagnostics and observability

cached_rebuild_decision_count exposes only a scalar count. Existing renderer logs/queue metrics are unchanged. Normalized M2 path remains the correlation key.

Verification

  • verify_m2_runtime_mesh_finalizer.gd: null/current/raw requirement, empty and ordinary marking, synthetic triangle billboard rebuild, rebuild failure fallback, refresh metadata, classifier clear, source boundary and 100-by-256 bounded finalization.
  • Classifier/extractor/cache/pipeline/material/shutdown/M2 build regressions cover adjacent behavior. No asset-backed or original-client visual claim is made.

Extension points

  • Asset-backed fixture coverage can be added without changing the finalizer's value-data contract.
  • Refresh versions above 2 require explicit cache/fidelity evidence and docs.

Capability status

Capability Status Evidence Gap/next step
Runtime Mesh refresh/fallback Implemented extraction Synthetic transition/rebuild verifier Asset-backed corrupt/stale cache pending
Rebuild predicate Implemented extraction dependency Classifier fixtures Original-client material comparison pending
Raw M2 refresh I/O Implemented repository dependency Repository source/invalid verifier Legal success fixture pending

Known gaps and risks

  • Required rebuild remains synchronous main-thread work behind existing permits.
  • Synthetic geometry proves transition/build behavior, not full asset materials.
  • No proprietary M2 traversal, descriptor-pressure/leak, p95/p99 or paired original-client capture is included.

Source map

Path Responsibility
src/render/m2/m2_runtime_mesh_finalizer.gd Refresh version, classification, rebuild and fallback
src/render/m2/m2_raw_model_repository.gd Raw-file/native I/O and Dictionary result
src/scenes/streaming/streaming_world_loader.gd Repository call and returned-Mesh adoption
src/render/m2/m2_runtime_mesh_rebuild_classifier.gd Memoized billboard/UV-rotation predicate
src/render/m2/m2_mesh_resource_extractor.gd First rebuilt-Mesh selection
src/tools/verify_m2_runtime_mesh_finalizer.gd Transition/rebuild/boundary/timing regression