Files
open-wc/docs/modules/wmo-render-resource-cache-state.md
T

11 KiB

WMO Render Resource Cache State

Metadata

Field Value
Status Implemented
Target/work package M03 / M03-RND-WMO-RENDER-RESOURCE-CACHE-001
Owners Validated lightweight-WMO render Resources, negative cache and pending request paths
Last verified Worktree work/sindo-main-codex/m03-wmo-render-resource-cache, 2026-07-17
Profiles/capabilities Lightweight WMO render-cache path; profile-independent

Purpose

Own the mutually exclusive cached, missing and pending states for normalized lightweight-WMO render paths outside the monolithic streamer. The state holder accepts only caller-validated Resource references and records cache paths for threaded requests whose I/O lifecycle remains in StreamingWorldLoader.

Non-goals

  • Normalize WMO paths or construct .res cache paths.
  • Call ResourceLoader, inspect files or validate script/format versions.
  • Own WMO cached scenes, live prototypes, placements, build jobs or engine Nodes.
  • Change fallback order, retry timing, quality profiles or visible output.
  • Persist, migrate or build WMO caches.

Context and boundaries

flowchart LR
    Placement[Normalized WMO render lookup] --> Loader[StreamingWorldLoader]
    Loader --> State[WmoRenderResourceCacheState]
    State -->|cached Resource| Loader
    Loader -->|cache path| ResourceLoader[Godot ResourceLoader]
    ResourceLoader -->|status and loaded Resource| Loader
    Loader --> Validate[Script and FORMAT_VERSION validation]
    Validate -->|accepted Resource or missing| State
    Loader --> Fallback[Cached scene or live-prototype fallback]

The module may retain validated Resource references and copied path Strings. It has no FileAccess, ResourceLoader, Node, RID, worker, mutex, gameplay, network or editor dependency. Cache validation stays at the I/O boundary in the loader.

Public API

Symbol Kind Purpose Thread/lifetime Errors
resource_for(path) Query Borrow validated cached Resource Renderer main thread; until full clear Empty/unknown returns null
contains_resource(path) Query Test accepted cache state Renderer main thread Empty returns false
is_missing(path) Query Test negative cache state Renderer main thread Empty returns false
has_request(path) Query Test pending threaded-request state Renderer main thread Empty returns false
remember_request(path, cache_path) Command/query Record one loader-started request Renderer main thread; until terminal/reset Invalid or occupied state returns false
request_paths_snapshot() Query Copy pending normalized/cache-path mapping Poll or shutdown drain Detached Dictionary
complete_request_with_resource(path, resource) Command/query Remove pending request and adopt caller-validated Resource Terminal loader poll Unknown/null returns false
complete_request_as_missing(path) Command/query Remove pending request and adopt negative state Terminal loader poll Unknown returns false
clear_transient_state() Command Clear pending and missing while retaining accepted Resources Map reset/request drain Idempotent
clear_all() Command Release Resources, pending and missing Final runtime cache release Idempotent
pending_request_count() Query Preserve renderer queue metric contribution Renderer diagnostics None
diagnostic_snapshot() Query Return sorted detached scalar keys Tests/diagnostics Never exposes Resources

Inputs and outputs

Direction Contract/data Producer Consumer Ownership Thread/lifetime
Input Normalized relative WMO path Placement resolver through loader Cache state Copied String Map/cache lifetime
Input .res cache path after accepted threaded-request result Loader Pending state Copied String Until terminal/reset
Input Script/version-validated WMO Resource Loader validation adapter Resource cache Strong reference Until full clear
Output Borrowed validated Resource Cache state Loader render-root/build adapters State retains reference Lookup/build start
Output Detached pending-path snapshot Cache state Loader ResourceLoader polling/shutdown Caller-owned Dictionary One drain pass
Output Sorted scalar diagnostic keys Cache state Verifier/future metrics Caller-owned values Snapshot lifetime

Data flow

flowchart TD
    Lookup[Lookup normalized path] --> Cached{Cached?}
    Cached -->|yes| Return[Return validated Resource]
    Cached -->|no| Blocked{Missing or pending?}
    Blocked -->|yes| Null[Return null; loader waits/falls back]
    Blocked -->|no| Start[Loader starts threaded request]
    Start --> Remember[remember_request]
    Remember --> Poll[Loader polls detached request snapshot]
    Poll --> Terminal{Loaded or failed?}
    Terminal -->|no| Poll
    Terminal -->|failed| Missing[complete as missing]
    Terminal -->|loaded| Validate[Loader validates script/version]
    Validate -->|valid| Adopt[complete with Resource]
    Validate -->|invalid| Missing

Lifecycle/state

Each normalized path is Absent, Pending, Cached or Missing. Valid request completion leaves exactly one terminal state. Transient clear moves Pending and Missing to Absent but retains Cached; full clear moves every state to Absent and releases retained Resources.

stateDiagram-v2
    [*] --> Absent
    Absent --> Pending: remember valid request
    Pending --> Cached: validated Resource completion
    Pending --> Missing: load/validation failure
    Pending --> Absent: clear transient/full
    Missing --> Absent: clear transient/full
    Cached --> Absent: full clear

Main sequence

sequenceDiagram
    participant Loader as StreamingWorldLoader
    participant State as WmoRenderResourceCacheState
    participant RL as ResourceLoader
    Loader->>State: cached/missing/pending queries
    Loader->>RL: exists + load_threaded_request(cache path)
    Loader->>State: remember_request(normalized, cache path)
    loop renderer tick
        Loader->>State: request_paths_snapshot()
        Loader->>RL: load_threaded_get_status(cache path)
    end
    alt load failed
        Loader->>State: complete_request_as_missing(normalized)
    else loaded
        Loader->>RL: load_threaded_get(cache path)
        Loader->>Loader: validate script and FORMAT_VERSION
        Loader->>State: complete with Resource or as missing
    end

Ownership, threading and resources

  • The state owns three Dictionaries and strong references to accepted Resources.
  • The loader owns normalization, cache paths, ResourceLoader calls and validation.
  • All mutation is serialized by the renderer main-thread lookup/drain lifecycle.
  • No mutex or callback is needed; detached request snapshots permit safe removal.
  • The loader/build queue borrow Resources without transferring ownership.

Errors, cancellation and recovery

Failure/state Detection Behavior Diagnostic Recovery
Empty path/cache path Request guard Reject unchanged Contract verifier Repair caller input
Duplicate or occupied path State membership Reject request unchanged Contract/source verifier Await terminal/reset
Threaded load failed Loader status Complete as missing Existing renderer metrics Transient reset permits retry
Wrong script/old format Loader validation Complete as missing Cache-version source gate Rebuild cache, then reset
Shutdown while pending Loader drains ResourceLoader snapshot Clear transient afterward Shutdown verifier Next runtime starts absent
Final cache release Loader shutdown lifecycle Full clear releases Resources Shutdown verifier Recreated with loader

Configuration and capabilities

The module adds no setting or profile branch. wmo_render_cache_dir, resource format version, request scheduling and WMO build budgets remain loader-owned.

Persistence, cache and migration

The state is runtime-only and serializes nothing. WMOStreamingResource script identity and FORMAT_VERSION validation remain unchanged in the loader; no cache migration or rebuild is introduced by this extraction.

Diagnostics and observability

pending_request_count preserves the existing wmobuild metric contribution. Diagnostics expose only sorted normalized-path keys for cached/missing/pending states; Resource references and cache file paths are not exposed. No logs emit.

Verification

  • verify_wmo_render_resource_cache_state.gd: invalid input, detached requests, successful/missing terminal transitions, exclusivity, partial/full reset, sorted diagnostics, ownership/source boundary and bounded timing.
  • verify_render_runtime_cache_shutdown.gd: full release of accepted Resources and negative state through the loader lifecycle.
  • WMO queue/planner/registry/resolver and surrounding renderer regressions verify unchanged fallback/build behavior. This package makes no visual parity claim.

Extension points

  • Cached WMO scene request state is a separate typed module because its size limit, PackedScene validation and missing-file behavior differ.
  • A later loader I/O adapter may consume the detached request snapshot while preserving this state contract and cache-version boundary.

Capability status

Capability Status Evidence Gap/next step
Lightweight WMO render Resource state Implemented extraction Lifecycle/source/timing and shutdown verifiers Asset-backed traversal/leak evidence pending
Cache script/version validation Preserved in loader Source boundary and WMO regressions Dedicated corrupt-cache fixture could follow
Cached WMO scene state Implemented extraction Scene-cache lifecycle/source/timing verifier Asset-backed traversal/leak evidence pending
WMO materialization Partial/loader-owned Queue/planner regressions Further safe extraction

Known gaps and risks

  • Strong Resource references live until final cache release, matching prior state.
  • Missing cache files remain unrecorded for render Resources, so lookup can retry; this intentionally differs from the cached-scene path.
  • No proprietary WMO corpus, corrupt-version fixture, leak run, traversal p95/p99 or paired original-client capture is included.

Source map

Path Responsibility
src/render/wmo/wmo_render_resource_cache_state.gd Resource/missing/request state and resets
src/scenes/streaming/streaming_world_loader.gd Normalize, request, poll, validate, fallback and shutdown I/O
src/tools/verify_wmo_render_resource_cache_state.gd State, boundary and timing regression
src/tools/verify_render_runtime_cache_shutdown.gd Loader final Resource ownership regression