Skip to content

🏁 Weld the Skyweave forks, seat the structures, and land the finish - #70

Merged
sasler merged 2 commits into
mainfrom
fix/skyweave-junction-and-finish
Jul 30, 2026
Merged

🏁 Weld the Skyweave forks, seat the structures, and land the finish#70
sasler merged 2 commits into
mainfrom
fix/skyweave-junction-and-finish

Conversation

@sasler

@sasler sasler commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Four reported defects in the Claude Opus 5 Neon Horizon Racer, plus a few found alongside them.

1. The forks read as tears and pointed the wrong way

index.html:242 hardcoded "steer left to commit" and the commit test hardcoded r.lateral < -1.6, but both branches diverge to +sidescreen right — which the file's own sideOfMain() already computed as +1. So the player was told to steer away from the fork and could only commit by hugging the wrong rail.

The side is now resolved from the geometry once, in buildCircuit, and read by the prompt, the commit test, the signposts and the takeBranch hook. A new junctionReport() hook projects a point inside each branch through the live chase camera, so a test can assert the wording against where the branch is actually drawn.

The junction geometry is rebuilt:

  • weldJunction blends each branch's derived bank and width into the main line's across the gore, unwrapping through the corkscrews' turn count. Bank was previously derived from each line's own curvature with its own smoothing window, so the two decks met a few degrees rolled apart — the visible tearing wedge. Residual roll at the seams is now < 1e-6.
  • The ring walk starts and ends on the junction samples. It used to stride from index 0, leaving up to a ring of raced deck undrawn exactly where the branch meets the road.
  • Rails ramp instead of switching. The main line's rail opens across the junction so there is no wall to cross; the branch's shared rail grows back out of the gore as the roads separate. Previously the clipped rail was flattened to a black strip lying on the road while the main line kept its full-height rail straight through the middle of the split.
  • The shared edge overlaps 35 cm so no hairline seam can open.
  • The gore is painted with amber hazard chevrons via a widened aTrack.w, weighted outboard so the racing line stays clean.

2. Structures floated

  • CanopyTruss was a 50 m gantry whose legs stopped 9 m below the deck plane and 13 m outboard of it — it never touched anything — and TRUSS_AT dropped several inside junction spans, where from a branch you see a detached gantry hanging in the void.
  • BranchPylon hovered 3.4 m past the deck edge over nothing, mirrored to both sides so its chevrons pointed both ways.
  • GateArch used fixed 0.86 / 0.68 scales, putting a 29 m span's footings ~3 m past the deck edge.
  • Main-line RibbonAnchor slots had no junction exclusion, though branch slots did.

Both offending assets are re-authored in Blender to clamp the ribbon — deck-edge legs plus an under-deck yoke on the truss, a bolted deck plate and under-hook on the pylon. Every deck-mounted prop is now seated by scaling its authored deck-edge reference onto the local half-width, and placement is junction-aware throughout. A propReport() hook reports worst-case footing overhang per family so this cannot regress silently.

3. The start line was invisible

There was no start structure at all: checkpoint gate 0 sat at s = 40 and looked identical to the other eight, while the actual lap boundary was an unmarked wrap at s = 0. A new StartGantry root — half again as tall as a checkpoint, twin lattice columns over a lit portal, timing pods, and a 12×3 chequered banner board — now stands on the boundary itself, over a procedural chequer band with amber lips that flashes on every crossing. The nine checkpoints are re-spaced half a slot in so none crowds it.

4. Finishing was silent

finishRacer fired one arpeggio and one particle burst; the else at the lap accounting swallowed any on-screen message; and endRace() only ran once every racer had finished, so a winning player coasted to a stop under an unchanged HUD for as long as the slowest rival took. Steering also stayed live after finishing.

Crossing now lands a chequer-topped #finishBanner with the placement and a live "waiting on" line, a screen flash, a multi-wave burst, a fuller audio cadence and a hero-orbit camera. The board arrives when the field is in or after a five-second outro hold, whichever comes first, quoting a metre gap for any rival still out instead of the DNF that live play could never reach. Steering is gated once finished, and the final lap is called out on the HUD.

Found alongside

  • Bollard cluster members now re-check gate proximity for themselves; the s + k * 9 offset could walk one into a gate mouth.
  • Main-line anchors skip junctions, as branch anchors already did.
  • Props with no deck reference no longer scale to NaN — this had made the fork signposts invisible until a visual check caught it.
  • The seed-determinism probe held a steer key, which pinned the craft against a rail where the run saturates and stopped sampling the seeded hazard scatter it exists to probe. Same assertions, throttle only.

Assets

Blender 5.2.0 LTS via Blender Assets MCP: StartGantry added, CanopyTruss and BranchPylon re-authored, skyweave-structures.glb re-exported (485 KiB → 1.17 MiB, cap 6 MiB), manifest recipe updated. Bevels reduced to one segment on the new large parts so the deck-clamped truss costs about what the floating one did.

Verification

Command Result
npm run validate:game-assets 2 manifests, 4 files
npm run test:game-assets 13 pass
npm run lint clean
npx playwright test tests/outrun-racer-opus-5.spec.ts 23 pass (6 new)
npx playwright test tests/games-load.spec.ts --grep outrun-racer 3 pass
npm run build clean
npm run inspect:threejs -- --game outrun-racer --model opus-5 --state active-play 110 calls / 290,304 triangles, down from 315,792 before this change

npm run sync:three-runtime -- --check reports the vendored runtime out of sync on this Windows checkout; the files are byte-identical to node_modules/three@0.185.1 apart from CRLF line endings, and public/vendor is untouched by this branch.

Visual review at 1280×720 through the sandboxed play page covered all four defects: both fork approaches (prompt direction, welded seam, hazard-striped gore), inside a branch mid-junction (nothing hanging beside the other deck), the start gantry and chequer band from the grid, and the crossing in place plus the results board.

🤖 Generated with Claude Code

Four reported defects, all in the Claude Opus 5 Neon Horizon Racer.

**The forks read as tears and pointed the wrong way.** The prompt hardcoded
"steer left" and the commit test hardcoded `lateral < -1.6`, but both branches
diverge to `+side` — screen right — as the file's own `sideOfMain` already
computed. Both now resolve the side from the geometry, along with the fork
signposts and the `takeBranch` hook. The junction itself is rebuilt: a new
`weldJunction` pass blends each branch's derived bank and width into the main
line's across the gore, so the abutting decks are exactly coplanar at the seam
instead of meeting a few degrees rolled apart; the ring walk now starts and
ends on the junction samples so no raced deck goes undrawn; rails ramp instead
of switching, opening the main line across the split so there is no wall to
cross and growing the branch's shared rail back out of the gore; the shared
edge overlaps by 35 cm; and the gore is painted with amber hazard chevrons
through a widened `aTrack.w`.

**Structures floated.** `CanopyTruss` was a 50 m gantry whose legs ended 9 m
below the deck, 13 m outboard of it, and `TRUSS_AT` dropped several inside
junction spans; `BranchPylon` hovered 3.4 m past the deck edge over the void
and was mirrored to both sides so its chevrons meant nothing. Both are
re-authored in Blender to clamp the ribbon — deck-edge legs with an under-deck
yoke on the truss, a bolted deck plate and under-hook on the pylon — and
placement is junction-aware throughout. Every deck-mounted prop is now seated
by scaling its authored deck-edge reference onto the local half-width.

**The start line was invisible.** There was no start structure at all: gate 0
sat at `s = 40` and looked like the other eight, while the lap boundary was an
untextured wrap at `s = 0`. A new `StartGantry` root — half again as tall as a
checkpoint, with a chequered banner board — now stands on the boundary itself
over a procedural chequer band that flashes on every crossing.

**Finishing was silent.** `finishRacer` fired one arpeggio and one particle
burst, the `else` swallowed any message, and the board waited for the whole
field. Crossing now lands a chequer-topped banner, a screen flash, a fuller
cadence and a hero-orbit camera, and the board arrives within a five-second
outro hold, quoting a gap for any rival still out instead of a DNF that live
play could never reach. Steering is gated once finished, and the final lap is
called out on the HUD.

Also fixed in passing: bollard cluster members re-check gate proximity for
themselves, main-line anchors skip junctions as branch anchors already did,
and props with no deck reference no longer scale to NaN.

Blender: `StartGantry` added, `CanopyTruss` and `BranchPylon` re-authored,
`skyweave-structures.glb` re-exported and the manifest recipe updated.

Verification:
- `npm run validate:game-assets` — 2 manifests, 4 files
- `npm run test:game-assets` — 13 pass
- `npm run lint` — clean
- `npx playwright test tests/outrun-racer-opus-5.spec.ts` — 23 pass
- `npx playwright test tests/games-load.spec.ts --grep outrun-racer` — 3 pass
- `npm run build` — clean
- `npm run inspect:threejs -- --game outrun-racer --model opus-5 --state active-play`
  — 110 calls / 290k triangles, down from 316k before this change

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

vercel Bot commented Jul 30, 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 9:56am

@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: a598afed6d

ℹ️ 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 thread public/games/outrun-racer/opus-5/index.html Outdated

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

Fixes multiple gameplay, geometry, prop-placement, and finish-flow defects in the Claude Opus 5 “Neon Horizon Racer / Skyweave” Three.js game, and adds regression hooks/tests to prevent the fork/junction/structure/finish issues from reappearing.

Changes:

  • Rebuilds junction handling (fork side resolution, welded seams, rail openings/ramps, hazard chevrons) and updates fork prompt + commit logic to match geometry.
  • Reworks prop placement to be junction-aware, adds StartGantry + start-line band/flash, and improves finish flow (banner, outro hold, steering gating, hero camera).
  • Expands Playwright coverage with new tests for fork prompts/commit direction, junction seam integrity, prop seating, and start/finish behavior.

Reviewed changes

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

File Description
tests/outrun-racer-opus-5.spec.ts Adds regression tests for fork prompt correctness, fork commitment, junction welding, prop seating, and start/finish flow.
public/games/outrun-racer/opus-5/index.html Implements the core fixes: junction welding/rails, prop seating & reporting hooks, start-line structure/band/flash, and improved finish/outro behavior.
public/games/outrun-racer/opus-5/assets/manifest.json Updates the authored-asset recipe/prompt and purpose to include StartGantry and new seating assumptions.
games-metadata.json Updates LOC and asset byte counts for the opus-5 version metadata.

💡 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
…amps

Two review findings.

**Codex, P2:** when the player crossed after all three rivals, `finishRacer`
raised the banner and started the hero orbit, and then the `racers.every(...)`
shortcut called `endRace()` in the very same fixed step — hiding both. The
outro hold only ever protected finishes with someone still on track, which is
to say it did not protect finishing last, the one place a player most needs
telling that the race is over. `outroFrom` is only ever set once the player is
in, so it now drives the whole end-of-race condition: `OUTRO_MIN` (2.8 s) with
the field already home, `OUTRO_HOLD` (5 s) while rivals are still out. Covered
by a new `crossLineLast()` hook and a regression test, confirmed failing
against the previous condition.

**Copilot:** `propReport()` recorded `overhang: 0` for `BranchPylon`, which was
not a measurement — the pylon has no deck reference because it is not scaled
onto the deck. Reporting a zero there meant a pylon could drift off the edge
without the guard noticing, and the manifest's "every deck-mounted part is
authored against a 9.8 m reference" was wrong about it.

Deck-mounted props are now explicitly two families. Portals span the road and
are reference-scaled, so they are measured by how far a footing overhangs the
deck edge. Edge clamps sit beside the deck at a fixed size and bolt on with a
plate reaching inboard, so they are measured by how far that plate grips the
deck — `PROP_EDGE_GRIP` plus a `grip` figure in `propReport`, asserted along
with the overhangs. Unmeasured families now report `null` rather than a
flattering zero, and the test pins which family each prop belongs to. Manifest
recipe reworded to match.

Verification:
- `npx playwright test tests/outrun-racer-opus-5.spec.ts` — 24 pass
- `npm run validate:game-assets` — 2 manifests, 4 files
- `npm run lint` — clean
- `npm run update-metadata` — line count refreshed

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@sasler
sasler merged commit 4bb374a into main Jul 30, 2026
7 checks passed
@sasler
sasler deleted the fix/skyweave-junction-and-finish branch July 30, 2026 11:10
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