Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
641 commits
Select commit Hold shift + click to select a range
54850e0
Merge prd617/runtime-fixes into prd617/integration
jonit-dev Oct 15, 2026
f86f01d
fix(renderer): the normal and velocity passes add nothing to the fram…
jonit-dev Oct 15, 2026
d4f791f
Merge prd617/post-bindings into prd617/integration
jonit-dev Oct 15, 2026
709c778
test(runtime-native): drop the unused ts-expect-error on the bundler …
jonit-dev Oct 15, 2026
a7db4f9
fix(abi): localToWorld and worldToLocal answer the vector they converted
jonit-dev Oct 15, 2026
49fef5b
feat(material): bind Material.colorWrite
jonit-dev Oct 15, 2026
37ed3ba
fix(three-native): BufferAttribute.updateRanges is a live array on th…
jonit-dev Oct 15, 2026
0eb8453
fix(native): a zero-parameter Fn builds per call on V8, as on Wasm an…
jonit-dev Oct 15, 2026
390c657
test(runtime-native): packed consumer installs resolve the cohort fro…
jonit-dev Oct 15, 2026
f77b1fe
fix(abi): Object3D.raycast exists on both back ends
jonit-dev Oct 15, 2026
25b98c6
test(abi): catalog_coverage allows the adapter's Object3D.raycast
jonit-dev Oct 15, 2026
43ff539
feat(native): bind DecalGeometry, setFromPoints and the examples/jsm …
jonit-dev Oct 15, 2026
64911ac
fix(native): a model's shared images ship in the native package and l…
jonit-dev Oct 15, 2026
fae99b4
fix(web-host): TN_POST_NORMAL_SKIPPED is a console log, not a console…
jonit-dev Oct 16, 2026
6d736a4
Merge prd617/runtime-fixes (37ed3ba4d) into prd617/integration
jonit-dev Oct 16, 2026
d2994b0
Merge branch 'prd617/post-bindings' into prd617/integration
jonit-dev Oct 16, 2026
4215b29
Merge branch 'prd617/runtime-fixes' into prd617/integration
jonit-dev Oct 16, 2026
1e8898d
chore(three-native): resync the native registry snapshot after the me…
jonit-dev Oct 16, 2026
4426e16
Revert "feat(examples): pin abyss-framework to the legacy engine"
jonit-dev Oct 16, 2026
144b972
fix(native): localToWorld answers its vector, and bind computeFrenetF…
jonit-dev Oct 16, 2026
95f4373
Merge remote-tracking branch 'origin/develop' into prd617/integration
jonit-dev Oct 16, 2026
9598fe2
docs(prd): file PRD-617, every template runs on the native engine
jonit-dev Oct 15, 2026
888ecd6
docs(prd): PRD-617 covers the eleven pinned templates
jonit-dev Oct 15, 2026
9abc4f1
docs(prd): PRD-617 blocks v1, native default stays (owner decision)
jonit-dev Oct 15, 2026
82154b5
chore: repair the lockfile after merging origin/develop
jonit-dev Oct 16, 2026
1c57737
docs(prd): PRD-573 records the owner decision, native stays the defau…
jonit-dev Oct 16, 2026
897fd24
chore: clear the lint errors and the typecheck error the branch merge…
jonit-dev Oct 16, 2026
55c32d1
chore(scripts): verify-one-template-desktop names the packed files in…
jonit-dev Oct 16, 2026
f7503f6
docs(verification): regenerate the native coverage record after the i…
jonit-dev Oct 16, 2026
c846430
fix(native): a playtest bridge call that answers undefined reaches th…
jonit-dev Oct 16, 2026
bfcdeac
chore(three-native): waive the new suppressions with reasons
jonit-dev Oct 16, 2026
e1ce0f9
fix(scripts): the golden path scaffold overrides the transitive cohor…
jonit-dev Oct 16, 2026
2170a03
fix(native): a playtest pointer or wheel the UI does not take reaches…
jonit-dev Oct 16, 2026
b4a4708
test(runtime-native): the iOS packaging check allows the engine playe…
jonit-dev Oct 16, 2026
854d44e
test(create-threenative): puzzle leaves the legacy-pin list and its t…
jonit-dev Oct 16, 2026
6aa48de
feat(three-native): toAttribute, ReadbackBuffer on Wasm, storage arra…
jonit-dev Oct 16, 2026
2688513
chore(three-native): publint gate, README row, source-only externals …
jonit-dev Oct 16, 2026
61a37fa
fix(release): the publish check knows the engine bundler resolves pla…
jonit-dev Oct 16, 2026
0c6247f
chore(examples): abyss-framework keeps a named temporary legacy pin w…
jonit-dev Oct 16, 2026
b7decc3
fix(playtest): the held applySetup hands back its confirmation, and t…
jonit-dev Oct 16, 2026
0d1a8b2
feat(templates): minimal and platformer run on the native engine
jonit-dev Oct 16, 2026
9d5ad56
merge prd617/integration into post-bindings
jonit-dev Oct 16, 2026
db06c71
test(scaffold): recompute the minimal and platformer tree hashes with…
jonit-dev Oct 16, 2026
80cf4c2
test(runtime-native): the V8 player pins BlendMode and the number-onl…
jonit-dev Oct 16, 2026
58bbab0
feat(runtime-native): Return, Break, Continue, log and deltaTime in T…
jonit-dev Oct 16, 2026
c37beda
Merge origin/develop into prd617/develop-merge
jonit-dev Oct 16, 2026
49f85f1
feat(runtime-native): what snow's GPUParticles3D needs from TSL and S…
jonit-dev Oct 16, 2026
b5753a9
WIP recovery(PR493): preserve unverified integration and Wasm packagi…
jonit-dev Oct 16, 2026
720ea50
WIP recovery(PR493): preserve unverified runtime and template decoder…
jonit-dev Oct 16, 2026
8d27e2c
WIP recovery(PR493): preserve unverified post-binding and template edits
jonit-dev Oct 16, 2026
071f82c
Merge branch 'prd617/post-bindings' into prd617/develop-merge
jonit-dev Oct 16, 2026
e4138f9
Merge recovered PR493 runtime work preserving decoder and wheel fixes
jonit-dev Oct 16, 2026
bd62964
Merge branch 'prd617/integration' into prd617/develop-merge
jonit-dev Oct 16, 2026
b4df9b3
fix(recovery): retain committed pointer and wheel behavior over super…
jonit-dev Oct 16, 2026
687729c
chore(recovery): refresh measured scaffold hashes and PRD617 status
jonit-dev Oct 16, 2026
470290a
chore(native): sync recovered Curve declaration and build checks
jonit-dev Oct 16, 2026
a221bfc
fix(three-native): identify browser node materials for cloth consumers
jonit-dev Oct 16, 2026
eae462f
fix(native): carry storage attributes and indices into fragments
jonit-dev Oct 16, 2026
5d67345
test(core): resolve native cloth catalog independently of working dir…
jonit-dev Oct 16, 2026
6bb4fba
fix(native): preserve typed uniform values through GPU uploads
jonit-dev Oct 16, 2026
7a63a92
fix(three-native): refresh reflected bounds and sprite node metadata
jonit-dev Oct 16, 2026
084f6ca
fix(native): preserve playtest pointer button transitions
jonit-dev Oct 16, 2026
1f3e679
fix(native): reuse storage bindings across graph lowering
jonit-dev Oct 16, 2026
118f2b2
test(native): retain traced UI overlay artifacts
jonit-dev Oct 16, 2026
ac57da7
fix(native): preserve camera conventions and buffer disposal lifetimes
jonit-dev Oct 16, 2026
944dc67
fix(native): retire disposed storage bindings safely
jonit-dev Oct 16, 2026
99e88c2
fix(web): preserve native attribute array edits by range
jonit-dev Oct 16, 2026
b584297
test(wasm): exercise per-call Fn graphs and scopes
jonit-dev Oct 16, 2026
048cb74
fix(coverage): include owned native engine qualification
jonit-dev Oct 16, 2026
36ded50
docs(prd617): record remaining starter and snow passes
jonit-dev Oct 16, 2026
947ad23
fix(coverage): distinguish binary inspections from executions
jonit-dev Oct 16, 2026
9e07f53
docs(coverage): refresh Linux legacy and owned engine proof
jonit-dev Oct 16, 2026
13b7733
perf(core): batch plain heightfield attribute writes
jonit-dev Oct 16, 2026
244e4d1
test: align recovered template contracts and record Snow validation
jonit-dev Oct 16, 2026
2392849
fix: measure streaming host turns through the yield seam
jonit-dev Oct 16, 2026
f2c4bf6
perf: test bounded Heightfield upload ranges
jonit-dev Oct 16, 2026
28eb709
revert: reject Heightfield ranges after paired tail regressions
jonit-dev Oct 16, 2026
371148c
fix: base starter quality fallback on completed work
jonit-dev Oct 16, 2026
a99e3f7
test: record starter quality source fingerprint
jonit-dev Oct 16, 2026
50d1592
fix(playtest): retain primary failure during cleanup
jonit-dev Oct 16, 2026
09359fc
fix(wasm): report completed GPU timing with source frames
jonit-dev Oct 16, 2026
113a734
docs: preserve native template recovery and Snow experiment results
jonit-dev Oct 16, 2026
c8a7b26
Fix deterministic native captures without advancing simulation
jonit-dev Oct 16, 2026
d6d04b9
fix(native): decode data: URLs in fetch and share the mystral link po…
jonit-dev Oct 16, 2026
08a63c4
fix(native): install a host Image so stock three.js SMAA loads its lo…
jonit-dev Oct 16, 2026
cd1ff45
docs(prd): PRD-617 records the native Image shim and stock-three SMAA…
jonit-dev Oct 16, 2026
8cec8d8
fix(native): split the Image load-token assignment for lint
jonit-dev Oct 16, 2026
af24f65
feat(playtest): perf --executable reports on-CPU time per frame
jonit-dev Oct 16, 2026
badba06
perf(core): heightfield refresh uploads only the rows it touched
jonit-dev Oct 16, 2026
bb5a77f
feat(native): offscreen PassNode on a separate scene, drawn where the…
jonit-dev Oct 16, 2026
c198e66
fix(templates): split starter quality policy under the render-file ca…
jonit-dev Oct 16, 2026
f34bd6a
fix(core): a missing WebGPU adapter fails boot with a readable TN_NO_…
jonit-dev Oct 16, 2026
3e65d6a
perf(playtest): report the busiest thread; PRD-617 AC-4 starter CPU
jonit-dev Oct 16, 2026
ad3d211
fix(three-native): web Wasm engine boots shooter, sailing, runner and…
jonit-dev Oct 16, 2026
8aefa64
docs(prd): PRD-617 AC-2 and AC-3 pass for the starter on desktop and web
jonit-dev Oct 16, 2026
21c984f
docs(prd): PRD-617 names the exact build behind the starter desktop e…
jonit-dev Oct 16, 2026
088d138
docs(prd): PRD-617 AC-1, the starter carries no legacy pin and bundle…
jonit-dev Oct 16, 2026
751cbc4
fix(three-native): the Wasm engine glTF loader hosts TN_discrete_lod
jonit-dev Oct 16, 2026
3ebec61
fix(core): LOD selection no longer calls Sphere.clone, which the engi…
jonit-dev Oct 16, 2026
4a707a8
fix(native): a post texture that moves no longer frees the bind group…
jonit-dev Oct 17, 2026
8079d37
fix(native): bounds of a skinned mesh read before the first frame can…
jonit-dev Oct 17, 2026
41e19a5
fix(native): a Fn result that ran statements lowers its statements on…
jonit-dev Oct 17, 2026
f73ccfe
fix(native): a material node that reads a post render-to-texture pass…
jonit-dev Oct 17, 2026
878de50
fix(native): screenSize reaches the vertex uniform block
jonit-dev Oct 17, 2026
796ee3e
fix(native): put the renderer.cpp bind-group hunks where they were wr…
jonit-dev Oct 17, 2026
f3eba20
feat(native): NodeMaterial.depthNode writes the fragment's depth
jonit-dev Oct 17, 2026
ff25677
fix(native): NodeMaterial.depthNode writes frag_depth on every mesh m…
jonit-dev Oct 17, 2026
04e74dc
perf(native): read the post-views stamp once per renderPrepared call
jonit-dev Oct 17, 2026
fc3de35
docs(prd): PRD-617 AC-6 evidence, rain parity on the Wasm engine
jonit-dev Oct 17, 2026
8316541
fix(wasm-host): stop drawing while two frames are still on the GPU, s…
jonit-dev Oct 17, 2026
58bd532
feat(create-threenative): rain runs on the native engine; its legacy …
jonit-dev Oct 17, 2026
9730115
test(create-threenative): rain's scaffold hash follows its deleted le…
jonit-dev Oct 17, 2026
54c2268
fix(native): TSL mat2 with four plain numbers is row-major, as three'…
jonit-dev Oct 17, 2026
7ec1bf0
docs(skills): add tempest-performance-loop
jonit-dev Oct 17, 2026
0b8f9a9
docs(skills): fold the Tempest campaign into native-performance-loop
jonit-dev Oct 17, 2026
1d9c193
test: follow the named TN_NO_RENDERER boot failure; waive the TSL Loo…
jonit-dev Oct 17, 2026
b7362aa
perf(runtime-native): a material's slots lower their shared nodes once
jonit-dev Oct 17, 2026
9c655bf
feat(runtime-native): the starter's LUT colour grade lowers on native
jonit-dev Oct 17, 2026
eb42aa7
fix(three-native): keep a uniform's update hook alive after the game …
jonit-dev Oct 17, 2026
7864ee1
fix(native): read a light target's matrixWorld as three does, never r…
jonit-dev Oct 17, 2026
044b979
fix(three-native): pass the rendering camera and scene to uniform upd…
jonit-dev Oct 17, 2026
f3d200a
feat(native): apply scene.fogNode, so the Wasm engine fogs as stock t…
jonit-dev Oct 17, 2026
3ada9cb
fix(runtime-native): continuous VSM invalidation rotates the level gr…
jonit-dev Oct 17, 2026
9da4048
fix(runtime-native): retain VSM casters beyond the source shadow camera
jonit-dev Oct 17, 2026
27beb34
fix(runtime-native): the V8 player's TSL extras receive vec4, so fog(…
jonit-dev Oct 17, 2026
aa0e6c1
fix(native): route scene fog nodes through the V8 shader bridge
jonit-dev Oct 17, 2026
b1ecdb5
fix(native): bridge NodeMaterial shader slots and material arguments
jonit-dev Oct 17, 2026
cd98f1d
ci(runtime-native): the shipped web Wasm engine has a 4 MiB size ceiling
jonit-dev Oct 17, 2026
fde750f
fix(racing): add the sun's target to the scene so the sun aims at the…
jonit-dev Oct 17, 2026
b1ec75b
fix(runtime-native): frame GPU time sums every pass, offscreen passes…
jonit-dev Oct 17, 2026
e894154
fix(three-native): registry snapshot names the Scene.fogNode getter
jonit-dev Oct 17, 2026
66b51e3
perf(native): the player always places its threads, no setting (PRD-610)
jonit-dev Oct 17, 2026
18ea321
Merge remote-tracking branch 'origin/develop' into prd617/integration
jonit-dev Oct 17, 2026
bf273db
perf(runtime-native): geometry upload sends the union of pending upda…
jonit-dev Oct 17, 2026
37bd190
fix(three-native): the catalog publishes Scene.fogNode, as the regist…
jonit-dev Oct 17, 2026
8494d6c
feat(profile): absolute long-frame counts and per-presented-frame Web…
jonit-dev Oct 17, 2026
80d95b7
fix(core): the frame budget counts frames the renderer declined to draw
jonit-dev Oct 17, 2026
283a3aa
feat(midway-bench): pass-ms.mjs times every GPU pass at the WebGPU AP…
jonit-dev Oct 17, 2026
b57a4df
fix(runtime-native): a full GPU timer stream refuses the sample inste…
jonit-dev Oct 17, 2026
9d6edf0
perf(three-native): a flag write of the value the flag holds stays ou…
jonit-dev Oct 17, 2026
9e522b2
perf(three-native): a handle crosses the bridge as three stores, not …
jonit-dev Oct 17, 2026
4517b9d
Merge commit '18ea321f6' into perf/snow-update-range
jonit-dev Oct 17, 2026
81b09e4
fix(playtest): perf --executable runs the host on the display it reports
jonit-dev Oct 17, 2026
12127fc
test: three unit reds from the PR #493 dispatch run (39054619343)
jonit-dev Oct 17, 2026
29616f1
ci: build what the native default needs in three jobs that missed it
jonit-dev Oct 17, 2026
7f069d0
fix(playtest): perf --executable stops the host's whole process group
jonit-dev Oct 17, 2026
6f3cf32
feat(config)!: engine values are "threenative" and "threejs"
jonit-dev Oct 17, 2026
871b760
ci: engine parity guard in every template leg
jonit-dev Oct 17, 2026
c7dc5c0
fix(three-native): a hot update can build a new Wasm renderer once th…
jonit-dev Oct 17, 2026
391dccc
ci(native-platforms): legacy-host proofs name engine: legacy; the sta…
jonit-dev Oct 17, 2026
d37fdbe
ci(native-platforms): use the renamed engine values in the new pins
jonit-dev Oct 17, 2026
310d6e4
fix(playtest): a driven advance draws a world frame only when the cal…
jonit-dev Oct 17, 2026
a264cc4
ci(native-release): the three scaffold callers name the Three.js engine
jonit-dev Oct 17, 2026
c2ea441
test(runtime-native): the UI frame gate matches the page colour withi…
jonit-dev Oct 17, 2026
ec78a74
fix(ci): the engine parity guard re-exports the template config and w…
jonit-dev Oct 18, 2026
4d1b78e
style(three-native): format the renderer-replacement spec
jonit-dev Oct 18, 2026
fc56ef2
fix(runtime-native): a lit mesh whose geometry has no normal attribut…
jonit-dev Oct 18, 2026
5bb12e5
fix(action-rpg): the attack arc's launch cone no longer builds a NaN …
jonit-dev Oct 18, 2026
4d93252
ci: the engine parity guard has no known gaps left
jonit-dev Oct 18, 2026
6160fe5
ci: the native-engine job installs the workspace before it runs ctest
jonit-dev Oct 18, 2026
08dbbbc
ci(native-platforms): the arm64 paired-host reconfigure keeps the phy…
jonit-dev Oct 18, 2026
666f1f0
feat(three-native): the Wasm and V8 engines answer AnimationMixer.stats
jonit-dev Oct 18, 2026
df69ae1
fix(abyss-framework): pin the example to the legacy engine until the …
jonit-dev Oct 18, 2026
1e923b7
merge: reconcile develop interpolation and retained targets for PR493
jonit-dev Oct 18, 2026
6c00fdd
merge: bring develop CI admission improvements into PR493
jonit-dev Oct 18, 2026
22f2b76
merge: integrate PR493 CI repairs and live animation stats
jonit-dev Oct 18, 2026
545c51a
test: refresh native coverage after develop integration
jonit-dev Oct 18, 2026
2e3efec
fix(renderer): preserve native surface resolution fallback
jonit-dev Oct 18, 2026
a58e4df
docs(prd): record merge repair validation and remaining gates
jonit-dev Oct 18, 2026
1efb358
fix(render): reserve quantized bloom mip capacity
jonit-dev Oct 18, 2026
b287006
Fix native animation tests on Wasm32
jonit-dev Oct 18, 2026
fa21251
fix(native): match Three.js missing-normal fallback
jonit-dev Oct 18, 2026
eeb5baf
fix native retained target subrect capability
jonit-dev Oct 18, 2026
14ac415
docs: record CI and Sailing repair evidence
jonit-dev Oct 18, 2026
37f035b
test native screenshot fixture readiness
jonit-dev Oct 18, 2026
d919fa6
docs: record controlled sailing ocean visual verdict
jonit-dev Oct 18, 2026
ce6ca37
fix(sailing): interpolate hull and rig from the current swell pose
jonit-dev Oct 18, 2026
8414e32
fix(native): bind normal maps per draw and reject validation errors
jonit-dev Oct 18, 2026
77c9cd2
test(sailing): refresh scaffold fingerprint for interpolation repair
jonit-dev Oct 18, 2026
2cae04e
test(sailing): supply interpolation in scene fixtures
jonit-dev Oct 18, 2026
b1281c1
fix(native): retain shader compiler failure diagnostics
jonit-dev Oct 18, 2026
c5f78ae
fix(playtest): retain custom capture startup failures
jonit-dev Oct 18, 2026
b2ea84d
docs(three-native): include package release documentation
jonit-dev Oct 18, 2026
7d152ab
test(sailing): detect rendered hull jitter during qualification
jonit-dev Oct 18, 2026
1cb8d8e
fix(playtest): retain startup observations on readiness failure
jonit-dev Oct 18, 2026
9a82299
fix(parity): compare observed poses without framework overlay
jonit-dev Oct 18, 2026
7815900
fix(sailing): reconcile ocean readbacks without hull jolts
jonit-dev Oct 18, 2026
15041bd
fix(native): retain budgeted terrain construction and refilters
jonit-dev Oct 18, 2026
a1d617f
chore(release): prepare unused package cohort and scaffold pins
jonit-dev Oct 18, 2026
0591caf
fix(native): exclude disabled MetaHuman sanitizer target
jonit-dev Oct 18, 2026
728f6e8
fix(native): release cached V8 undefined handle on shutdown
jonit-dev Oct 18, 2026
599b396
fix(test): forward the documented conformance dry-run budget
jonit-dev Oct 18, 2026
048bf36
fix(scaffold): keep Sailing instructions within the line budget
jonit-dev Oct 18, 2026
1c7ee8a
fix(test): snapshot native binding sources once per lookup
jonit-dev Oct 18, 2026
96d0f59
fix(native): drain owned WebGPU references safely
jonit-dev Oct 18, 2026
ad3226e
fix(native): align loop and admission conformance with source
jonit-dev Oct 18, 2026
691c9ae
test(native): run NaN alpha regression in registered loop case
jonit-dev Oct 18, 2026
b6c8139
test(release): refresh current native coverage proof
jonit-dev Oct 18, 2026
5cb2a22
fix(sailing): initialize chase camera without startup shake
jonit-dev Oct 18, 2026
a0d3c10
fix: synchronize replay release pin and stabilize device timeout test
jonit-dev Oct 18, 2026
8fff669
fix: use explicit SMAA edge mip for FXC and trace native projection p…
jonit-dev Oct 18, 2026
68dbfc7
test: refresh measured scaffold trees for SMAA patch
jonit-dev Oct 18, 2026
45ebc88
fix: synchronize SMAA patch hash for frozen installs
jonit-dev Oct 18, 2026
acf61d6
test: align SMAA builder typing with root typecheck
jonit-dev Oct 18, 2026
0f12d7f
chore: refresh current native coverage after projection diagnostics
jonit-dev Oct 18, 2026
2852217
ci: target emulator and retain final adb logcat failure details
jonit-dev Oct 18, 2026
2761ef8
docs: retain fresh Sailing release performance blocker
jonit-dev Oct 18, 2026
a1b54f4
fix(parity): retain browser process logs for failed captures
jonit-dev Oct 18, 2026
5df46d6
docs(release): record completed Android qualification limits
jonit-dev Oct 18, 2026
2f2cebe
docs(release): qualify Windows and track published dependency repair
jonit-dev Oct 18, 2026
e967443
docs: record diagnostic qualification and upstream repair proof
jonit-dev Oct 18, 2026
a62f8c3
ci: retain bounded watchdog evidence for failed parity
jonit-dev Oct 18, 2026
8a4dbd7
ci: timestamp parity failure diagnostics for crash ordering
jonit-dev Oct 18, 2026
f6c62bb
docs: record completed release qualification blockers
jonit-dev Oct 18, 2026
2f52fff
docs: record controlled GPU watchdog reproductions
jonit-dev Oct 18, 2026
051e5aa
docs: record GPU timestamp counterfactual result
jonit-dev Oct 18, 2026
7284ecf
docs: retain failed parity affinity control
jonit-dev Oct 18, 2026
98a7343
docs: record PMREM watchdog isolation
jonit-dev Oct 18, 2026
7742510
Preserve parity observations when capture guards fail
jonit-dev Oct 18, 2026
596e93b
wip(PRD-624): frame-pumped native PMREM and async Three.js PMREM warm…
jonit-dev Oct 18, 2026
4e8d240
fix(native): bound PMREM pumping per frame by the costliest packet
jonit-dev Oct 18, 2026
d1f21db
Merge origin/develop into PR #493 release branch
jonit-dev Oct 18, 2026
bc64a25
Merge commit 'd1f21dbb4' into fix/pr493-ready
jonit-dev Oct 18, 2026
c82647d
test(native): check the clamped action time before stop() resets it
jonit-dev Oct 18, 2026
2c26124
fix(core): reach the PMREM preparer through pmremTexture, not a three…
jonit-dev Oct 18, 2026
0a42016
fix(core): group async PMREM face fences by GPU cost
jonit-dev Oct 18, 2026
2d2bed0
fix(native): keep the active PMREM bake across passes that do not sam…
jonit-dev Oct 18, 2026
826f3d9
test(parity): route engine-parity temp dirs through makeTempDir
jonit-dev Oct 18, 2026
b004ba6
chore(native): refresh the native coverage report for the current sou…
jonit-dev Oct 18, 2026
e5ec2c1
fix(core): prepare PMREMNode textures asynchronously on queue-fenced …
jonit-dev Oct 18, 2026
18eb7c5
fix(core): startup waits for the native engine's environment bake
jonit-dev Oct 18, 2026
fe493a0
fix(core): bound the native environment wait by the warm-up budget
jonit-dev Oct 18, 2026
266fba9
chore(native): refresh the native coverage report for the current sou…
jonit-dev Oct 18, 2026
5cbeade
docs(prd): PRD-624 resolves PR #493 against develop (1/7, prd:25%)
jonit-dev Oct 18, 2026
1699bf5
fix(native): broadcast texture retirements and wait for probe env bakes
jonit-dev Oct 18, 2026
870dfd5
fix(core): warm-up compiles on its own budget after the environment bake
jonit-dev Oct 18, 2026
2c83ba3
fix(native): a probe capture during an environment bake reports Pending
jonit-dev Oct 18, 2026
a81fa20
chore(native): refresh the native coverage report for the current sou…
jonit-dev Oct 18, 2026
a069e14
docs(prd): PRD-624 native PMREM ready before covered rendering (2/7);…
jonit-dev Oct 18, 2026
386e7fb
fix(core): raise threenative-sculpt-mcp to 0.2.2 for the SDK 1.31.0 t…
jonit-dev Oct 18, 2026
67717a5
fix(core): pin threenative-sculpt-mcp 0.2.2 in the MCP launch shim
jonit-dev Oct 18, 2026
3b3490d
docs(prd): PRD-624 dependency floor, frozen cohort and Sailing gate p…
jonit-dev Oct 18, 2026
0ea9b0a
style(create-threenative): format the recaptured sculpt MCP surface
jonit-dev Oct 18, 2026
c77a015
docs(prd): PRD-624 frozen cohort rechecked on final head 0ea9b0a3e
jonit-dev Oct 18, 2026
4e2c6df
fix(native): share pipeline caches with render-target siblings
jonit-dev Oct 18, 2026
2a6def6
docs(verification): refresh native coverage digest after the sibling …
jonit-dev Oct 19, 2026
1e9273e
fix(native): pace headless player frames to the simulation tick
jonit-dev Oct 19, 2026
470d469
fix(core): compile warm-up pipelines asynchronously
jonit-dev Oct 19, 2026
1a67605
fix(core): always issue the covered warm pass; bound only its wait
jonit-dev Oct 19, 2026
1c49a86
docs(verification): refresh native coverage digest after headless pacing
jonit-dev Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 10 additions & 1 deletion .agents/skills/native-performance-loop/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: native-performance-loop
description: Run an autonomous ThreeNative native-performance optimization loop using existing harnesses, quick synthetic load tests, and representative real games. Profile bottlenecks, make focused changes, accept or reject measured experiments, and maintain an HTML benchmark dashboard. Use for sustained native runtime optimization, frame pacing, startup, memory, or thermal efficiency campaigns.
description: Run an autonomous ThreeNative native-performance optimization loop using existing harnesses, quick synthetic load tests, and representative real games. Profile bottlenecks, make focused changes, accept or reject measured experiments, and maintain an HTML benchmark dashboard. Use for sustained native runtime optimization, frame pacing, startup, memory, or thermal efficiency campaigns, including the Tempest (rain) campaign where the web Wasm engine must beat stock three.js with the same image.
---

# Native performance loop
Expand Down Expand Up @@ -41,6 +41,15 @@ the developer to supervise each iteration. Creating or editing this skill does n
Keep separate goals for frame tails, startup, memory, and energy. Never optimize a blended
score that can conceal one game's regression. Run the unchanged baseline before editing.

## KPIs and named campaigns

- Score every campaign on [engine-kpis.md](references/engine-kpis.md) as well as on its primary
scalar. Keep a lever only if it moves at least one engine KPI and the sentinel game does not
regress. A lever that helps one game only is `provisional`.
- For the Tempest sample (the `rain` template, web Wasm engine against stock three), read
[tempest.md](references/tempest.md). It sets goals T1 to T3, the image-identity rule, the arms,
the capture recipe and the known state.

## The experiment loop

Repeat without asking for a new task after each result:
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/native-performance-loop/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
interface:
display_name: "Native Performance Loop"
short_description: "Optimize native games with measured keep/reject loops"
short_description: "Optimize native games and Tempest with measured keep/reject loops"
default_prompt: "Use $native-performance-loop to improve native game performance, choose representative workloads, keep verified gains, and maintain an HTML benchmark dashboard."
61 changes: 61 additions & 0 deletions .agents/skills/native-performance-loop/references/engine-kpis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Engine KPIs that pay in every game

These KPIs are the scoreboard of every campaign, whatever its workload. Each one measures an
engine cost that every game pays when it draws. A lever that moves one of them helps all
templates. A lever that moves only one game's frame time is suspect.

Record each KPI for both arms (the engine under test and its control, such as stock three on the
web or the incumbent build) at the frozen pose or route. Where a meter is
missing, add the smallest meter with a check as a separate harness change, then re-baseline. Do
not estimate a value.

## GPU (rank first when the game is GPU-bound)

| KPI | Definition | Target | Meter |
| --- | --- | --- | --- |
| G1 GPU cost ratio | Engine GPU ms ÷ control GPU ms (stock three on the web), same pose, size and tier | ≤ 1.0, then lower | playtest `assert.performance` window `gpuMs`, both arms |
| G2 Shader cost per material | Instructions, texture samples and loop trip counts in the emitted WGSL, against three's WGSL for the same node graph | ≤ three on every program | WGSL dump from both engines; diff per program |
| G3 Full-screen passes per frame | Passes that touch every pixel, plus MSAA resolves and target-to-target copies | ≤ three; 0 redundant copies | pass list from the render graph; Dawn capture if needed |
| G4 Render-target bytes | Sum of live color, depth and MSAA target memory | ≤ three | renderer target census |
| G5 Load/store waste | Clears and stores of targets that the next pass overwrites or never reads | 0 | pass descriptors (loadOp/storeOp) |

## CPU and the JS/Wasm boundary

| KPI | Definition | Target | Meter |
| --- | --- | --- | --- |
| C1 Render CPU ms | CPU time from `render()` entry to submit | ≤ three | window `cpuMs` |
| C2 Boundary calls per frame | JS→Wasm and Wasm→JS calls in one steady frame | falls as levers land | call counter in `packages/three-native` glue |
| C3 Steady GPU object churn | Bind groups, buffers, textures and pipelines created per steady frame | 0 | create counters in the renderer |
| C4 Upload bytes per frame | `writeBuffer`/`writeTexture` bytes in a steady frame | only data that changed | upload counter |

## Startup and hitches

| KPI | Definition | Target | Meter |
| --- | --- | --- | --- |
| S1 Pipeline count and compile time | Distinct render pipelines at the pose, and `compileMs` / `compileSettledMs` | ≤ three | `pipelineCensus`, compile fields |
| S2 First-use hitch | Worst frame in the first 5 s after the pose is ready | ≤ 2x budget | presented intervals after the ready mark |
| S3 Time to first frame | Navigation start to the first presented world frame | ≤ three | loading scenario marks |

## Pacing and memory

| KPI | Definition | Target | Meter |
| --- | --- | --- | --- |
| P1 Presented interval | p50, p95 and p99 of the real presented interval (not rAF and not fps) | p95 ≤ budget | presentation samples |
| P2 Frames in flight | Frames submitted and not yet complete | ≤ 2 (backpressure) | `framesOnGpu` in `web_host.cpp` |
| M1 Steady memory growth | JS heap and Wasm memory growth per minute at the pose | 0 after warmup | `performance.memory`, `WebAssembly.Memory` byte length |

## Guard KPIs (must not move)

| KPI | Definition | Limit |
| --- | --- | --- |
| V1 Visual parity | Mean absolute diff against the control at the pose, 0–255 | ≤ 0.01 and judge NEUTRAL or IMPROVEMENT |
| V2 Behavior | The workload's playtest set and the sentinel game's set | No new red |
| V3 Workload identity | Draw calls, triangles and active stages | Same as the baseline, unless the lever deletes provably redundant work and the judge passes |

## Reading the scoreboard

- Report each KPI as baseline, incumbent and absolute delta, with a percent only for a positive
baseline. Do not blend KPIs into one score.
- Show a KPI that is not yet metered as `unavailable: <reason>`.
- A drop in G3, G5, C3 or C4 with no GPU or CPU ms change is still a kept maintenance win only if
it is proven on the sentinel. Label it as such. Do not label it a speedup.
167 changes: 167 additions & 0 deletions .agents/skills/native-performance-loop/references/tempest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Tempest campaign

Read this file when the campaign workload is the Tempest sample: the `rain` template
(`packages/create-threenative/templates/rain`), drawn by the web Wasm engine against stock three.js.
Tempest is per-pixel heavy (a raymarched sky and clouds, a reflection pass, 4x MSAA, bloom and a
grade). It is the worst case for engine render cost, so a lever that pays here pays in every game
that draws full-screen passes, materials or render targets.

The skill's loop, acceptance rules and dashboard contract apply. This file adds only what differs.
The web lane is the primary lane here. That is an exception to the skill's native-first rule: the
Wasm engine is the engine under test on the web, and T3 carries the result to the native player.

## Contract

1. **Goal order.**
- **T1:** Wasm engine GPU ms is at or below stock three on the same pose, resolution and tier.
- **T2:** 60 fps on the reference GPU. GPU ms ≤ 16.7 and presented interval p95 ≤ 16.7 ms
at 1920x1080, `high` tier.
- **T3:** the same on the native desktop V8 player.

T1 comes first because it is an owner rule: native must beat JS.
2. **Primary scalar.** GPU ms per frame, median of steady windows, lower is better. Do not
use `fps` or `minFps` from the Wasm engine as the primary scalar. The rAF backpressure
(`tnw_web_frame(11)`, two frames on the GPU) skips renders, so both values overstate the engine.
Read CPU ms, GPU ms and the presented interval.
3. **Allowed edit surface.**
- Engine only: `packages/runtime-native/` (C++, WGSL codegen, the renderer, `web_host.cpp`) and
`packages/three-native/` (JS glue).
- The template's `src/render/` and `tools/tempest-*.frag` are the look. Do not change them
for speed. A template-side saving (cloud steps, reflection resolution, MSAA, bloom resolution)
is a measured *proposal* for the owner. It is not a kept lever.
- Do not patch three.js.
4. **Image identity.** The Wasm frame must match stock three on the pose (mean absolute diff
≤ 0.01 on 0–255, plus no region the judge marks as different). Every kept lever passes a fresh
read-only visual judge with BEFORE/AFTER captures and two runs per arm. Both engines are
deterministic run to run, so two runs show stability, not two independent samples.
5. **Generality gate.** A lever is kept only if it moves at least one KPI in
[engine-kpis.md](engine-kpis.md) and does not regress a second template (the sentinel). Use
`starter`, or a template whose bottleneck differs from Tempest. A lever that only helps
Tempest's shaders is `provisional`, never `keep`.

## Start or resume

1. Do the "Start or resume" steps of the skill. Use the campaign directory
`<primary>/artifacts/native-performance-loop/tempest-<date>/`. Copy `render.mjs` and
`check-render.mjs` from the newest campaign there instead of writing a renderer. Create
`index.html` before the first run.
2. Read the arms and lanes sections below for the arms, the capture recipe and the frozen pose.
Then read [engine-kpis.md](engine-kpis.md) and record a baseline for every KPI that has a meter.
Mark a KPI without a meter as `unavailable: <reason>`, never as zero.
3. Freeze: engine SHA, wasm hash, three version, template hash, pose, viewport 1920x1080, tier
`high`, warmup, sample windows, and the GPU identity (`TN_GPU_CLASS` nvidia/turing).
4. Run the unchanged pair (legacy arm and Wasm arm) at least three times, alternating order.
Set the noise margin from these runs before you write any code.

## Finding the next lever

Tempest cost is per pixel: at 960x540 both engines are about 3.5x faster than at 1080p. So rank
first by GPU work per frame, in this order:

1. **Pass attribution.** Get GPU ms per pass (scene, reflection, MSAA resolve, bloom chain, post)
on both engines. Use timestamp queries where the adapter grants them. Otherwise use ablation:
turn one stage off on *both* arms and diff the deltas. An ablation is diagnosis only and never
ships. The pass with the largest ours-minus-legacy delta is next.
2. **Codegen diff.** For that pass, dump the WGSL that each engine emits for the same node graph.
Compare instruction count, texture samples, loop bounds, precision and redundant work (a value
lowered twice, a constant recomputed per pixel, a branch that three folds and we do not).
3. **Target traffic.** Count render targets, resolves, copies, clears, load/store ops, formats and
sizes per frame against stock three.
4. **CPU and churn.** Do this only after the GPU gap closes, or when CPU ms exceeds GPU ms.

Record the predicted saving before you edit. Use one conceptual change per experiment. Each
behavior change needs a red/green unit test in `packages/runtime-native` (`ctest -R <case>`) or
`packages/three-native` (vitest). A performance number is not a red/green test.

## Confirm and decide

- Rebuild the web engine (`packages/runtime-native/build/web/tn-native-engine-web.wasm`). Install
it into a fresh Tempest scaffold. Verify that the served wasm is byte-identical to the build.
- Run at least three valid pairs, alternating legacy-first and Wasm-first. Run them against the
incumbent, and against legacy for the T1 ratio. An adapter other than turing, or exit 75 after
its retries, makes the pair `invalid`.
- Run the visual judge, then the sentinel template, then the rain playtest set (16 scenarios; the
known red is `lightning`/`thunderVoices` on both engines).
- Keep only if the median improvement clears the margin, the judge returns NEUTRAL or
IMPROVEMENT, the sentinel does not regress, and the tests are green. Commit each kept lever on
the campaign branch with its test.
- Every third experiment, rerun the original baseline pair to detect drift.

## Stop and report

Stop at the skill's stop conditions, or when engine levers stop paying. In that
case, report:

- the per-pass GPU table (ours and legacy);
- the remaining gap to T2;
- each template-side option with its measured saving and the judge's description of how the
image changes. Apply none of them.

Finish with the dashboard link, the KPI table (baseline, incumbent and delta per KPI), the
accepted and rejected counts, and one next action that someone can resume.

## Arms, lanes and frozen scenarios

Paths are relative to the owning ThreeNative checkout. Check the current CLI help before you use
a flag. These are routing pointers.

### Arms

| Arm | How to make it | What it proves |
| --- | --- | --- |
| Wasm engine (candidate) | Scaffold `rain` with the local framework. The default engine is native. | The engine under test |
| Legacy (control) | The same scaffold with `engine: "legacy"` in `threenative.config.ts` | Stock three.js WebGPURenderer on the same template revision |
| develop (optional) | Scaffold from `origin/develop` in its own worktree | A third view when the template itself changed |

Scaffold the same way that `scripts/verify-template-playtests.ts` does: `createProject({ install:
true, packageSources: await packageLocalFramework(root), target, template: "rain" })` from
`packages/create-threenative/src/index.js` and `scripts/visual-gate.js`. Use a fresh temporary
root for each arm. Serve each arm with `pnpm exec vite --host 127.0.0.1 --port <port>
--strictPort` from its project directory.

Confirm each arm by what it loads, not by its config. The Wasm arm imports the
`threenative:web-engine` module. The legacy arm imports `three_webgpu.js` from `.vite/deps`.

### The web lane (primary)

- Use the playtest runner's own Xvfb. Unset `TN_PLAYTEST_HOST_DISPLAY`. Never use the owner's
display or the laptop display.
- Pass `--browser-recipe webgpu --headed`. Without `--headed`, Chromium can fall back to
SwiftShader.
- Every run must report the reference adapter in `adapter.info`. On João's machine this is the
RTX 2080: vendor nvidia, architecture turing. Any other adapter makes the run `invalid`.
- Exit 75 means that the capture lock is busy. Retry it. Set `CAPTURE_LOCK_TIMEOUT_MS` to wait
longer. Other agents share the GPU, so do not run two arms at the same time.
- With `assert.performance`, the runner adds `--disable-frame-rate-limit` and
`--disable-gpu-vsync`. GPU ms is then the uncapped cost. The presented interval of a 60 Hz claim
needs a vsync-on run.

### The desktop lane (T3)

Build the V8 player (`pnpm native:build`). Run the scaffold with `pnpm build --target desktop` and
`THREENATIVE_ENGINE_PLAYER` set to the player. Use the playtest runner's `--target desktop` with
the template's `native-playtests/` (`boot`, `lightning`). Read frame windows with
`node packages/playtest/dist/runner/cli.js perf --file <log>`. Use the legacy browser arm as the
comparison, and label it as a cross-runtime comparison.

### Frozen scenarios

| Scenario | Use |
| --- | --- |
| `playtests/performance.playtest.json` | Primary timing: 1920x1080, `high` tier, 60 warmup frames, a walk, then 600 ticks |
| A pose scenario (viewport 1904x960, warmupFrames 30, waitTicks 300, one `pose` screenshot) | Visual judge and parity diff. Save it in the campaign directory and hash it. |
| `playtests/storm.playtest.json`, `weather.playtest.json`, `tiers.playtest.json` | Second Tempest load levels: heavy storm and each quality tier |
| The full `playtests/` set | Behavior gate before keep |

### Known state (2026-10-16, engine 54c226867)

These numbers start the history. They are not a baseline for a new campaign: measure your own.

- GPU ms at 1920x1080: Wasm 113.6, legacy 43.5 (3 pairs). CPU ms is equal on both arms.
- At 960x540, both arms are about 3.5x faster, so the cost is per pixel.
- `reflections: false` saves about 19 ms on Wasm and 5 ms on legacy. About 55 ms of the gap has
no named pass yet.
- Pose parity against stock three: full-frame mean diff 0.006 after the mat2 order fix.
- The rain playtest set passes 15 of 16 on Wasm. `lightning`/`thunderVoices` fails on both engines.
- Stock three itself is near 30 fps on the reference GPU, so T2 means beating stock three by more
than 2.5x.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
packages/runtime-native/patches/*.patch -text
# Unified-diff context prefixes precede the upstream bundle's tab indentation.
patches/[email protected] whitespace=-space-before-tab
packages/three-native/tests/compatibility/goldens/** linguist-generated
packages/three-native/tests/compatibility/fixtures/** linguist-generated
packages/three-native/api/*.json linguist-generated
packages/three-native/generated/** linguist-generated
Loading
Loading