{"slug":"wild-orbs-opus","total":7,"limit":100,"offset":0,"since":null,"commits":[{"hash":"40f3e99","date":"2026-09-09 09:16:20 -0700","author":"Steve Abrams","subject":"chore: lint, refactor, v1.0.1 (session close)","body":"Refactor (behavior-preserving): extracted the duplicated wrapped-delta ->\nforce -> velocity step from six gravity-well / black-hole pull sites into one\napplyPull() helper. Each site keeps its own constants and falloff formula; only\nthe shared 'divide by distance, add to velocity' step is centralized. An\nindependent reviewer had scored maintainability 6/10 citing exactly this.\n(One site regroups (dx/d)*f*1.1 as (dx/d)*(f*1.1) — a last-ULP float\nassociativity difference, not a semantic one.)\n\nFix found by the close-out gate: the adaptive-resolution controller could not\nshed pixels when it most needed to. Downscale and upscale shared one cooldown\ncounter, and a recovery step sets it to 300 frames — so a recent upscale locked\nout an urgently-needed downscale for ~10 seconds, leaving the game pinned at\n29fps while refusing to lower resolution. A clearly-dropping framerate now\nbypasses the cooldown, and a downscale reseeds frameAvg just under the trigger\ninstead of down at a healthy value (which had forced the average to re-climb\nfrom scratch after every step). Measured on a loaded machine: convergence to\nthe floor went 9s -> 6s and the settled framerate 49fps -> 66fps.\n\nThis was surfacing as an intermittent 56/57 'holds framerate under load'\nfailure that I had been attributing to machine load. Sampling renderScale once\na second showed it stuck at 0.95, which is unreachable by downscale steps and\ntherefore proved an upscale cooldown was blocking it. Suite is back to 57/57\nwith cross-engine + touch green.\n\nAlso removed four stray *-dtd.mjs probe files left in the repo by panel\nsubagents.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"4e055c9","date":"2026-09-09 07:55:10 -0700","author":"Steve Abrams","subject":"Keep the neutral build comparator; leave the Qwen3 repo pristine","body":"test/compare.mjs is the internals-agnostic head-to-head harness written during\nthe decision panel: it knows nothing about either build's variable names, so\nneither candidate gets a home-field advantage. It measures only what is\nobservable from outside — console errors, whether the canvas actually animates,\nresponse to synthetic input, resize survival, 25s of input hammering, and\nframerate before and after. It found a dead heat between the two arena entries,\nwhich is what moved the verdict off 'pick a winner'.\n\nIt was sitting untracked in the Qwen3 entry's directory; moved here where it\nbelongs. That directory is now pristine — index.html, README.md, .gitignore and\n.git, nothing of mine left in it.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"8a61163","date":"2026-09-09 07:50:56 -0700","author":"Steve Abrams","subject":"Split out as the standalone Claude Opus arena entry","body":"The Wild Orbs challenge was run against multiple models' artifacts in parallel:\nthis build descends from the Claude Opus artifact, while a concurrently-running\nsession built its own from Qwen3 14B's artifact in ~/Projects/wild-orbs. Both\nwere landing in the same directory, which cross-contaminated the working tree\nand made one look like a successor to the other.\n\nSeparated so each arena entry stands alone. ~/Projects/wild-orbs is left exactly\nas it was — no writes to it. README now states the provenance instead of\nimplying a branch hierarchy.\n\nVerified in place: 57/57 assertions pass from the new location (an earlier 56/57\nwas a Spotlight-indexing load spike, not a regression — the file is byte-identical\nby md5 to the copy that passed four consecutive runs).\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"e78346c","date":"2026-09-08 17:07:27 -0700","author":"Steve Abrams","subject":"Verify the touch + cross-browser claims; fix the pointer-capture bug they exposed","body":"The README claimed touch and cross-engine support that was never actually\ntested. Testing it found a real bug: cv.setPointerCapture() ran first in the\npointerdown handler and throws NotFoundError when the pointer is already gone\n(fast taps, browser gesture cancellation). Thrown from the top of the handler it\naborted everything after it, so fire and PULSE inputs were silently dropped on\ntouch devices. Moved it last and wrapped it in try/catch.\n\nAlso: the pulse HUD hint read 'PULSE (SHIFT)' on phones, which have no Shift key.\n\ntest/browsers.mjs: boots and plays the game in Chromium, Firefox and WebKit,\ndetonates all 13 orb behaviours in each, verifies the WebAudio graph and\nlocalStorage path, then runs a touch pass on an emulated iPhone (stick steers +\nthrusts, right side fires, on-screen PULSE fires, thumb UI stays hidden for mouse\nusers). All green in all three engines.\n\nFixed a race in the wave-clear assertion: it cleared orbs while a spawnGuard\ncountdown was still in flight, which suppresses the clear detector, so the test\nintermittently waited forever. 57/57 across four consecutive runs.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"81c6680","date":"2026-09-08 16:13:51 -0700","author":"Steve Abrams","subject":"Nova shockwaves chain; lock the cascade bounds in tests","body":"Measuring the nova cascade showed peak concurrent shockwaves = 1: dmg 1 could\nnever kill an hp-2 nova, so the type never chained into itself despite its own\ndescription. Raised the shockwave to dmg 2 so it shatters what it crosses.\n\nThe recursion is bounded by construction (a shockwave damages each orb at most\nonce via its hit Set, and waves expire), which the new regression test now\nasserts rather than assumes: a 20-nova cluster peaks at ~87 shockwaves, clears\nthe field, and settles to zero in ~61 frames with no errors.\n\nAlso replaced the fixed-sleep assertions with polling — they failed on a loaded\nmachine, measuring the load average instead of the game.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"9854c68","date":"2026-09-08 16:07:32 -0700","author":"Steve Abrams","subject":"Wild Orbs: rebuild from the Opus artifact — 13 orb types, tested","body":"Built on the Claude Opus Model-Arena artifact rather than replacing it: kept\nthe orb bestiary, field/effect model and juice, fixed its defects, extended it.\n\nCorrectness fixes:\n- `continue` inside a nested for..of over black holes continued the INNER loop,\n  so a bullet was spliced then used after free; later splices removed the wrong\n  bullet.\n- Respawn ran on setTimeout, so the ship could respawn while paused and a stale\n  timer could fire across a restart. Now frame-counted.\n- Ship trail streaked across the screen on every wrap-seam crossing.\n- Entities popped at the screen edges: collision was wrap-aware but rendering\n  was not. Added wrap-aware draw for orbs/ship/bullets/hunters/sentries/pickups.\n- Rubber orbs spawned off-screen and snapped to the border on frame one.\n- `if(!byChain) G.combo++; G.comboT = 70;` — brace-less if made the second\n  statement unconditional.\n- Orb velocity had no ceiling; wells + shockwaves + rubber boosts could stack an\n  orb past collision resolution.\n- Wave-clear raced its own guard; toast/banner state leaked across restarts.\n- A 'nova' sound effect existed with no orb type to trigger it.\n\nRobustness: auto-pause on blur/visibilitychange, synth voice budget so a 20-orb\ncascade can't detonate the mixer, adaptive particle cap, and dynamic resolution\nscaling (the game is fill-rate bound, so it scales the backing store instead of\ndropping frames), prefers-reduced-motion respected.\n\nContent: 3 new orb types (NOVA shockwave, SENTINEL turrets, WARP position-swap),\nelder/boss orbs every 5th wave, 5 powerups, pulse bomb, hyperspace, turret\nenemies, end-of-run stats, persistent best, pause menu, touch + gamepad.\n\nTests: test/smoke.mjs drives the real game in Chromium — 55 assertions covering\nevery orb type at every tier including elders, a 24-orb chain cascade, all\nabilities, pause/wave/death/respawn/gameover/restart/resize, failing on any\nconsole error. Perf assertion measures the environment's own rAF ceiling first\n(headed Playwright is vsync-capped at 30fps; headless is software-rasterised).\n\nBranched off master so the independently-built version at db229b2 stays intact.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XP13P5ZKs7oWJQ3pjbvpnG"},{"hash":"db229b2","date":"2026-09-08 15:41:57 -0700","author":"Steve Abrams","subject":"Wild Orbs: complete single-file canvas arcade shooter","body":"Rebuilt from a broken starting artifact. Fixed along the way: undefined\n'timestamp' in the fire handler (shooting threw on every press), gameLoop\ncalled with no argument (NaN delta poisoned every position), per-frame\nvelocities multiplied by dt (everything crawled ~60x too slow), orbs spawned\noff-screen at negative coordinates, splice-during-forEach skipping entities,\nrecursive spawn handlers that multiplied orbs without bound, hex colours\ninterpolated into rgba(), particles that re-randomised direction every frame,\na game-over overlay that covered the start screen, and a ship heading 90\ndegrees out of phase with its thrust vector.\n\nAdded: 12 distinct orb types with unique silhouettes and on-hit rules, gravity\nwells / black holes / stasis bubbles / shockwaves as real force and time fields,\nricocheting shards, homing swarmlings, wrap-aware collision and homing, a glow\nsprite cache, motion trails, trauma screen shake, combo scoring, waves with\nstaggered type unlocks, lives and extra lives, per-type WebAudio synthesis with\na wave-scaled bassline, and start/pause/game-over screens with a live bestiary.\n\nVerified with node --check plus a Playwright suite: every orb behaviour, the\nfield-effect lifecycles, death to game-over to restart, pause, mid-game resize,\nand a 20s soak. Zero console errors, 73fps under load.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_013NMeFvLtrZNgG2sQnYqmUp\n"}]}