Compare commits

...

9 Commits

Author SHA1 Message Date
sindoring 5627180fd5 docs(M00): mark closeout handoff ready
Work-Package: M00-QAR-INTEGRATOR-CLOSEOUT-001
Agent: sindo-main-codex
Tests: coordination and documentation gates
Fidelity: metadata-only handoff; no compatibility claim change
2026-07-13 13:17:06 +04:00
sindoring ba81098797 test(M00): close renderer baseline milestone
Work-Package: M00-QAR-INTEGRATOR-CLOSEOUT-001
Agent: sindo-main-codex
Tests: post-merge render baseline dry-run; comparator self-test; coordination and documentation gates
Fidelity: records seven build-12340 reference categories and measured gaps without claiming parity
2026-07-13 13:16:52 +04:00
sindoring f19c0c45a7 Merge pull request 'fix(M00): release GUI capture render resources' (#15) from work/sindo-main-codex/m00-gui-rid-shutdown into master
Reviewed-on: #15
2026-07-13 12:12:33 +03:00
sindoring 09b3e87a8d fix(M00): release GUI capture render resources
Work-Package: M00-QAR-GUI-RID-SHUTDOWN-001
Agent: sindo-main-codex
Tests: render baseline dry-run; runtime cache shutdown; comparator self-test; coordination and documentation gates
Fidelity: shutdown-only ownership fix; no visual or Blizzlike335 behavior change
2026-07-13 11:08:30 +04:00
sindoring d1df794cd6 Merge pull request 'test(M00): complete animation and sky evidence' (#14) from work/sindo-main-codex/m00-animation-sky-evidence into master
Reviewed-on: #14
2026-07-13 09:02:32 +03:00
sindoring 0327e4862d test(M00): complete animation and sky evidence
Work-Package: M00-QAR-ANIMATION-SKY-EVIDENCE-001
Agent: sindo-main-codex
Tests: 14-pair visual audit; manifest/self-test; coordination/documentation gates
Fidelity: sky evidence paired approximately; Gryphon animation observed but placement-unpaired
2026-07-13 10:01:19 +04:00
sindoring 239cb2432e Merge pull request 'test(M00): record final paired evidence' (#13) from work/sindo-main-codex/m00-final-paired-evidence into master
Reviewed-on: #13
2026-07-12 02:28:00 +03:00
sindoring b5ddc86c92 test(M00): record final paired evidence 2026-07-12 03:21:39 +04:00
sindoring 3d90c6d79a Merge pull request 'test(M00): add landmark-region visual diff' (#12) from work/sindo-main-codex/m00-landmark-region-diff into master
Reviewed-on: #12
2026-07-12 02:07:30 +03:00
27 changed files with 580 additions and 26 deletions
+8
View File
@@ -822,6 +822,14 @@ $exe = Join-Path $env:TEMP 'godot-4.6.1-openwc\Godot_v4.6.1-stable_win64.exe'
- Added `src/tools/capture_render_checkpoints.gd` to load the Eastern Kingdoms streaming scene, move a dedicated camera to fixed regression viewpoints and save PNGs under `user://render_checkpoints`.
- Current checkpoints cover the Elwynn waterfall from front/side and Goldshire Inn/Blacksmith windows. Headless runs are dry-run only because the headless display server cannot produce viewport PNGs.
## 2026-07-13 Renderer Shutdown Ownership
- `StreamingWorldLoader` drains its asynchronous work before teardown, leaves parented streamed nodes to SceneTree ownership, then explicitly frees detached M2/WMO prototype nodes and clears resource caches.
- `ADTBuilder` explicitly frees a temporary `Water` root when an ADT liquid payload produces no child geometry. Dry tiles must not leave empty nodes in ObjectDB.
- `src/tools/verify_render_runtime_cache_shutdown.gd` regression-checks detached prototype and resource-cache release plus empty-liquid-root ownership. The unified render-baseline runner executes it before capture.
- A focused 8-second GUI checkpoint and a seven-checkpoint single-pass GUI run finish without Node, renderer resource or RID leak diagnostics. A timing-dependent anonymous zero-reference `RefCounted` ObjectDB warning can remain at engine teardown; it is tracked separately and is not suppressed.
- This is shutdown-only ownership behavior and does not alter checkpoint rendering, cache formats or the `Blizzlike335` compatibility profile.
## Practical Rule For Future Work
If something improves quality but creates visible hitch, it is not done. Move it to bake/cache/background work, split finalization over frames, or prewarm it before the player can see it.
+4 -1
View File
@@ -788,7 +788,10 @@ static func _build_tile_water_root(data: Dictionary, origin_offset: Vector3) ->
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
root.add_child(mi)
return root if root.get_child_count() > 0 else null
if root.get_child_count() > 0:
return root
root.free()
return null
static func _append_liquid_geometry(
@@ -0,0 +1,79 @@
# M00-QAR-ANIMATION-SKY-EVIDENCE-001 — Animation and sky evidence
<!-- OPENWC_CLAIM:M00-QAR-ANIMATION-SKY-EVIDENCE-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-ANIMATION-SKY-EVIDENCE-001:d1df794 -->
## Ownership
- Target: M00
- Program: QAR
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m00-animation-sky-evidence`
- Lease expires UTC: 2026-07-15
- Integrator: milestone integrator
## Outcome
Add private build 12340 evidence for the remaining sky-transition and native animated-M2 coverage, rerun all paired comparisons, and hand the resulting audit to the milestone integrator.
## Non-goals
- Committing proprietary screenshots or extracted assets.
- Claiming renderer parity from mismatched world placement or animation phase.
- Marking M00 DONE; only the milestone integrator may change target status or Evidence.
## Paths
- Exclusive: this claim and animation/sky evidence documentation
- Shared/hotspots: `docs/M00_FINAL_PAIRED_EVIDENCE.md`, `docs/modules/world-renderer.md`
- Generated/ignored: normalized private references under `sources/OpenWCReferenceCheckpoints`; captures and reports under `user://`
## Contracts and data
- Public API/events: unchanged
- Schema/format version: unchanged
- Migration/compatibility: existing five-reference comparison remains valid
- Consumers: M00 milestone integrator
## Dependencies
- Requires: user-captured build 12340 screenshots at 19:00 and two real `GryphonRoost01` animation phases
- Blocks: final integrator decision on M00 completion
- External state: private screenshots remain outside Git
## Verification
- Commands: private-reference preparation, full baseline runner, comparator self-test, coordination and documentation gates
- Fixtures: seven private build 12340 checkpoint references plus a second animation-phase provenance frame
- Fidelity evidence: sky-transition screenshot and observed wing pose change over three seconds
- Performance budget: existing M00 capture budgets
## Documentation deliverables
- Inline public API docs: unchanged
- Module specification: paired coverage and remaining limitations
- Data-flow diagram: unchanged
- Sequence/state/dependency diagrams: unchanged
- Source map/status updates: final paired evidence audit
## Simplicity and naming
- Important names introduced: none
- Simplest considered solution: normalize private captures outside Git and reuse the existing comparator
- Rejected complexity/abstractions: adding a video comparator or committing an asset corpus
- Unavoidable complexity and justification: animation phase and synthetic placement require human evidence classification alongside pixel metrics
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: exact-size private references registered; real ADT placement verified; canonical and visual captures completed; fourteen comparisons audited
- Next: milestone integrator reviews synthetic/real placement classification and GUI RID risk
- Blocked by:
## Handoff
- Commit: this work-package commit
- Results: `compared=14`, `failed=14`, `missing=0`; mean error `0.066893..0.176955`; original-client Gryphon wing phase changed over three seconds
- Remaining risks: synthetic probe placement differs from the original-client world placement; GUI RID/resource diagnostics remain separate
- Documentation updated: `docs/M00_FINAL_PAIRED_EVIDENCE.md`, `docs/modules/world-renderer.md`
@@ -1,6 +1,7 @@
# M00-QAR-CAMERA-FRAMING-REFINEMENT-001 — Goldshire pitch/FOV refinement
<!-- OPENWC_CLAIM:M00-QAR-CAMERA-FRAMING-REFINEMENT-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-CAMERA-FRAMING-REFINEMENT-001:3172f41 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-CAMERA-OCCLUDERS-001 — Camera occluder diagnostic
<!-- OPENWC_CLAIM:M00-QAR-CAMERA-OCCLUDERS-001:sindo-main-codex:2026-07-13 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-CAMERA-OCCLUDERS-001:9d34a47 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-CAMERA-POSE-EVIDENCE-001 — Goldshire camera pose evidence
<!-- OPENWC_CLAIM:M00-QAR-CAMERA-POSE-EVIDENCE-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-CAMERA-POSE-EVIDENCE-001:eca76c5 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-CAMERA-POSE-SWEEP-001 — Empirical camera pose sweep
<!-- OPENWC_CLAIM:M00-QAR-CAMERA-POSE-SWEEP-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-CAMERA-POSE-SWEEP-001:657a1d8 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-CAPTURE-SHUTDOWN-001 — Capture shutdown drain
<!-- OPENWC_CLAIM:M00-QAR-CAPTURE-SHUTDOWN-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-CAPTURE-SHUTDOWN-001:8d4641a -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-COORD-CALIBRATION-001 — Renderer coordinate calibration
<!-- OPENWC_CLAIM:M00-QAR-COORD-CALIBRATION-001:sindo-main-codex:2026-07-13 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-COORD-CALIBRATION-001:dfc1031 -->
## Ownership
@@ -0,0 +1,79 @@
# M00-QAR-FINAL-PAIRED-EVIDENCE-001 — Final paired evidence audit
<!-- OPENWC_CLAIM:M00-QAR-FINAL-PAIRED-EVIDENCE-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-FINAL-PAIRED-EVIDENCE-001:239cb24 -->
## Ownership
- Target: M00
- Program: QAR
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m00-final-paired-evidence`
- Lease expires UTC: 2026-07-14
- Integrator: milestone integrator
## Outcome
Produce one final WMO-ready paired report for all available build 12340 references and reconcile the remaining M00 acceptance gaps.
## Non-goals
- Achieving renderer parity inside M00.
- Calibrating unknown manual camera parameters.
- Marking the target DONE; only the milestone integrator may do so.
## Paths
- Exclusive: paired-run exit handling and final evidence record
- Shared/hotspots: renderer baseline/module findings
- Generated/ignored: final captures and reports under `user://`
## Contracts and data
- Public API/events: visual comparison exit 0/1 both count as completed report generation
- Schema/format version: unchanged
- Migration/compatibility: comparator infrastructure errors remain fatal
- Consumers: M00 integrator
## Dependencies
- Requires: merged region diagnostic and five private reference images
- Blocks: integrator decision on M00 completion
- External state: private images remain outside Git
## Verification
- Commands: complete paired baseline run, report audit, repository gates
- Fixtures: five build 12340 references
- Fidelity evidence: cold/warm comparison metrics and human gap classification
- Performance budget: existing M00 capture budgets
## Documentation deliverables
- Inline public API docs: PowerShell comparison step semantics
- Module specification: final evidence status
- Data-flow diagram: unchanged
- Sequence/state/dependency diagrams: unchanged
- Source map/status updates: baseline acceptance summary
## Simplicity and naming
- Important names introduced: `Invoke-GodotComparisonStep`
- Simplest considered solution: allow only comparator exit codes 0 and 1
- Rejected complexity/abstractions: suppressing all process failures
- Unavoidable complexity and justification: threshold exceedance is evidence, not infrastructure failure
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: paired-run exit contract fixed; full baseline and visual capture completed; ten pairs audited; final acceptance document written
- Next: integrator decides animated/sky reference policy and GUI RID-risk disposition
- Blocked by:
## Handoff
- Commit: this work-package commit
- Results: compared=10, failed=10, missing=0; mean error 0.066892..0.176952; cold/warm gaps stable; full workflow returned success with threshold evidence preserved
- Remaining risks: no build 12340 animated-M2 or sky-transition reference; GUI renderer RID/resources still reported at exit
- Documentation updated: `docs/M00_FINAL_PAIRED_EVIDENCE.md`, `docs/modules/world-renderer.md`
@@ -1,6 +1,7 @@
# M00-QAR-FOV-SWEEP-001 — Empirical camera FOV sweep
<!-- OPENWC_CLAIM:M00-QAR-FOV-SWEEP-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-FOV-SWEEP-001:f548507 -->
## Ownership
@@ -0,0 +1,79 @@
# M00-QAR-GUI-RID-SHUTDOWN-001 — GUI capture RID shutdown
<!-- OPENWC_CLAIM:M00-QAR-GUI-RID-SHUTDOWN-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-GUI-RID-SHUTDOWN-001:f19c0c4 -->
## Ownership
- Target: M00
- Program: QAR
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m00-gui-rid-shutdown`
- Lease expires UTC: 2026-07-15
- Integrator: milestone integrator
## Outcome
Identify ownership of GUI render-baseline shutdown leaks and apply the smallest regression-covered fix that lets queued world resources release before engine teardown.
## Non-goals
- Renderer architecture decomposition.
- Hiding or filtering Godot leak diagnostics.
- Changing M00 status, Evidence or `OPENWC_TARGET_DONE`.
## Paths
- Exclusive: capture shutdown sequencing and its regression diagnostic
- Shared/hotspots: `src/tools/capture_render_checkpoints.gd`, renderer module shutdown documentation
- Generated/ignored: GUI capture output and verbose logs under `user://`
## Contracts and data
- Public API/events: unchanged
- Schema/format version: unchanged
- Migration/compatibility: capture images and report schema remain unchanged
- Consumers: M00 baseline runner and milestone integrator
## Dependencies
- Requires: merged seven-reference evidence audit
- Blocks: integrator disposition of the final GUI renderer leak risk
- External state: proprietary references are not required for the focused shutdown regression
## Verification
- Commands: focused GUI single-checkpoint capture with verbose shutdown, headless project load, manifest/self-tests, repository gates
- Fixtures: existing non-proprietary render-baseline manifest and local extracted corpus
- Fidelity evidence: no visual behavior change; focused PNG hash/report remains valid
- Performance budget: shutdown-only change
## Documentation deliverables
- Inline public API docs: shutdown method semantics if introduced
- Module specification: shutdown ownership and observed leak status
- Data-flow diagram: unchanged
- Sequence/state/dependency diagrams: update shutdown sequence only if behavior changes
- Source map/status updates: capture tool if changed
## Simplicity and naming
- Important names introduced: `_release_runtime_caches_for_shutdown`, `_free_detached_node_cache`, `_queue_free_streamed_node`
- Simplest considered solution: explicitly release capture-owned scene references and drain deferred deletion
- Rejected complexity/abstractions: global RID registry or suppressed engine diagnostics
- Unavoidable complexity and justification: async streaming jobs must finish before resource ownership can drain
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: reproduced the focused leak; assigned detached prototype/resource caches and empty liquid roots to explicit owners; added a headless regression; verified zero Node/resource/RID leak lines in focused and seven-checkpoint GUI captures
- Next: integrator review and disposition of the residual engine-level zero-reference `RefCounted` diagnostic
- Blocked by:
## Handoff
- Commit: this work-package commit
- Results: before the fix the focused capture retained 6 mesh, 6 material, 4 shader, 6 texture, 6 instance and RenderingDevice RIDs (30 resources); after the fix focused and seven-checkpoint captures retained none
- Remaining risks: D3D12 descriptor fallback remains unrelated; Godot can report a timing-dependent anonymous `RefCounted` whose reference count is already zero, without retained Node/resource/RID ownership
- Documentation updated: `RENDER.md`, `docs/modules/world-renderer.md`, `docs/M00_FINAL_PAIRED_EVIDENCE.md`; existing renderer shutdown sequence updated, no new diagram required
@@ -0,0 +1,79 @@
# M00-QAR-INTEGRATOR-CLOSEOUT-001 — M00 milestone closeout
<!-- OPENWC_CLAIM:M00-QAR-INTEGRATOR-CLOSEOUT-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M00-QAR-INTEGRATOR-CLOSEOUT-001:ba81098 -->
## Ownership
- Target: M00
- Program: QAR
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m00-integrator-closeout`
- Lease expires UTC: 2026-07-15
- Integrator: sindo-main-codex, assigned by the user on 2026-07-13
## Outcome
Audit merged M00 work packages, refresh final Evidence, close the milestone and activate M01.
## Non-goals
- Change renderer behavior or compatibility claims.
- Start M01 implementation.
- Commit proprietary references or generated capture output.
## Paths
- Exclusive: M00/M01 target status and final M00 Evidence
- Shared/hotspots: `targets/README.md`, `targets/DEVELOPMENT_ROADMAP.md`, completed M00 claims
- Generated/ignored: `user://` post-merge reports
## Contracts and data
- Public API/events: unchanged
- Schema/format version: unchanged
- Migration/compatibility: none
- Consumers: milestone integrator and M01 work packages
## Dependencies
- Requires: merged M00 PRs #1 through #15 and final paired evidence
- Blocks: M01 activation
- External state: private reference images remain outside Git; their hashes and metrics are already recorded
## Verification
- Commands: post-merge render baseline dry-run, coordination gate, documentation gate
- Fixtures: seven-checkpoint non-proprietary manifest and recorded private-reference hashes/metrics
- Fidelity evidence: closeout preserves the explicit non-parity classification in `docs/M00_FINAL_PAIRED_EVIDENCE.md`
- Performance budget: no runtime change
## Documentation deliverables
- Inline public API docs: unchanged
- Module specification: unchanged
- Data-flow diagram: unchanged
- Sequence/state/dependency diagrams: unchanged
- Source map/status updates: target index, roadmap current state and M00 Evidence
## Simplicity and naming
- Important names introduced: none
- Simplest considered solution: status and Evidence-only integrator patch
- Rejected complexity/abstractions: new closeout tooling for a one-time milestone transition
- Unavoidable complexity and justification: none
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: verified all M00 PRs and merge commits, refreshed final Evidence, closed M00, activated M01 and passed transition gates
- Next: review and merge the closeout PR before starting an M01 implementation claim
- Blocked by:
## Handoff
- Commit: `ba81098`
- Results: exactly one ACTIVE target (M01); M00 DONE marker accepted; post-merge baseline, comparator self-test, coordination and documentation gates passed
- Remaining risks: documented renderer fidelity gaps and D3D12 fallback continue beyond M00
- Documentation updated: target status/index, development-roadmap current state and final M00 Evidence
@@ -1,6 +1,7 @@
# M00-QAR-LANDMARK-REGION-DIFF-001 — Landmark-region visual diff
<!-- OPENWC_CLAIM:M00-QAR-LANDMARK-REGION-DIFF-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-LANDMARK-REGION-DIFF-001:3d90c6d -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-TERRAIN-HEIGHT-001 — Terrain height diagnostic
<!-- OPENWC_CLAIM:M00-QAR-TERRAIN-HEIGHT-001:sindo-main-codex:2026-07-13 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-TERRAIN-HEIGHT-001:f8538ba -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-TILE-OWNERSHIP-001 — Waterfall terrain tile ownership
<!-- OPENWC_CLAIM:M00-QAR-TILE-OWNERSHIP-001:sindo-main-codex:2026-07-13 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-TILE-OWNERSHIP-001:2306200 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-VISUAL-DIFF-001 — Renderer checkpoint visual diff
<!-- OPENWC_CLAIM:M00-QAR-VISUAL-DIFF-001:sindo-main-codex:2026-07-13 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-VISUAL-DIFF-001:19df5b7 -->
## Ownership
@@ -1,6 +1,7 @@
# M00-QAR-WMO-READINESS-001 — Goldshire WMO readiness
<!-- OPENWC_CLAIM:M00-QAR-WMO-READINESS-001:sindo-main-codex:2026-07-14 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M00-QAR-WMO-READINESS-001:5092995 -->
## Ownership
+76
View File
@@ -0,0 +1,76 @@
# M00 Final Paired Evidence — 2026-07-13
## Scope and result
The final local M00 audit used Godot 4.6.1, the existing cache state, the manifest-standard 8-second readiness wait, and `2560x1440` visual candidates. Seven private WoW 3.3.5a build 12340 references produced fourteen cold/warm comparisons with no missing pair. Private images and generated reports remain outside Git.
Every pair exceeded the strict regression tolerance. Comparator exit code `1` means a valid report with measured visual gaps; only codes outside `0/1` are infrastructure failures. This evidence establishes coverage and current differences, not renderer parity.
```powershell
.\tools\run_render_baseline.ps1 `
-Output user://render_baseline_m00_complete_2026-07-13 `
-CacheState existing `
-WaitSeconds 8 `
-MeasureSeconds 0.5 `
-ReferenceCheckpointDirectory .\sources\OpenWCReferenceCheckpoints `
-VisualComparisonReport user://render_baseline_m00_complete_2026-07-13/visual_comparison.json `
-VisualComparisonWidth 2560 `
-VisualComparisonHeight 1440
```
The initial shell timeout detached the canonical capture process after it started. The process completed all fourteen canonical captures and wrote `report.json`; the documented visual-capture and comparator stages were then invoked separately with the same arguments. The final output directory contains both complete reports.
## Paired metrics
| Checkpoint | Pass | Mean perceptual error | Changed-pixel ratio | Classification |
|---|---|---:|---:|---|
| `elwynn_adt_boundary` | cold | 0.087258 | 0.634580 | Composition plus terrain/vegetation/material gaps |
| `elwynn_adt_boundary` | warm | 0.087255 | 0.634598 | Stable against revisit |
| `elwynn_sky_dusk` | cold | 0.094778 | 0.575956 | Approximate paired camera; sky color, lighting and scene-composition gaps |
| `elwynn_sky_dusk` | warm | 0.094757 | 0.575898 | Stable against revisit |
| `elwynn_terrain_overview` | cold | 0.174137 | 0.851791 | Largest composition/framing gap |
| `elwynn_terrain_overview` | warm | 0.176955 | 0.861271 | Stable gap, not a cold-load artifact |
| `elwynn_waterfall_liquid` | cold | 0.088629 | 0.706522 | Framing, terrain, liquid and lighting gaps |
| `elwynn_waterfall_liquid` | warm | 0.087398 | 0.693690 | Stable against revisit |
| `goldshire_dense_m2` | cold | 0.066893 | 0.575257 | Smallest available paired gap; vegetation/material differences remain |
| `goldshire_dense_m2` | warm | 0.066927 | 0.575592 | Stable against revisit |
| `goldshire_inn_large_wmo` | cold | 0.101224 | 0.701835 | WMO is ready; manual framing and presentation gaps remain |
| `goldshire_inn_large_wmo` | warm | 0.101206 | 0.701855 | Stable against revisit |
| `gryphon_roost_native_animation` | cold | 0.119467 | 0.882073 | Same build-12340 asset, different real/synthetic placement and uncontrolled animation phase |
| `gryphon_roost_native_animation` | warm | 0.119471 | 0.882076 | Full-frame metric is diagnostic only; animation observation is human evidence |
Cold and warm values are close for all seven references. The measured gaps are therefore not explained by first-visit cache readiness. Goldshire timing evidence separately demonstrated that the 8-second wait is necessary for WMO publication.
## Animation and sky provenance
The private source corpus preserves exact screenshot bytes; no resize, crop or generated content was used:
| Evidence | SHA-256 | Interpretation |
|---|---|---|
| `elwynn_sky_dusk.jpg` | `1fb06836cacae714c76eaf9b8bf7c292fd5e2f2df33eef821bfe4c4a6bd97072` | Build 12340, Elwynn camera position, server time approximately 19:00, UI hidden |
| `gryphon_roost_native_animation.jpg` | `d3488c741cb8dfe7212198e48332842631a951862a4388b67045338f37357447` | Build 12340 real-world `GryphonRoost01` placement, first visible wing phase |
| diagnostic animation phase B | `1025572c7ab9fa0d2e500ff026be46eb9c1e6e5447116dbdc3675dd5f44574ab` | Same camera three seconds later; visibly raised wing phase |
| diagnostic placement context | `b12c0b713a7d75123ed30f5a316b33537331442cd56615aea69214c7cc4e7a42` | Two real Lakeshire placements and surrounding build-12340 scene |
An ADT scan found no `GryphonRoost01` placement in Goldshire. The M00 checkpoint deliberately injects the model there as a synthetic probe. The original-client observation therefore uses two real Lakeshire placements. The three-second pose change establishes `Observed` native animation behavior, but the full-frame comparison cannot establish spatial or animation-phase parity.
## Fidelity interpretation
M00 now has private build 12340 evidence for every required coverage category: terrain, ADT boundary, dense M2, large WMO, liquid, animated M2 and sky transition. The sky reference is approximately paired by map position/time and manually approved composition. Animated-M2 evidence is asset-paired but placement-unpaired because the OpenWC probe is synthetic.
The reports demonstrate current differences and do not claim `1:1`. Camera calibration experiments also show that unknown manual yaw/pitch/FOV cannot be recovered reliably from full-frame color error alone. Region scoring reduces terrain bias but still requires semantic landmark approval.
## Operational risks
A follow-up shutdown ownership fix removed the GUI renderer leaks found by the final visual capture. Before the fix, the focused animated-M2 checkpoint retained 6 mesh, 6 material, 4 shader, 6 texture, 6 instance and associated RenderingDevice RIDs, for 30 resources in use. After the fix, both the focused 8-second capture and a seven-checkpoint single-pass capture completed without Node, resource or RID leak diagnostics.
Godot can still emit a timing-dependent ObjectDB warning for one or more anonymous `RefCounted` objects whose reported reference count is already zero. The warning has no retained Node, renderer resource or RID ownership in the verified captures. It remains recorded as an engine-teardown diagnostic rather than being hidden, but it is distinct from the resolved GUI renderer leak.
## Integrator decision checklist
- Seven required reference checkpoints: cold/warm report complete, `compared=14`, `missing=0`.
- Animated M2: build-12340 native motion observed in two phases; synthetic/real placement mismatch explicitly classified.
- Sky transition: build-12340 19:00 evidence present with approximate paired camera and human-approved composition.
- Renderer visual differences: registered as gaps, not parity claims.
- GUI renderer RID/resource diagnostics: resolved by explicit shutdown ownership and covered by a headless regression verifier; the residual zero-reference `RefCounted` engine-teardown warning remains tracked separately.
- Target status, target Evidence and `OPENWC_TARGET_DONE` marker: integrator-only actions.
+10 -4
View File
@@ -143,7 +143,8 @@ sequenceDiagram
Stream->>Render: evict outside retention range
Stream->>Worker: shutdown: wait for WorkerThreadPool tasks
Stream->>Stream: shutdown: finish registered ResourceLoader requests
Stream->>Render: clear queues, nodes, caches and RIDs
Stream->>Render: clear queues and owned tree nodes/RIDs
Stream->>Stream: free detached prototypes and release resource caches
```
## Ownership, threading and resources
@@ -153,6 +154,8 @@ sequenceDiagram
- Parsed/grouped results передаются обратно через guarded result queues.
- Mesh/material/node/RID finalization выполняется main thread и ограничивается exported budgets.
- Shutdown/map switch обязан дождаться WorkerThreadPool jobs и зарегистрированных threaded ResourceLoader requests до очистки очередей, nodes, caches и RIDs.
- Parented streamed nodes остаются owned by SceneTree during shutdown; detached M2/WMO prototype caches are explicitly `free()`d after asynchronous work drains.
- A temporary liquid root with no generated child geometry is explicitly freed by `ADTBuilder` instead of being returned or abandoned.
- Cache resources считаются immutable после публикации.
## Errors, cancellation and recovery
@@ -165,7 +168,7 @@ sequenceDiagram
| Main-thread hitch | Named section timing | Frame spike, work remains queued | `HITCH` log | Lower budget/fix finalize path |
| D3D12 descriptor exhaustion | Rendering backend error | Render failure/fallback backend | Godot error + baseline report | Dedup resources/fix settings |
| Teleport/map change | Focus/session transition | Old jobs become stale | Target/session generation | Cancel/drop stale results |
| Shutdown leak | Godot leak/RID diagnostics | Resource retained | Verbose shutdown report | Drain owned worker and resource requests before clearing registries |
| Shutdown leak | Godot leak/RID diagnostics | Resource retained | Verbose shutdown report + cache shutdown verifier | Drain requests, preserve tree ownership, then free detached prototypes and clear resource caches |
## Configuration and capabilities
@@ -197,7 +200,7 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
- Unit/contract tests: material mapping, unique-ID dedupe, placement probes, baseline manifest, five-point coordinate calibration, synthetic perceptual checkpoint diff, camera-pose grid plan.
- Integration/E2E: Eastern Kingdoms/Kalimdor streaming scenes and seven cold/warm checkpoints.
- Fidelity evidence: пять локальных build 12340 reference JPG откалибровали terrain/ADT/M2/WMO/liquid viewpoints; automated paired-image metrics exist, но synthetic animation/dusk и полный human approval ещё не закрыты.
- Fidelity evidence: семь локальных build 12340 reference JPG покрывают terrain/ADT/M2/WMO/liquid/sky и реальный `GryphonRoost01`; automated cold/warm metrics имеют `compared=14`, `missing=0`. Sky использует приблизительно paired camera, а animated-M2 остаётся asset-paired/placement-unpaired из-за synthetic probe.
- Performance budgets: M00 report records cold/warm p95 and max hitch; no final acceptance threshold yet.
- Manual diagnostics: [`../RENDER_BASELINE.md`](../RENDER_BASELINE.md) and [`../../RENDER.md`](../../RENDER.md).
@@ -234,7 +237,8 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
- A ready-scene Goldshire 3x3 grid improved mean error from `0.101402` at zero offsets to `0.087952` at yaw `10`/pitch `-10`; pitch/FOV refinement remains required before manifest calibration.
- Joint Goldshire pitch/FOV refinement had no human-approved optimum: full-frame error preferred grass-heavy FOV 62/pitch -25, while FOV 38/pitch -10 better matched building scale. Landmark/region scoring is required before calibration.
- Common-region scoring `[300,100,1400,650]` moved Goldshire's numeric optimum to FOV 38/yaw 10/pitch -15, but human inspection still found an oversized/cropped facade; semantic landmarks or masks remain required.
- D3D12 descriptor issues remain; the capture-path anonymous `RefCounted` shutdown leak is regression-covered by a clean verbose dry-run, while other RID/resource diagnostics still require independent evidence.
- Final paired audit compared fourteen cold/warm images for seven private build 12340 references with zero missing pairs; mean error ranges `0.066893..0.176955`. Animated-M2 native motion is observed across two original-client phases, but its real Lakeshire placement differs from the synthetic Goldshire probe. Sky-transition evidence uses the checkpoint map position/time with manually approved approximate framing.
- D3D12 descriptor issues remain. Explicit shutdown ownership removes the GUI capture's Node/resource/RID leaks in focused and seven-checkpoint runs; a timing-dependent ObjectDB warning for anonymous zero-reference `RefCounted` objects remains as a separate engine-teardown diagnostic.
- M2/WMO/material/particle/ribbon/portal parity incomplete.
- Public API is mostly exported configuration rather than stable contracts.
@@ -252,6 +256,7 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
| `src/tools/build_*cache.gd`, `src/tools/bake_*cache.gd` | Offline cache generation |
| `tools/run_render_baseline.ps1` | Unified M00 baseline runner |
| `src/tools/compare_render_checkpoints.gd` | Offline JPG/PNG paired-image perceptual metrics and JSON pass/fail report |
| `src/tools/verify_render_runtime_cache_shutdown.gd` | Headless ownership regression for detached runtime prototypes, resource caches and empty liquid roots |
| `src/tools/capture_render_checkpoints.gd` | Deterministic no-roll checkpoint camera, performance and visual capture |
| `tools/sweep_render_checkpoint_camera_pose.ps1` | Offline yaw/pitch capture grid and paired-error ranking |
| `src/tools/verify_render_coordinate_calibration.gd` | Build 12340 camera-coordinate golden point round-trip diagnostic |
@@ -263,5 +268,6 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
- [`../../RENDER.md`](../../RENDER.md)
- [`../RENDER_BASELINE.md`](../RENDER_BASELINE.md)
- [`../CAMERA_POSE_SWEEP.md`](../CAMERA_POSE_SWEEP.md)
- [`../M00_FINAL_PAIRED_EVIDENCE.md`](../M00_FINAL_PAIRED_EVIDENCE.md)
- [`../../targets/roadmap/02-rendering-and-graphics.md`](../../targets/roadmap/02-rendering-and-graphics.md)
- [`../GODOT_BEST_PRACTICES.md`](../GODOT_BEST_PRACTICES.md)
+52 -7
View File
@@ -374,6 +374,39 @@ func _exit_tree() -> void:
_shutting_down = true
_wait_for_tile_tasks()
_clear_streamed_world()
_release_runtime_caches_for_shutdown()
## Frees detached prototype nodes and releases render resources owned by this
## loader after all asynchronous work has completed. Map refreshes retain these
## caches; only scene shutdown destroys them.
func _release_runtime_caches_for_shutdown() -> void:
_free_detached_node_cache(_m2_scene_cache)
_free_detached_node_cache(_m2_animated_scene_cache)
_free_detached_node_cache(_wmo_prototype_cache)
_m2_mesh_cache.clear()
_m2_static_animation_cache.clear()
_m2_missing_cache.clear()
_wmo_render_cache.clear()
_wmo_scene_resource_cache.clear()
_wmo_render_missing_cache.clear()
_wmo_scene_cache_missing.clear()
_wmo_missing_cache.clear()
_shared_tex_cache.clear()
func _free_detached_node_cache(node_cache: Dictionary) -> void:
for cached_value in node_cache.values():
if not (cached_value is Node):
continue
var cached_node := cached_value as Node
if not is_instance_valid(cached_node):
continue
if cached_node.is_inside_tree():
cached_node.queue_free()
else:
cached_node.free()
node_cache.clear()
func _apply_quality_preset() -> void:
@@ -2781,15 +2814,27 @@ func _clear_streamed_world() -> void:
_free_render_instance(chunk_rid)
var tile_root: Node = state.get("root", null)
if tile_root:
tile_root.queue_free()
_queue_free_streamed_node(tile_root)
_tile_states.clear()
_clear_tile_mesh_cache()
_clear_quality_terrain_mesh_cache()
_clear_wmo_registry()
_ensure_world_wmo_root()
if enable_wmo:
_place_global_wmo()
if not _shutting_down:
_ensure_world_wmo_root()
if enable_wmo:
_place_global_wmo()
## During world shutdown, parented nodes are recursively owned by the world
## root. Queueing them separately from `_exit_tree()` can detach them from that
## deletion and leave empty Node objects alive at engine teardown.
func _queue_free_streamed_node(node: Node) -> void:
if node == null or not is_instance_valid(node):
return
if _shutting_down and node.is_inside_tree():
return
node.queue_free()
func _reset_terrain_root_children() -> void:
@@ -3889,10 +3934,10 @@ func _clear_wmo_registry() -> void:
var entry: Dictionary = entry_variant
var node: Node = entry.get("node", null)
if node and is_instance_valid(node):
node.queue_free()
_queue_free_streamed_node(node)
_wmo_registry.clear()
if _world_wmo_root and is_instance_valid(_world_wmo_root):
_world_wmo_root.queue_free()
_queue_free_streamed_node(_world_wmo_root)
_world_wmo_root = null
@@ -4458,7 +4503,7 @@ func _cancel_m2_build_job(key: String) -> void:
var job: Dictionary = _m2_build_jobs[key]
var root: Node = job.get("root", null)
if root != null and is_instance_valid(root):
root.queue_free()
_queue_free_streamed_node(root)
_m2_build_jobs.erase(key)
@@ -0,0 +1,77 @@
extends SceneTree
const STREAMING_WORLD_LOADER := preload("res://src/scenes/streaming/streaming_world_loader.gd")
const ADT_BUILDER := preload("res://addons/mpq_extractor/loaders/adt_builder.gd")
var _failures := 0
func _initialize() -> void:
_verify_empty_water_root_ownership()
_verify_runtime_cache_ownership()
if _failures > 0:
push_error("Render runtime cache shutdown verification failed: %d issue(s)" % _failures)
quit(1)
return
print("Render runtime cache shutdown verification passed.")
quit(0)
func _verify_empty_water_root_ownership() -> void:
var node_count_before := int(Performance.get_monitor(Performance.OBJECT_NODE_COUNT))
var empty_water_root: Node3D = ADT_BUILDER.build_tile_water_scene({"chunks": []}, Vector3.ZERO)
var node_count_after := int(Performance.get_monitor(Performance.OBJECT_NODE_COUNT))
_expect(empty_water_root == null, "empty ADT liquid payload should not produce a water root")
_expect(node_count_after == node_count_before, "empty ADT liquid payload should release its temporary water root")
func _verify_runtime_cache_ownership() -> void:
var loader: Node = STREAMING_WORLD_LOADER.new()
var static_m2_prototype := Node3D.new()
var animated_m2_prototype := Node3D.new()
var wmo_prototype := Node3D.new()
loader.set("_m2_scene_cache", {"static": static_m2_prototype})
loader.set("_m2_animated_scene_cache", {"animated": animated_m2_prototype})
loader.set("_wmo_prototype_cache", {"wmo": wmo_prototype})
loader.set("_m2_mesh_cache", {"mesh": ArrayMesh.new()})
loader.set("_m2_static_animation_cache", {"static": true})
loader.set("_m2_missing_cache", {"missing": true})
loader.set("_wmo_render_cache", {"render": Resource.new()})
loader.set("_wmo_scene_resource_cache", {"scene": PackedScene.new()})
loader.set("_wmo_render_missing_cache", {"missing": true})
loader.set("_wmo_scene_cache_missing", {"missing": true})
loader.set("_wmo_missing_cache", {"missing": true})
loader.set("_shared_tex_cache", {"texture": ImageTexture.new()})
loader.call("_release_runtime_caches_for_shutdown")
_expect(not is_instance_valid(static_m2_prototype), "static M2 prototype should be freed")
_expect(not is_instance_valid(animated_m2_prototype), "animated M2 prototype should be freed")
_expect(not is_instance_valid(wmo_prototype), "WMO prototype should be freed")
for cache_name in [
"_m2_scene_cache",
"_m2_animated_scene_cache",
"_wmo_prototype_cache",
"_m2_mesh_cache",
"_m2_static_animation_cache",
"_m2_missing_cache",
"_wmo_render_cache",
"_wmo_scene_resource_cache",
"_wmo_render_missing_cache",
"_wmo_scene_cache_missing",
"_wmo_missing_cache",
"_shared_tex_cache",
]:
var cache: Dictionary = loader.get(cache_name)
_expect(cache.is_empty(), "%s should be empty after shutdown" % cache_name)
loader.free()
func _expect(condition: bool, message: String) -> void:
if condition:
return
_failures += 1
push_error(message)
+9 -8
View File
@@ -1,6 +1,7 @@
# M00 — Renderer Baseline
<!-- OPENWC_TARGET:ACTIVE -->
<!-- OPENWC_TARGET:DONE -->
<!-- OPENWC_TARGET_DONE:M00:work/sindo-main-codex/m00-integrator-closeout:2026-07-13 -->
## Outcome
@@ -38,10 +39,10 @@ godot --headless --path . --script res://src/tools/capture_render_checkpoints.gd
## Evidence
- Date: 2026-07-10
- Revision/worktree: `93bfe11` + worktree baseline changes.
- Commands: `.\tools\run_render_baseline.ps1 -DryRun -WaitSeconds 0.1 -MeasureSeconds 0.1 -Output user://render_baseline_runner_test`; `.\tools\run_render_baseline.ps1 -Output user://render_baseline_m00_2026-07-10 -CacheState existing`.
- Results: headless load, renderer material smoke, M2 unique-id dedupe and manifest contract passed. Full run produced 14 PNGs and 14 result records for 7 cold/warm checkpoints. Actual renderer was Godot 4.6.1, Vulkan Forward+, NVIDIA RTX 5070, 1280x900, High profile, with all seven cache families present. Cold p95 range was 31.585..86.537 ms with max hitch 258.456 ms; warm p95 range was 18.824..38.085 ms with max hitch 163.363 ms. The final streaming snapshots had an empty tile queue. Report: `user://render_baseline_m00_2026-07-10/report.json`.
- Fidelity comparison: fixed positions/time/profile and current visual gaps are recorded, but no approved paired screenshots from the original WoW 3.3.5a build 12340 were available. This baseline does not claim parity.
- Changed files: `RENDER.md`, `docs/RENDER_BASELINE.md`, `src/scenes/streaming/streaming_world_loader.gd`, `src/tools/capture_render_checkpoints.gd`, `src/tools/render_baseline_manifest.json`, `src/tools/verify_render_baseline_manifest.gd`, `tools/run_render_baseline.ps1`, `targets/00-render-baseline.md`.
- Remaining risks: original-client paired comparison is still required before DONE; D3D12 descriptor heap creation failed and the measured run fell back to Vulkan; shutdown reported leaked renderer RIDs/resources; current captures intentionally preserve visible terrain/placement/material/animation gaps, including the synthetic native animated M2 probe; perceptual image diff/tolerance is documented but not automated yet.
- Date: 2026-07-13
- Revision/worktree: merged M00 implementation through `f19c0c4`; closeout worktree `work/sindo-main-codex/m00-integrator-closeout`.
- Commands: `.\tools\run_render_baseline.ps1 -Output user://render_baseline_m00_complete_2026-07-13 -CacheState existing -WaitSeconds 8 -MeasureSeconds 0.5 -ReferenceCheckpointDirectory .\sources\OpenWCReferenceCheckpoints -VisualComparisonReport user://render_baseline_m00_complete_2026-07-13/visual_comparison.json -VisualComparisonWidth 2560 -VisualComparisonHeight 1440`; `.\tools\run_render_baseline.ps1 -DryRun -WaitSeconds 0.1 -MeasureSeconds 0.1 -Output user://render_baseline_m00_post_merge`; `.\tools\verify_coordination.ps1`; `.\tools\verify_documentation.ps1`.
- Results: the final GUI run produced fourteen cold/warm captures for seven checkpoints and all seven required coverage categories, with `compared=14` and `missing=0`. The post-merge dry-run passed project load, material, M2 unique-id dedupe, runtime-cache shutdown, manifest and five-point coordinate calibration checks. Coordination and documentation gates passed. Renderer shutdown follow-up removed retained Node/resource/RID diagnostics in focused and seven-checkpoint GUI runs.
- Fidelity comparison: private original-client WoW 3.3.5a build 12340 references cover terrain, ADT boundary, dense M2, large WMO, liquid, animated M2 and sky transition. Every measured pair exceeds the strict visual tolerance and is recorded as a current gap rather than parity. Sky framing is approximately paired; animated M2 is asset-paired but placement-unpaired because the OpenWC Goldshire probe is synthetic. Full metrics and provenance are recorded in `docs/M00_FINAL_PAIRED_EVIDENCE.md`.
- Changed files: `RENDER.md`, `docs/RENDER_BASELINE.md`, `docs/M00_FINAL_PAIRED_EVIDENCE.md`, `docs/modules/world-renderer.md`, renderer baseline scripts/verifiers, manifest/capture tooling, streaming shutdown ownership and M00 coordination claims.
- Remaining risks: renderer parity is not claimed; documented terrain/material/placement/animation/lighting/liquid/culling gaps remain future renderer work. D3D12 descriptor heap creation can fall back to Vulkan. Godot can emit a timing-dependent anonymous zero-reference `RefCounted` teardown warning without retained Node/resource/RID ownership.
+1 -1
View File
@@ -1,6 +1,6 @@
# M01 — Coordinates and Architecture Seams
<!-- OPENWC_TARGET:OPEN -->
<!-- OPENWC_TARGET:ACTIVE -->
## Outcome
+1 -1
View File
@@ -21,7 +21,7 @@ OpenWC должен предоставить четыре согласованн
- MPQ/BLP/ADT/WDT/M2/WMO native parsing и renderer vertical slice уже существуют.
- Runtime streaming, terrain quality, MultiMesh M2, WMO caches, liquids, sky и character experiments находятся в рабочем состоянии, но сосредоточены в крупных orchestration scripts.
- Renderer baseline M00 создан; до `DONE` не хватает paired comparison с оригинальным клиентом и закрытия известных diagnostic gaps.
- Renderer baseline M00 завершён: paired comparison с оригинальным клиентом записывает измеренные gaps без заявления parity, а обязательные diagnostic gaps закрыты или явно классифицированы. Текущая работа M01 вводит coordinate и architecture seams.
- Gameplay domain, network protocol, production UI/Lua, audio orchestration и server adapters в основном предстоит реализовать.
- Editor plugin пока решает extraction/preview задачи, но не является полноценной authoring platform.
+3 -3
View File
@@ -10,7 +10,7 @@
## Current target
`M00` — [00-render-baseline.md](00-render-baseline.md)
`M01` — [01-coordinates-and-seams.md](01-coordinates-and-seams.md)
Одновременно `ACTIVE` может быть только одна цель. Следующая цель становится `ACTIVE` после появления валидной `OPENWC_TARGET_DONE` метки у предыдущей.
@@ -33,8 +33,8 @@
| ID | Цель | Зависит от | Статус |
|---|---|---|---|
| M00 | [Renderer baseline](00-render-baseline.md) | — | ACTIVE |
| M01 | [Coordinates and architecture seams](01-coordinates-and-seams.md) | M00 | OPEN |
| M00 | [Renderer baseline](00-render-baseline.md) | — | DONE |
| M01 | [Coordinates and architecture seams](01-coordinates-and-seams.md) | M00 | ACTIVE |
| M02 | [Player decomposition](02-player-decomposition.md) | M01 | OPEN |
| M03 | [Renderer facade and extraction](03-renderer-facade.md) | M02 | OPEN |
| M04 | [Godot Editor shell](04-editor-shell.md) | M03 | OPEN |
+11 -1
View File
@@ -40,11 +40,21 @@ function Invoke-GodotStep {
}
}
function Invoke-GodotComparisonStep {
param([string]$Name, [string[]]$Arguments)
Write-Host "[$Name] $GodotPath $($Arguments -join ' ')"
$process = Start-Process -FilePath $GodotPath -ArgumentList $Arguments -NoNewWindow -Wait -PassThru
if ($process.ExitCode -notin @(0, 1)) {
throw "$Name failed with exit code $($process.ExitCode)"
}
}
Push-Location $repoRoot
try {
Invoke-GodotStep "project-load" @("--headless", "--path", ".", "--quit")
Invoke-GodotStep "render-materials" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_materials.gd")
Invoke-GodotStep "m2-unique-dedupe" @("--headless", "--path", ".", "--script", "res://src/tools/verify_m2_unique_dedupe.gd")
Invoke-GodotStep "runtime-cache-shutdown" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_runtime_cache_shutdown.gd")
Invoke-GodotStep "baseline-manifest" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_baseline_manifest.gd")
Invoke-GodotStep "coordinate-calibration" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_coordinate_calibration.gd")
@@ -80,7 +90,7 @@ try {
"--viewport-height", $VisualComparisonHeight.ToString()
)
Invoke-GodotStep "visual-capture" $visualCaptureArgs
Invoke-GodotStep "visual-comparison" @(
Invoke-GodotComparisonStep "visual-comparison" @(
"--headless", "--path", ".",
"--script", "res://src/tools/compare_render_checkpoints.gd",
"--",