Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions docs/PRDs/batch-2026-10-01-visual-quality/EXECUTE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Execute this batch

## Agent handoff

```text
Read AGENTS.md, docs/PRDs/AGENTS.md and this folder's README.md.
Work from current origin/develop in an isolated branch/worktree.
Choose the highest-value unblocked item from the execution queue.
For an existing owner, read and update its canonical PRD rather than writing a replacement.
Reconcile the current code, tests and merged/open PRs before treating any older claim as missing.
Search capabilities and inspect the installed Three pin and its patches before adding a system.
Keep appearance in generated game source. Reuse the renderer, mixer, loader and frame lifecycle.
Open one implementation PR for that PRD, not one PR for this entire implementation batch.
Implement the smallest bounded phase, run its named tests and playtest, and update actual results inline.
Do not tick another platform's box from browser proof or a green metadata/build check.
Rebase/reconcile shared files between dependent tasks; do not merge parallel changes blindly.
Stop at a failed admission gate with the measured reason, or complete/archive the PRD honestly.
```

## Proof setup

Each new PRD names future test/scenario paths. Those paths are not claimed to exist today. Add the smallest opt-in fixture to the existing `examples/abyss-framework` example, or reuse a better existing fixture and change the proof path in the canonical PRD. Its normal scene must remain unchanged. Do not create a new engine package merely to hold an example.

`VQ_URL` must point to the built/served fixture. `VQ_NATIVE_EXECUTABLE` must name that same fixture's packaged Linux executable. `VQ_ANDROID_DEVICE` is the chosen online emulator/device serial for VQ-01. Build/serve/package using the repository's existing commands; variables with `:?` deliberately refuse an unset value. Capture the fixture route, exact cohort/commit and adapter with the result. Do not run a scenario against an unrelated default scene and report success.

For new public mechanisms, use the existing capability manifest/MCP and update generated guidance. Inspect the installed pin (`three@0.185.1` at the audit baseline) before using an addon seen in online documentation. An incompatible addon can be declined, scoped down, or introduced through an explicitly qualified upgrade; none licenses an automatic fork of the renderer.

## Checks and progress

Run `pnpm prd:progress <canonical-file>` before work and after each phase. New specs have three phases, six phase boxes and two acceptance boxes, with `proof:` on each. All start at zero; a written plan is not implementation progress. Existing PRDs may need their old checklist shape repaired **without deleting completed work**.

For implementation, use the root AGENTS.md runtime gates and the exact feature playtests. For this documentation-only collection, use the repository's prose lane:

```sh
pnpm check:docs
pnpm exec vitest run scripts/__tests__/check-doc-links.spec.ts scripts/__tests__/evidence-budget.spec.ts scripts/__tests__/evidence-citations.spec.ts scripts/__tests__/sync-agent-docs.spec.ts scripts/__tests__/ci-structure.spec.ts scripts/__tests__/ci-needs.spec.ts
```

Those commands are required execution guidance, not a claim they were run while filing this collection. No runtime test, new benchmark result or human visual approval is supplied by this planning change.

## Concurrency and shared ownership

| Workstream | Can proceed independently | Serialize or reconcile |
|---|---|---|
| Build/runtime correctness | VQ-01 | Runtime artifact capability contract and loader/cook changes |
| Native output correctness | VQ-02 | `renderer.ts`, output attachments and native replay |
| Temporal/exposure | PRD-269, then PRD-455; PRD-339 after output is reliable | `chain.ts`, `velocity.ts`, `worldEnvironment.ts`, quality source |
| Animation | VQ-04 followed by VQ-05 | One mixer/action owner; do not let both reset action weights |
| World transitions | PRD-460, then proxy/impostor follow-ups | CPU and GPU WorldCells selection, per-instance identity, shadow alpha |
| Lighting | VQ-03 and upstream admission for VQ-06 | Material lighting contribution, probe capture budgets and PRD-457 |
| Optional look work | Decals and material fixture authoring | Shared generated render plumbing and temporal/alpha semantics |

Hardware access, rights to assets and human aesthetic approval are named blockers, not progress boxes. Browser and Linux-native qualification is not a promise of phone frame rate. Release scope is unchanged; this folder does not declare all visual experiments release-critical.
43 changes: 43 additions & 0 deletions docs/PRDs/batch-2026-10-01-visual-quality/EXISTING-PRDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Existing canonical PRDs in this batch

These are **references to existing work, not duplicate specifications**. Their files, evidence, completed boxes and associated PRs stay at their canonical paths. This preserves history and in-flight branches while providing one execution entry point.

Baseline inspected: `d72778382b134ef8763f58825cb4d4fd8cc0f6e3` on `develop`. Old status prose is not authoritative over newer code. Before execution, compare the relevant implementation and tests, preserve all proved work, add only the unresolved scope and normalize missing per-phase/proof markers in the canonical document. Never turn a stale `PROPOSED` heading into a rewrite order.

| Queue | Owner | Outcome | Execution note | Dependency / coordination |
|---|---|---|---|---|
| Wave 0 | [PRD-269](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/lighting/PRD-269-motion-vectors-or-the-temporal-filters-lie.md) | Velocity/history correctness | Source exists; reconcile old PROPOSED text with current velocity code. Qualify gaps; do not rebuild it. | Before 455, VQ-13 and temporal hair/fog consumers. |
| Wave 1 | [PRD-455](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-455-temporal-reconstruction-from-dynamic-resolution.md) | Temporal AA and dynamic-resolution reconstruction | Reuse existing owner. Same-resolution temporal qualification is its first bounded milestone; an upstream TRAA node is not by itself an upscaler. | 269; coordinate MSAA, jitter, camera cuts and instance identity. |
| Wave 1 | [PRD-339](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-339-the-frame-sets-its-own-exposure.md) | Auto exposure / eye adaptation | Reuse; adapt the current generated-source exposure seam, not a second tone mapper. | VQ-02 output correctness; include dark/bright transition traces. |
| Wave 1 | [PRD-460](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-460-invisible-streaming-transitions.md) | Prop arrival and LOD crossfades | Reuse; terrain morphing already exists. Apply the remaining work to CPU and GPU-selected scatter routes. | Existing WorldCells and PR #375; coordinate temporal reactive/disocclusion behavior. |
| Wave 2 | [PRD-456](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-456-distant-world-cell-proxies.md) | Distant cell HLOD / silhouettes | Reuse; do not confuse per-asset impostors or shadow proxies with cell HLOD. | Existing world-resource accounting; 460 handoffs. |
| Wave 2 | [PRD-457](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-457-virtual-shadows-scale-by-measurement.md) | Shadow scheduling, sparse-page admission, local-light boundary | Reuse. Directional virtual shadows already exist; phase 3 also owns local-light work. | Coordinate VQ-06; preserve a correct cached-level fallback. |
| Wave 2 | [PRD-344](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-344-contact-occlusion-baked-from-the-geometry-it-ships-with.md) | Cheap baked contact occlusion | Reuse; distinguish this outcome from existing lightmaps and imported AO textures. | Use current cook/mesh data; retain mobile low-tier benefit. |
| Wave 2 | [PRD-268](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/lighting/PRD-268-light-that-comes-from-off-screen.md) | Static diffuse probes / off-screen lighting | Source exists; reconcile implementation and remaining proof before any extension. | Precondition for VQ-09; not a replacement for specular VQ-03. |
| Cross-cutting | [PRD-341](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/done/PRD-341-a-frames-tone-is-a-number-and-the-number-is-a-gate.md) | Tone and luminance assertions | Implemented and archived by [PR #392](https://github.com/ThreeNativeHQ/threenative/pull/392), merged 2026-10-02. Reuse its captured-tone observations, assertions and CLI; a luminance score is not an aesthetic verdict. | Useful for 339, VQ-02 and matched material tests. |
| Cross-cutting | [PRD-342](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-342-where-the-frame-goes-pass-cost-ablation.md) | Measured post-stage ablation | Reuse rather than build another profiler. Inspect current frame/pass instrumentation first. | Useful for 455 and every optional expensive effect. |

## Canonical checkout paths

```text
docs/PRDs/lighting/PRD-269-motion-vectors-or-the-temporal-filters-lie.md
docs/PRDs/unreal-like-features/PRD-455-temporal-reconstruction-from-dynamic-resolution.md
docs/PRDs/AAA-visuals/PRD-339-the-frame-sets-its-own-exposure.md
docs/PRDs/unreal-like-features/PRD-460-invisible-streaming-transitions.md
docs/PRDs/unreal-like-features/PRD-456-distant-world-cell-proxies.md
docs/PRDs/unreal-like-features/PRD-457-virtual-shadows-scale-by-measurement.md
docs/PRDs/AAA-visuals/PRD-344-contact-occlusion-baked-from-the-geometry-it-ships-with.md
docs/PRDs/lighting/PRD-268-light-that-comes-from-off-screen.md
docs/PRDs/done/PRD-341-a-frames-tone-is-a-number-and-the-number-is-a-gate.md
docs/PRDs/AAA-visuals/PRD-342-where-the-frame-goes-pass-cost-ablation.md
```

## Companion work: resume, do not re-file

- [PRD-454](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-454-worldcells-budget-real-resources.md): actual resource budgets; precondition to texture-residency extensions.
- [PRD-458](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-458-open-worlds-hold-60-fps-by-default.md) and [open-world PRD-473](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-473-open-worlds-hold-120-fps-gpu-driven.md): preserve merged GPU/LOD/shadow work and finish remaining visible/performance qualification, including impostor coverage/shadows. Their merged [PR #375](https://github.com/ThreeNativeHQ/threenative/pull/375) still describes open acceptance work. A merge does not establish 60/120 fps.
- [PRD-381](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/feature-mining/PRD-381-nine-mineable-seams-in-eanpa-sky.md): VQ-03 is the bounded local-reflection child for row 5; VQ-08 covers the cloud/overhead-field outcome related to row 4. Record these child links when executing that parent's own admission work; filing a child does not mean its gate passed. Local-shadow row 8 remains coordinated through PRD-457.
- [PRD-343](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-343-a-light-smaller-than-a-pixel-is-still-a-light.md) and [PRD-345](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-345-a-backlit-subject-is-not-a-hole-in-the-sky.md): optional existing work for subpixel emitters and authored backlit readability. Do not implement a compulsory rim light in core.
- [Merged rain/snow PR #382](https://github.com/ThreeNativeHQ/threenative/pull/382): reuse the kits and preserved completed PRDs. Only the reported native bloom regression is added here as VQ-02. Snow rolling resistance is nonvisual physics follow-up and is not silently included in this visual batch.

The repository already has two different PRDs numbered 473. Use **full paths and titles**, not the number alone. New `VQ-01` through `VQ-15` identifiers intentionally avoid allocating more conflicting global integers.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
prd_contract: v1
---

# PRD-VQ-01 — Native asset compatibility follows the selected runtime and actual decoders

**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed.
**Batch:** [Visual quality execution batch](README.md). **Wave:** 0 / correctness.
**Dependencies:** None. This is a build/runtime contract repair, not permission to remove compatibility guards.

## Grounding and intended outcome

[packages/create-threenative/src/build.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/create-threenative/src/build.ts) still rejects compressed assets by mobile target in `assertNativeAssetsCompatible`, while the runtime documentation identifies Android V8 as the default. The source establishes inconsistent capability selection; it does not prove that shipping V8 alone makes the Basis, Meshopt or Draco loading paths work. Workers, bundling, file access, decoder payloads and GPU formats are separate requirements.

**Outcome:** A packaged game either decodes its declared assets on its selected runtime or is refused before publication with an accurate codec-specific reason. Android V8 and QuickJS must not be conflated; desktop QuickJS must not bypass checks simply because it is desktop.

## Design and ownership

Resolve one runtime capability record from the exact selected artifact/cohort before cooking. Thread it through asset cooking, the compatibility guard, native bundling and the runtime loader. Record engine, WASM support, packaged decoder versions and supported texture formats independently. An unknown capability takes an explicit decoder-free path or fails; it is never inferred from the build machine or from a desktop executable used to package Android. Keep QuickJS rollback supported. Do not silently change an authored asset or trust a manifest that disagrees with the packaged bytes.

Reuse `runtimeHasWebAssembly`, `assertNativeAssetsCompatible`, asset compiler decoder options and `packages/runtime-native/scripts/bundle.mjs`. Extend the artifact capability contract only where necessary. No new renderer, codec implementation, or blanket Android whitelist. Preserve current WebGL and decoder-free fallbacks.

## Required behavior

- A table-driven suite covers web, desktop V8, desktop QuickJS, Android V8, Android QuickJS and unknown artifacts, with each codec independently allowed or refused.
- The loader validates actual KTX2 block formats and fallback transcodes. Mesh compression is separately tested; smaller download bytes are not reported as smaller GPU vertex buffers.
- Cook-cache keys include decoder capabilities and cohort identity. Switching engine or codec cannot reuse incompatible output.
- Diagnostics identify the asset, codec, selected artifact and missing capability. Build failure must leave the previous packaged artifact intact.

## Execution phases

All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates.

### Phase 1 — One capability decision

- [ ] Implement capability resolution from the selected artifact, including unknown-artifact handling and the full target/engine table. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`.
- [ ] Wire the same capability record into cooking and compatibility validation; preserve decoder-free rollback. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`.

### Phase 2 — The packaged bytes are authoritative

- [ ] Make bundling and loading retain exactly the declared decoders and invalidate stale cook-cache entries. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`.
- [ ] Create separate tiny textured/animated fixtures for KTX2, Meshopt and Draco; assert decoded texture content and geometry rather than only a successful import. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`.

### Phase 3 — Qualify the visible result

- [ ] The unchanged web fixture renders each codec correctly, with named adapter and no loader/GPU diagnostics. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-asset-capabilities.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`.
- [ ] The packaged Android V8 fixture decodes the admitted codecs on an emulator; unsupported codecs remain explicitly refused and the QuickJS decoder-free fixture still runs. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-asset-capabilities.playtest.json --target android --device ${VQ_ANDROID_DEVICE:?}`.

## Acceptance criteria

- [ ] All admitted codecs are demonstrated through the packaged loader, not merely through WASM availability; all refused combinations retain actionable build errors. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here.
- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts` plus the Phase 3 lifecycle scenario.

## Performance and promotion

Record encoded bytes, decoded texture/geometry bytes and peak load memory per codec. Enabling a path requires correct pixels and bounded lifetime, not a promised compression ratio. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source.

## Blocked on

Physical Android performance and thermals require a named phone and are separate from emulator correctness. Missing codec qualifications must remain individual exclusions.

## Completion record

Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete.
Loading
Loading