Two proper venues off the real Ipswich pair, both built in code.
Willowbank Dragway (levels/willowbank_dragway): a true 402 m dual-lane
strip -- concrete launch pad, FLUX-rubbered lanes, crowd grandstand with
canopy, red control tower, distance boards at 60ft/eighth/1000ft,
checkered finish under a scoreboard gantry, sand trap and tyre wall,
smashable SL_ light towers and a staging paddock of parked fleet cars.
Between the lanes: a working christmas tree, six bulbs driven by game.gd
through material_override emission.
Drag mode grew the event around it. Every drag now stages at the tree
(three ambers, green at 2.7 s); rolling >2 m early is a RED LIGHT that
bogs your launch. The opposition is a six-rung ladder of preset locals
(Nanna's Shopping Run through The Willowbank Widowmaker), each with its
own fleet car, power and reaction time. Beating your current rung climbs
the ladder and pays an escalating purse ($250-$1600, top dog repeats);
crossing at all pays $50; and every car keeps a persistent quarter-mile
PB worth $150 when beaten. Losing no longer ends the run early -- you
still cross for your ET, with a 10 s grace if you dawdle. Ladder rung
and PBs persist in the garage save (schema extended compatibly).
Queensland Raceway (levels/qld_raceway): the National Circuit digitised
from the official track map and scaled to its exact 3126 m lap. The road
is one generated quad strip with trimesh collision; kerbs, gravel traps
and tyre stacks derive automatically from centreline curvature, sponsor
hoardings space themselves down the straights, and the SF straight gets
the checkered line, gantry, pit wall and the mandatory red pit complex.
Plus the pond. Race/cruise/rage all run on its RacePath.
Trap for the diary: Godot front faces wind CLOCKWISE. The first cut of
the road ribbon wound CCW and rendered invisible from above while
colliding perfectly -- the smoke suite passed and the screenshot showed
four cars gridded on open grass.
Three new FLUX textures (crowd, dragstrip, sand; the sand prompt tripped
Cloudflare's NSFW filter, of all things, and fell back to local). Smoke
suite covers tree staging, the held rival, rung-0 identity, green-bulb
emission, red-light innocence, PB/rung persistence and the 3126 m lap.
Also swept stale shot_*.png.import debris and ignored the pattern.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Terrain rewrote every junction's scoring economics, so the tuner re-ran (12
varied launches per event, closed-loop aim, percentile targets). The spread is
now $3k bronze at Cliffs Corner to $111k gold at Albert x Adelaide -- terrain
funnels that one into a monster pile-up, while the downhill scenery-crash
events (Margaret x Edward, Cliffs Corner, Bridge Approach) top out early with
median == max around $3-4k: winnable and honestly tuned, but they end on the
first wall. Those three still deserve hand-picked crossings eventually.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tools/fetch_dem.py pulls the open AWS terrarium elevation tiles for each
level's bbox (derived from the OSM geometry itself -- the fetch bboxes were
never recorded) and writes an f32 heightmap. The builder bilinear-samples it:
roads/footpaths/crossings drape (subdivided to ~8 m so long OSM segments stop
chording across curved ground), buildings lift rigidly to the lowest terrain
under their footprint with a 2 m foundation skirt, trees/props/planters ride
their own base heights, and the flat ground slab becomes a real terrain mesh.
Bridges get an explicit deck profile (lerp between end heights plus a hump)
instead of draping down into the river, the truss follows the deck, and the
Bradfield Highway now genuinely flies over Kemp Place -- the game has an
underpass. Kangaroo Point's cliffs are an actual 20 m drop, Edward Street
climbs to 55 m at Spring Hill.
Junction events bake spawn/convoy heights (osm_junction.py grew a pure-python
DEM sampler); the game respects marker heights everywhere it used to hardcode
ground=0.
Bugs the terrain surfaced, all found by measurement:
- Long road segments chorded across curved ground: the car visually sank to
its windows mid-block. Fixed by subdividing draped ribbons.
- The 9 m terrain grid aliases cliff edges and bulged metres ABOVE the finely
draped roads: a car spawning there was inside the terrain sheet and got
depenetrated through the floor into the void (y = -710). Fixed by giving
roads real collision and carving the terrain grid down wherever a draped
road sample lands (11k+ carve samples on Kangaroo Point alone).
- The junction validator and tuner drove throttle-only, which cross-slope
drift turned into 40-86 m misses; they now hold aim like a player would.
- Edward x Elizabeth launched down a 17% grade, went airborne at the crest
and wedged off-street: unwinnable geometry, not a bug. Swapped for
Elizabeth x George on the flat lower CBD. All 9 junctions validate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
18 kg of chrome chaos each: procedural basket + handle + castors on a
low-friction RigidBody, so they roll away when nudged and FLY when hit at
speed. Four strays around every trolley bay plus five rogues claiming
parking spots, as is tradition.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Medal targets are no longer one uniform 15/35/60k guess across every event.
tools/tune_junctions.gd plays each junction 12 times with varied launches and
sets bronze/silver/gold at the 35th/65th/88th percentile of actual damage, so
they now range from $4k at Cliffs Corner to $73k gold at Melbourne x Merivale.
The old numbers made half the events impossible and the other half trivial.
Grey x Glenelg scored $0 in 12/12 runs and took three fixes, each found by
measuring rather than reading:
- The launch sat on the street centreline, so the car drove cleanly BETWEEN the
two convoy lanes -- closest pass 2.9 m, almost exactly the 2.7 m lane offset.
It now launches in a lane. (The first attempt offset the wrong way and widened
the pass to 5.5 m, which is how the sign error announced itself.)
- int(L / headway) floors to one car on a short clipped stream, so that junction
fielded 9 convoy cars against the usual 20-25. Minimum 3 per stream, evenly
spaced to fit.
Result: $0 -> $91k, convoy 9 -> 18, and 0 of 9 junctions now unplayable.
The tuner has turned out to be the event validator as much as a balance tool --
"scores nothing in every run" is an unplayable event, not a tuning problem.
Also from the review: the deformer no longer crumples det_* panels after they've
been shed onto their own body, and notes that rebuilding an ArrayMesh drops any
imported LODs.
Honest gap: Cliffs Corner and Bridge Approach show median == max at ~$4.7k --
winnable and correctly tuned, but the run ends on scenery before the convoy is
reached. Both are curved approaches; they want better crossings picked by hand.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three new modes, all our own code:
- Pursuit (Simpsons Hit & Run's meter): smashing in cruise fills heat, at full
the police hunt you. Open 250 m for 6 s to escape, get pinned 4 s to be busted.
Heat decays, so picking a fight is a choice not a timer.
- Drag (NFSU2's): the gearbox IS the event. The builder finds each level's
longest genuinely straight run of wide road (442-628 m across the five OSM
levels) and drops DragStart/DragEnd, so no level needs hand-authored coords.
- Derby: five opponents in the carpark, last one running. Reuses the pursuit AI,
each hunting a different car so it's a brawl not a mob.
Crash damage now shows: total control-point travel drives paint dulling,
roughness and a scratch layer, so scuffs and crumple can never disagree.
Junction generator fixes, all found by measurement rather than inspection:
- streams[:6] truncated after street A's ways, so junctions where A yielded 3+
usable ways shipped with ZERO cross traffic. Interleaved before capping;
every event now has 2-4 crossing streams.
- RADIUS 170 -> 95 spread the convoy over a 340 m window, so you threaded the
intersection through a 20 m gap. Margaret x Edward was unwinnable: 27 convoy
cars alive, zero collisions, $0.
- Launch points now walk the street to exactly SPAWN_DIST and pick the busiest
shared node, and _clear_spawn() unblocks a buried start. Albert x Adelaide
went from $0 (drove 1 m into a building) to $91k.
- build_all_junctions.sh records the street pairs, which existed nowhere before.
Fixes from an adversarial review (23 confirmed findings), the worst being:
- Derby could only ever be LOST: wrecked opponents un-wrecked 2.2 s later via
Car._recover, so "last one running" was unreachable and the kill bounty could
be farmed to the boost cap off one revived car. They now hold their wreck.
- Drag reported WON to a beaten player: the AI's lookahead wrapped on a 2-point
path, U-turning before the line so its distance-to-finish grew again.
- The scratch layer used BLEND_MODE_MIX, whose mask defaults to white -- it
replaced the paint entirely rather than scuffing it. Now MUL.
- Drag on a level with no strip left the car at the origin, half-buried, unable
to end. Cop spawns used an unflattened basis. Stale "WANTED" HUD text.
Test harness: smoke covers all seven modes, and failures now exit instead of
hanging -- a failed assert in a headless SceneTree halts the script but leaves
the tree spinning, which cost 53 minutes of wall clock to notice.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Street lamps, bollards and bins are no longer baked scenery. The builder emits
SL_/BO_/WB_ markers off the OSM nodes and game.gd spawns them as RigidBodies
with a low centre of mass, so clipping a lamp at 100 topples it instead of
driving through a painted pole. ~206 physics bodies per level (58 parked cars,
60 lamps, 88 bollards/bins), all asleep until hit. Verified by ramming one:
23.6 deg tilt, launched at 18 m/s.
Fixes a self-inflicted trap from the last commit: level_*.jpg are Godot's
extraction of the GLB's embedded textures, NOT Blender output. build_all
cleared them to avoid orphans but left level.glb.import, so Godot's cache
decided nothing had changed and never re-extracted -- queen_st_mall shipped
with 0 of its 31 textures, loading fine but rendering untextured. The .import
now goes with them.
Also confirmed the Wheel of Brisbane pivot really does turn (0.086 rad over
120 frames, 0.000 m centre drift) -- it was previously untested.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Taps the last big unused seam in the OSM data: 140 highway=traffic_signals per
CBD level become pole + mast arm + two lantern heads with emissive lenses.
Timber power poles with catenary-sagging wires run down one side of every
residential street. Billboards now cycle three fictional ad designs.
Cloudflare's free tier (10k neurons/day) ran out mid-session, so flux_texture.sh
now falls back to the local MODELBEAST farm automatically -- transparent, same
output contract. tools/crop_poster.py trims generated billboards to the poster
face by saturation, since FLUX renders them in situ with sky and support pole
however the prompt is worded.
Fixed: signal lenses were built as 0.04 m beams and beam() bails under 0.05 m,
so they silently never existed -- caught by inspecting the exported GLB, not
the screenshot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every OSM level now spawns 50 shuntable parked fleet cars + 40 wheelie bins
from builder-emitted PP_/WB_ markers (kerbside + real amenity=parking rows;
asleep until rammed, absent in junctions to keep the puzzles deterministic).
Traffic bumped in cruise/crash.
Brisbane pass: red busway asphalt, jacaranda canopies on a fifth of the street
trees, Queenslander weatherboard + corro on building=house, art deco + glass
apartment facade variants, fictional shop-fascia signs above awnings, rooftop
billboards. Southbank gets the Wheel of Brisbane (by its mapped ticket office)
and the Grand Arbour's bougainvillea tendrils along the mapped footway.
Verified: smoke green, 50+40 smashables counted on southbank, screenshots of
the wheel, arbour trail, red busway, and one authentic parked-car rear-ending.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Builder now uses the furniture OSM already carries (footways, lamps, benches,
bins, bollards, bus stops, crossings): raised chamfered footpaths, shopfront
bands, awnings in three fabrics, parapets, layered fig/palm trees, zebra bars,
dashed centre lines, Queen St Mall winged canopies. ACES tonemap + SSAO + fog
in game.gd. flux_texture.sh gains size/luma clamping (FLUX renders "pale" as
blown-out white); gen_textures.sh + check_textures.py manage the set. Woolies
carpark rebuilt textured, parking the real fleet. Fixes: fractional OSM layer
tag crash, zero-length-normal UV projection, blood-red mall pavers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9 junction events across 6 levels, auto-generated from real OSM intersections
(tools/osm_junction.py): each crossing street's ways become lane-offset convoy
streams, deterministic speeds/intervals/models -- learnable puzzles, not dice.
Menu lists CRASH JCT entries; crash -> 9s settle with camera-relative
aftertouch on the wreck and a one-shot crashbreaker shockwave (blast() on
traffic, radial impulse on debris, orange boom). Damage tally vs
bronze/silver/gold targets. Fixed zero-normal UV projection that striped
roads. Smoke test drives a full junction run to tally (k, gold).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
southbank, albert_parklands, story_bridge, kangaroo_point + queen_st_mall
rebuilt textured. Level builder now does: FLUX facade/road/grass/water/rock/
steel materials with box-projected UVs (roofs split to plain grey), parks,
multipolygon river water (solid, cars skim it), tree nodes as low-poly cones,
natural=cliff walls, and a procedural steel cantilever truss along a named
bridge way (Story Bridge / Bradfield Highway, 338m). osm_xml_to_json.py
assembles water relations; osm_level_args.py gains trace: mode for race paths
that follow one iconic road. 11 textures via Cloudflare Workers AI
flux-1-schnell (tools/flux_texture.sh, creds from .env never printed).
Data (c) OpenStreetMap contributors, ODbL.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tools/build_level_osm.py extrudes OSM buildings (-col), lays road strips,
Spawn + RacePath empties; osm_level_args.py computes a building-clear spawn on
a named way and race-loop corners from street intersection nodes. game.gd
builds Path3D from GLB RacePath empties, sanitizes spawn bases, and places
bodies BEFORE add_child. Three real bugs fixed: mall canopies (building=roof)
extruded as solid blocks, underground busways rendered at surface, and the
km-wide ground trimesh breaking suspension raycasts (now -convcol). Cars get
continuous_cd for thin building shells. tests/probe.gd is the physics
raycast debugger that found it.
Data (c) OpenStreetMap contributors, ODbL.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Modes: Cruise / Crash Mode (60s damage dollars) / Race (3 laps, rubber-banded
rivals). Burnout loop: boost earned by drift, near miss, smash; takedowns refill
and grow the meter to 4x; hard crashes shed det_* panels and trigger Impact Time
slow-mo. Traffic follows the level RacePath frozen-kinematic and goes dynamic
when whacked. tools/build_cars.py builds six Aussie shitbox GLBs (profile
extrusion + detachable doors/mirrors/bumpers/bonnet/boot). Smoke test covers
all three modes headless.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop-in content: cars/<id>/stats.tres (+optional car.glb), levels/<id>/level.glb
or .tscn with a Spawn marker. Raycast arcade car (boost, drift, drift-earns-boost),
chase cam, HUD, menu built from registry scan. Placeholder Woolies carpark with
shuntable parked cars. Headless smoke test + windowed screenshot harness.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>