Guide4 min read2 sections

Cooperative runtime asset work

docs/ASSET_WORK.mdSource updated 2026-10-25
Markdown
On this page 2 sections

Runtime texture transport and semantic admission now yield to ordinary event-loop tasks. AssetWork targets a task boundary after four milliseconds of observed elapsed time at explicit checkpoints. It uses ordinary timer tasks: the first Chromium test showed that scheduler.yield() continuations could complete all validation while ordinary timer callbacks remained starved. Both main-thread and Worker tests now verify that callbacks run during validation and that cancellation messages stop work before publication.

This is a cooperative target, not a four-millisecond maximum task or a global per-frame CPU quota. JSON snapshots/parsing, checksum preparation, some geometry checks, individual row/chunk operations and GPU uploads still contain synchronous work. Browser timer clamping also increases total loading time. Background tabs and physical devices need separate qualification.

#Work and ownership boundaries

  • Compressed transport expands in 256-byte input slices using the existing bounded inflater and integrity checks. Scheduled expansion owns its input before yielding. The synchronous offline helper remains available and produces the same bytes.
  • Base64 mip payloads decode in aligned 16,384-character fragments. Nonfinal padding is rejected; each fragment retains canonical encoding validation and the original total byte limit. This removes the previous long conversion of an entire mip in one task.
  • Mip derivation runs one row at a time through the same arithmetic kernel as offline compilation. Color, opaque color, data and normal-map behavior, odd dimensions and every encoded pixel remain unchanged.
  • A texture reader owns fresh input before the first yield. A model reader carries the same work scope through texture checks and checks cancellation before registering its successfully validated immutable result.

The streaming client ties each unit's work to that unit's abort signal. Shared consumers keep its work alive; the last pending release cancels it. Default yield timers are cleared on abort and reject immediately, so cancellation does not wait for a throttled tab to schedule another timer callback. Model hydration has a separate controller owned by the shared model unit. An individual consumer can stop waiting without cancelling a sibling. Last release or shutdown cancels hydration. If cooling allows a new attempt before an old rejection settles, a controller-identity check prevents that rejection from clearing the new result. No partial image/model can become ready or replace an accepted scene.

F2 and exported reports include Content work yields. The count covers transport, texture validation and hydration initiated by that content client. It is not a count of rendered frames or a CPU-time measurement. Byte reservations, cooling, GPU ownership and room publication gates retain their independent contracts.

No image/model/world/checkpoint format changed. Lossless texture transport remains place-content.4, and retained profiles 1–3 stay readable.

#Evidence and limits

npm run bench:asset-work runs seeded-noise 256- and 512-pixel textures with complete mip chains. It measures one-millisecond timer callbacks during transport plus semantic texture admission, with one warmup and three observations. The same script ran against commit 213356380aa6d8b7e75688b588378f5ff4024188 and current sources. All artifact hashes and encoded lengths match.

For the 512-pixel fixture, the median longest observed timer gap falls from about 251 ms to 21 ms, while total wall time rises from about 251 ms to 400 ms. The 256-pixel fixture changes from about 66 ms to 10 ms for its longest gap, with total time rising from about 66 ms to 124 ms. These are local responsiveness/throughput observations, not FPS, network startup, p95 or hardware guarantees. Baseline, current observations.

The dedicated browser probe uses the production codec and texture reader in both main-thread and real Worker placements. It validates exact identity, real timer progress, cancellation and retry. Separate shared-player journeys cover normal travel, corrupt speculative content, graphics recovery, published simulation recovery and live editor revisions. Acceptance evidence records the final verification and the initial browser starvation failure.

Remaining work includes aggregate CPU scheduling, asynchronous JSON/geometry preparation, incremental GPU installation, progressive mip/detail streaming, long-session/physical-device qualification and the final art pass. This increment does not complete a numbered roadmap milestone.

GPU installation now has its own cooperative upload contract and acceptance. Admission and installation retain separate per-job budgets; this does not establish an aggregate CPU/frame deadline.

End of Asset work