Runtime performance

What does one character cost, or a hundred? These measurements compare published Play 1.17.1 (A) with 1.18.0 (B) through the same legacy Pixi snapshot adapter. Some pose and combined CPU costs fell; submission and GPU outcomes depend on the workload and capture. They do not establish an FPS gain or a budget for every rig.

The sources are the frozen original hardware report (#62) and separate RTX recapture (#64), with #62 JSON and #64 JSON. These are historical package comparisons, not measurements of today's releases, every renderer, DOM/canvas mode or a direct-buffer path. They do not isolate a core-only change. Play bundles core: 1.17.1 declares build-time core 2.67.0, with embedded sources matching 2.70.0; 1.18.0 declares and matches 2.72.0. Installing another core beside it does not replace that bundled code.

What was measured

CaptureDevice and browserDate and conditions
#62 MacApple M4, 10 GPU cores; ANGLE Metal; Chromium 151.0.7922.34; macOS 26.6.1 (25G76), Darwin 25.6.0Calendar date absent from the published receipt. Other measurement/build sessions excluded during capture; normal desktop background work remained.
#62 WindowsNVIDIA GeForce RTX 4070 Ti; ANGLE D3D11; driver 32.0.16.1088; Chromium 155.0.8059.80; Windows 11 Pro 10.0.26300JSON host observations: 2026-10-26, 18:14:51–18:16:17 UTC. An unrelated application used the measured display GPU at 22% before / 21% after, plus desktop composition. Not an uncontended RTX baseline.
#64 WindowsRTX 4070 Ti; ANGLE D3D11; driver 32.0.16.1088; Chromium 155.0.8059.80Capture date absent from the published receipt. Adapter identity pinned per launch, host observations retained privately; no quiet or idle claim. Mac was not recaptured: admission refused before a timing browser launch.

Both workloads play walk, at 1 and 100 independent instances, on a shared 1800 × 640 canvas, DPR 1, with 60 warmup and 180 measured paired frames per workload per launch. The fixture identity and size below come from the report JSON; bone/mesh/triangle counts are not supplied there. Byte size identifies these inputs, not a general measure of rig complexity.

FixtureCompiled model bytesModel SHA-256
spineboy748,02406bb683060a3e38866718885b78d295c2aa246739ff79efddb22bd7332dd8919
raptor917,1064b02193c4100e1da392929b409f4b12806c50d79aca7d8bc3738ad83a5aa18fc

The fixtures use rigc v2.64.1 and upstream Spine examples at 38ddb1a0652c2e3473e8487ebd88b4b291ad9a7e (input metadata). Wind-wave was withdrawn, not replaced by another workload.

Read the clocks separately. poseMs is CPU posing; submitMs is CPU render submission, including query instrumentation and possible driver back-pressure; cpuMs is combined CPU work. gpuMs comes from asynchronous per-arm WebGL timer queries when available. Whole-frame gl.finish() completion is CPU wall time, not GPU-only execution. Presentation, input-to-present latency and FPS were not measured. CPU and GPU deltas cannot be converted into FPS. See the same-frame timing boundaries.

Original capture: M4 and contended RTX

#62 ran AA1, AA2, AB1, AB2 in fresh headful launches. A/A compares old/old; A/B compares old/new, alternating AB/BA within each frame. A gain needs both paired A/B medians below the negative maximum absolute A/A p05/p95 envelope. All values here are milliseconds, copied to six decimals; slash-separated numbers are AB1 / AB2, not a confidence interval.

M4 workloadA combined CPU p50B combined CPU p50Paired B − A p50Verdict
spineboy / 10.125000 / 0.1300000.080000 / 0.085000−0.055000 / −0.050000Gain outside A/A envelope
spineboy / 1008.635000 / 9.8000006.230000 / 6.945000−2.535000 / −2.970000Gain outside A/A envelope
raptor / 10.210000 / 0.2250000.175000 / 0.190000−0.045000 / −0.050000Gain outside A/A envelope
raptor / 10013.845000 / 13.52000013.235000 / 12.935000−0.620000 / −0.630000Unresolved

Pose CPU gains resolve for those same first three M4 workloads. M4 raptor/100 pose, every M4 submission delta and every M4 GPU delta remain unresolved. Every Windows #62 metric remains unresolved: no improvement repeats beyond its A/A envelope. That does not prove equal performance or no poser benefit. Background load remains part of the RTX capture's limit. The full tables retain the individual pose, submission and GPU costs, envelopes and both repeats; separate column medians need not subtract to the paired median.

RTX recapture: gains and repeated positive costs

#64 rebuilt the merged instrument at 78e696b41fc07552a4861dde84cd8c85148cb8c4 and interleaved AA1 AB1 AA2 AB2 AA3 AB3. Unresolved finite intervals or mixed A/B signs triggered the predeclared extension to six pairs. Each launch contributes its paired median; AA and AB get separate mean ± t × sampleSD/√n intervals. Gain requires AB upper < 0, AB upper < AA lower and every AB launch median < 0.

Stage 3 had 6 gain / 10 unresolved rows; stage 6 had 8 gain / 8 unresolved. These nominal descriptive 95% intervals do not guarantee sequential or family-wise coverage after adaptive looks and multiple comparisons. Added launches narrowed 25 intervals, widened 4 and left 3 unchanged. The decision statistic changed: applying #62's legacy envelope rule to these same rows yields only one gain at each stage, spineboy/100 pose. The counts cannot show an apples-to-apples hardware, noise or code improvement over #62.

Below are all stage 6 outcomes. Values are B − A milliseconds, mean of six launch medians [descriptive 95% interval], rounded to nine decimals, as in the report. G is gain under its posted rule; U preserves the reader's unresolved verdict.

WorkloadMetricMean [lower, upper] msVerdict
spineboy / 1Pose CPU−0.040000061 [−0.043318665, −0.036681457]G
spineboy / 1Submission CPU0.000000000 [0.000000000, 0.000000000]U
spineboy / 1Combined CPU−0.044166664 [−0.050300811, −0.038032517]G
spineboy / 1GPU−0.003461333 [−0.005792260, −0.001130406]G
spineboy / 100Pose CPU−2.327500045 [−2.444536837, −2.210463254]G
spineboy / 100Submission CPU0.002500017 [−0.050050417, 0.055050452]U
spineboy / 100Combined CPU−2.254999995 [−2.421195607, −2.088804384]G
spineboy / 100GPU0.002218667 [0.000367736, 0.004069597]U
raptor / 1Pose CPU−0.015833318 [−0.021967501, −0.009699136]G
raptor / 1Submission CPU0.000000020 [−0.000000031, 0.000000071]U
raptor / 1Combined CPU−0.015833318 [−0.021967501, −0.009699136]G
raptor / 1GPU−0.034304000 [−0.064229862, −0.004378138]U
raptor / 100Pose CPU−0.125833352 [−0.230430851, −0.021235854]G
raptor / 100Submission CPU+0.672499955 [+0.583344255, +0.761655655]U
raptor / 100Combined CPU+0.529166679 [+0.402301365, +0.656031993]U
raptor / 100GPU−0.013824000 [−0.075801845, 0.048153845]U

Raptor/100 submission and combined CPU have repeated positive cost observations. All six A/B launch medians are positive and their intervals lie above the A/A intervals. The posted rule named gains only: these observations do not retrofit a predeclared regression verdict or change U to another label. Conversely, a negative GPU interval alone does not establish a gain: raptor/1 still fails the full rule. The complete #64 report preserves stage 3, stage 6, A/A intervals and all exclusions. No new Mac timing or idle RTX baseline follows from this recapture.

Fixture integrity and reproduction

The historical #62 manifest hashes were checked, but its declarations did not prove which bytes the receiving browser consumed. The merged fixture instrumentation (#65), documented in receiving-host fixture integrity, now verifies all 18 bodies before controls/timing and makes both players and the oracle consume those verified Blobs. #64 records those per-launch measurements. This closes that consumption gap for the recapture; it does not retroactively browser-verify #62 or make legacy fixture generation immutable across toolchains. Keep the exact recorded hashes with any reproduction.

  • #62 protocol and commands cover frozen installation, oracle and fixture preparation, published-player site preparation, precheck, historical Mac capture and summary, and the native Windows task route. Its host-window instructions describe that historical run, not a new scheduling requirement.
  • #64 protocol and commands specify the interleaved 3/6 schedule, controls, stopping rule and recovered-reader replay. Its Windows scheduler, capture config and frozen reader copies are private. The old public Mac/Windows runners still schedule 2/2 and cannot produce this v2 capture; the printed private task command is not a public turnkey reproduction.
  • Timing boundaries and fixture controls explain what is checked before sampling and what the clocks exclude. Neither preparation nor a correctness test is a new hardware measurement. No benchmark was run for this guide.

For integration, return to Play or Adapters. Use these workload- and version-bound costs as recorded evidence; measure your own rig and presentation path before choosing a character budget.