Skip to content

🏎️ Add Skyweave, a Claude Opus 5 Neon Horizon Racer on an inverting light-ribbon - #69

Merged
sasler merged 2 commits into
mainfrom
feat/outrun-racer-opus-5
Jul 30, 2026
Merged

🏎️ Add Skyweave, a Claude Opus 5 Neon Horizon Racer on an inverting light-ribbon#69
sasler merged 2 commits into
mainfrom
feat/outrun-racer-opus-5

Conversation

@sasler

@sasler sasler commented Jul 29, 2026

Copy link
Copy Markdown
Owner

🏎️ Skyweave

The five existing Neon Horizon Racer versions are all the same idea: a flat synthwave highway where you dodge oncoming traffic. This one is a different game on the same marquee.

Skyweave races a mag-locked hovercraft along a suspended light-ribbon circuit that banks past vertical and corkscrews through two full 360° rolls, threaded between the megastructures of a drowned neon city.

The load-bearing decision

Nothing integrates in world space. Racers carry (s, lateral, hop) in ribbon-local coordinates and the world transform is derived from the track sample frame:

obj.position.copy(smp.p).addScaledVector(smp.side, lateral).addScaledVector(smp.up, RIDE_HEIGHT + hop);
basis.makeBasis(smp.side, smp.up, forward.copy(smp.tangent).negate());

Inversions therefore cannot desync, and the camera inherits the same basis so it stays level with the ribbon rather than the world. Corner banking is derived from curvature at build time, so every corner banks the correct way regardless of which direction the loop runs; the authored roll term supplies only the corkscrews.

What's in it

  • Circuit — closed Catmull-Rom through 28 authored polar nodes, resampled uniformly by arc length so sampleAt is an index lookup. Two branch lines fork away and rejoin, sharing guide nodes with the main line so the seams are invisible.
  • Charge economy — four distinct sources (rail-edge riding with a streak multiplier, gate threading scaled by precision, close passes, slipstream), spent on boost. Branch lines pay a premium because they are narrower and unforgiving.
  • Rivals — three AI craft running the same physics function as the player, differing only in the input struct they produce, with seeded personalities. Elastic is a ±5% clamp on the speed ceiling, never a teleport.
  • Feel — tuck raises the ceiling and costs 55% of steering authority; rails clamp and scrub rather than kill; hop clears bollards.

Blender-authored assets

Twelve model-owned forms authored in Blender 5.2.0 LTS via MCP and exported as two uncompressed GLBs totalling 1.0 MB (budget 8 MiB): four craft with deliberately distinct silhouettes (broad canard racer, forward-swept needle, flat delta, twin-hull catamaran), gate arches, branch pylons, ribbon anchors, an overhead gantry, deck hazards, and three skyline tower families. Hulls are lofted from authored cross-sections rather than assembled from primitives. No UVs, no vertex colours, no textures, no compression — only POSITION/NORMAL and KHR_materials_emissive_strength.

The deck itself is a shader carrying its own markings: sector-tinted centre line, lane guides, transverse rungs that give the speed read, edge chevrons, and a charge pulse that flows with the race.

Validation

Command Result
npm run validate:game-assets ✅ 2 manifests, 4 files, 2,928,232 bytes
npm run test:game-assets ✅ 13 passed
npm run lint ✅ clean
npm test -- tests/outrun-racer-opus-5.spec.ts ✅ 16 passed
npm test -- tests/games-load.spec.ts ✅ 92 passed
npm test -- tests/threejs-pipeline.spec.ts ✅ 3 passed
npm run inspect:threejs --game outrun-racer --model opus-5 --state active-play ✅ automatic checks passed

Inspector: 118 colour buckets, luminance stdDev 42.3, zero console/page/network/external failures. 121 draw calls, 22 instanced meshes, DPR capped at 1.5, shadows off (deliberate — emissive rails and grounded contact discs carry depth at this scale), 0 post passes.

Visual scorecard: art direction 3, authored forms 3, environment 3, materials/lighting 2, motion/VFX 2, readability 2, UI cohesion 3, performance evidence 3 — average 2.63, every category ≥ 2, no automatic failure.

npm run sync:three-runtime -- --check reports drift on the authoring Windows checkout only. public/vendor is git-clean and byte-identical to node_modules apart from CRLF, caused by core.autocrlf=true; the vendored files were not touched, and CI on Linux is unaffected.

🤖 Generated with Claude Code

…ight-ribbon

The five existing Neon Horizon Racer versions are all the same idea: a flat
synthwave highway where you dodge oncoming traffic. This one is a different
game on the same marquee.

Skyweave races a mag-locked hovercraft along a suspended light-ribbon circuit
that banks past vertical and corkscrews through two full 360-degree rolls,
threaded between the megastructures of a drowned neon city.

The load-bearing decision is that nothing integrates in world space. Racers
carry (s, lateral, hop) in ribbon-local coordinates and the world transform is
derived from the track sample frame, so inversions cannot desync and the
camera inherits the same basis. Corner banking is derived from curvature at
build time; the authored roll term supplies only the corkscrews.

- Closed Catmull-Rom circuit resampled uniformly by arc length, plus two
  branch lines that fork away and rejoin, sharing guide nodes so the seams
  are invisible
- Charge economy with four distinct sources - rail-edge riding, gate
  threading, close passes and slipstream - spent on boost; branch lines pay
  a premium because they are narrower
- Three rival AI craft running the same physics as the player, differing
  only in the input struct they produce, with seeded personalities
- Twelve model-owned forms authored in Blender 5.2.0 LTS via MCP and exported
  as two uncompressed GLBs totalling 1.0 MB: four craft with distinct
  silhouettes, gate arches, branch pylons, ribbon anchors, an overhead
  gantry, deck hazards and three skyline tower families
- Deck rendered by a shader carrying its own markings: sector-tinted centre
  line, lane guides, transverse rungs for speed read, edge chevrons and a
  charge pulse that flows with the race
- Procedural Web Audio throughout, deterministic ?test=1 hooks and
  diagnostics, and a seed hook that rebuilds the seeded world rather than
  only swapping the generator

Local validation:
- npm run validate:game-assets - 2 manifests, 4 files
- npm run test:game-assets - 13 passed
- npm run lint - clean
- npm test -- tests/outrun-racer-opus-5.spec.ts - 16 passed
- npm test -- tests/games-load.spec.ts - 92 passed
- npm test -- tests/threejs-pipeline.spec.ts - 3 passed
- npm run inspect:threejs --game outrun-racer --model opus-5 --state
  active-play - automatic checks passed; 118 colour buckets, 121 draw calls,
  22 instanced meshes, DPR capped 1.5, shadows off, 0 post passes
- npm run sync:three-runtime -- --check reports drift on this Windows
  checkout only: public/vendor is git-clean and byte-identical to
  node_modules apart from CRLF, from core.autocrlf=true

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
brainrot Ready Ready Preview Jul 30, 2026 3:22am

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f3beb86cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1597 to +1600
r.s = mainLine.length - 30 - row * 13;
r.lateral = (col === 0 ? -1 : 1) * 4.2;
r.lateralVel = 0; r.speed = 0; r.hop = 0; r.hopVel = 0; r.airborne = false;
r.lap = 1; r.rank = i + 1; r.progress = 0; r.lastMain = r.s; r.finished = false; r.finishTime = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Count all three laps before finishing

On every normal start, the grid is placed only 30 metres before the start line while each racer is already marked as being on lap 1. That first, almost immediate crossing increments the racer to lap 2, and finishRacer is subsequently called after only two complete circuits, so the advertised three-lap race and recorded total times are consistently short by nearly one lap. Place the grid just after the start line or distinguish the opening crossing from a completed lap.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Neon Horizon Racer variant (“Skyweave”) for Claude Opus 5, expanding the Outrun Racer lineup with a Three.js suspended ribbon circuit (banking + full inversions), authored GLB assets, and a dedicated Playwright spec to validate deterministic test hooks, gameplay mechanics, and rendering budgets.

Changes:

  • Added the new standalone Three.js game implementation at /games/outrun-racer/opus-5/index.html plus an assets manifest.
  • Added a comprehensive Playwright spec (tests/outrun-racer-opus-5.spec.ts) covering load integrity, determinism, core mechanics, branching, pause/focus behavior, and diagnostics budgets.
  • Updated repo indices/registries so the new model/version participates in catalog + load tests (games-metadata.json, tests/games-load.spec.ts, README.md).

Reviewed changes

Copilot reviewed 5 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/outrun-racer-opus-5.spec.ts Adds a dedicated end-to-end Playwright validation suite for the new Opus 5 Skyweave version, including deterministic hooks + diagnostics assertions.
tests/games-load.spec.ts Registers outrun-racer/opus-5 in the global “loads without errors” matrix.
README.md Updates the Neon Horizon Racer version count and the model/game LOC table to include Opus 5’s new racer entry.
public/games/outrun-racer/opus-5/index.html Introduces the full Skyweave standalone game (Three.js renderer, ribbon-track sampling/frame logic, gameplay/economy/AI, diagnostics + test hooks).
public/games/outrun-racer/opus-5/assets/manifest.json Declares the two GLB assets with provenance/usage metadata for validation tooling.
games-metadata.json Adds the new Opus 5 outrun-racer version entry with features + asset sizing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread public/games/outrun-racer/opus-5/index.html Outdated
Addresses the merge/split graphical glitches and both reviewer findings.

Branch junctions (reported with screenshots):
Two separate causes, both showing up as flat wedges tearing through the deck.
A branch shares its lead-in and lead-out guide nodes with the main line, so
roughly 94 m at each end was geometrically identical to the main deck and was
being drawn straight over it. Those stretches are no longer drawn - only the
raced span is. That alone is not enough, because C1 continuity through the
shared node means the two centrelines separate quadratically; measurement put
full clearance at 42-56 m, so no node tweaking pulls them apart faster. The
branch cross-section is now clipped to begin at the main deck's edge, turning
the overlap into a proper gore: one continuous surface widening away from the
main road, with the clipped-side rail laid flat so it cannot spear up through
the road beside it. The clip self-resolves - once the lines are clear the main
edge falls outside the branch's own half-width and the clamp is a no-op.

Codex P1, three laps were never raced: the grid lined up 30 m *behind* the
start line with lap already 1, so the opening crossing banked a lap that was
never driven and a three-lap race ran two circuits. The grid now starts past
the line and the first lap is timed from zero. Verified at 3.038 circuits.

Copilot: dropped the unused `list` parameter from the prop-bucket helper.

Also fixed a bug visible in the reported screenshots: finishRacer capped
`lap`, which retroactively shortened `progress` by a whole lap length and made
the standings read "--1705m". Progress now stays monotonic and finished racers
show their finish time instead of a metre gap.

`holdCentre` now drives the real fixed step with the player pinned to the
centre line, so it exercises lap accounting and ranking rather than stepping
one racer in isolation.

Local validation:
- npm run validate:game-assets - 2 manifests, 4 files
- npm run lint - clean
- npm test -- tests/outrun-racer-opus-5.spec.ts - 17 passed, including a new
  three-circuit race assertion
- npm test -- tests/games-load.spec.ts tests/threejs-pipeline.spec.ts - 96 passed
- npm run inspect:threejs --game outrun-racer --model opus-5 --state
  active-play - automatic checks passed
- Reviewed both junctions from five angles each (fork approach, at the fork,
  early on the branch, approaching the merge, and the merge from the main
  line); no console or page errors at any of them

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@sasler

sasler commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

Pushed 6c89f2e addressing both review findings and the merge/split artifacts reported with screenshots.

Branch junction artifacts — two separate causes:

  1. A branch shares its lead-in and lead-out guide nodes with the main line, so ~94 m at each end was geometrically identical to the main deck and was being drawn straight over it. Only the raced span is drawn now.
  2. That alone was not enough. C1 continuity through the shared node means the centrelines separate quadratically — I measured full clearance at 42–56 m, so no node tweaking pulls them apart faster. The branch cross-section is now clipped to begin at the main deck's edge, turning the overlap into a proper gore: one continuous surface widening away from the main road, with the clipped-side rail laid flat so it cannot spear up through the road beside it. The clip self-resolves — once the lines are clear, the main edge falls outside the branch's own half-width and the clamp becomes a no-op.

Reviewed both junctions from five angles each (fork approach, at the fork, early on the branch, approaching the merge, and the merge seen from the main line). Zero console or page errors at any of them.

@chatgpt-codex-connector P1 — count all three laps. Confirmed and fixed. The grid lined up 30 m behind the start line with lap already 1, so the opening crossing banked a lap that was never driven and a three-lap race ran two circuits. The grid now starts past the line and lap 1 is timed from zero. Measured at 3.038 circuits, and tests/outrun-racer-opus-5.spec.ts now asserts the lap sequence is exactly [2, 3, 4] with circuits between 2.9 and 3.3.

@copilot — unused put() parameter. Removed; callers no longer pass propBuckets.

Also fixed, spotted in the reported screenshots: finishRacer capped lap, which retroactively shortened progress by a whole lap length and made the standings render --1705m. Progress stays monotonic now, and finished racers show their finish time rather than a meaningless metre gap.

Validation: validate:game-assets ✅, lint ✅, new spec 17 passed, games-load + threejs-pipeline 96 passed, inspector automatic checks ✅.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@sasler
sasler merged commit b6a5284 into main Jul 30, 2026
8 checks passed
@sasler
sasler deleted the feat/outrun-racer-opus-5 branch July 30, 2026 03:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants