The Sir Leo Hielscher Bridges and their industrial hinterland, from OSM
+ DEM like everything else -- but a 64.5 m concrete box girder split
across 13 OSM ways and twin carriageways broke every bridge assumption
the builder had, three different ways, before the right abstraction
appeared:
- Per-way sine humps (the Story Bridge recipe) turned each short
approach span into a 52 m wall.
- A whole-bridge axis projection lifted named segments 3 km from the
water and cliffed at every segment seam.
- The fix: deck height is a CONTINUOUS FIELD of distance-to-river --
smoothstep from terrain to +57 m over the water. The river is the
thing being bridged; let it set the profile. Seams are geometrically
impossible because the field doesn't know what a segment is.
The bridge arg grew to Name:hump:style. Style "box" adds concrete
piers under every bridge-tagged span (28 of them), collision guardrails
chasing both deck edges (a 64 m deck with open edges is a cliff with
lane markings -- the first playtest fell off it), and puts Spawn,
DragStart/End and the RacePath on the deck field. Story Bridge keeps
its 16 m truss unchanged.
The payoff mode: a 1,422 m drag strip -- the longest in the game --
running up and over the bridge, verified in-shot racing Nanna's Morry
between the steel rails with the deck climbing ahead. Race mode's
auto-traced loop weaves interchange ramps and is honestly chaotic;
README flags the hand-authored-loop fix if bridge racing matters.
Plus the trace stitcher's loose-join pass (carriageways within 60 m
merge), a FLUX river-industrial sky, and the loose-join is what future
divided-road levels will lean on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The OSM pipeline pointed at actual mountains. Both levels ride the real
terrarium DEM (Coot-tha's range tops at 287 m, Gravatt's at 196 --
matching the survey numbers) with the real roads draped and carved over
it: Sir Samuel Griffith Drive winding up one side of town, Mount
Gravatt Outlook Drive zigzagging up the other. Race mode is 3 laps of
the mountain; the drag finder even discovered a 1080 m strip through
Mount Gravatt's suburbs (Logan Road, of course it is).
Pipeline upgrades earned along the way, all reusable:
- trace: RacePath mode now STITCHES every OSM way sharing the name into
one chain by shared endpoints (SSG Drive is 19 segments; tracing only
the longest produced a fraction of the route) and samples densely --
16 points cut hairpins cross-country and gridded race starts in a
paddock.
- 9th builder arg selects the raw-terrain texture. Bushland levels pass
"grass" (tiled at 3 m -- 18 m tiling reads as macro-photography lawn
blades under the car) which also enables forest fill: ~2600 extra
gums, 65% biased to within ~150 m of roads, where the driver's eyes
actually are.
- amenity=parking polygons are now PAVED (draped asphalt) as well as
stocked with parked shitboxes -- a summit lookout carpark is a
burnout pad, not a dirt patch. Both summits come ready.
- man_made mast/tower ways become tapered lattice towers with a cage
and whip antenna, built from beams into the steel bucket. Mount
Gravatt's telecom tower stands over its carpark.
- Levels can carry their own sky: levels/<id>/sky_<time>.jpg overrides
the global panorama for any time of day, including day (previously
always procedural). Both mountains ship FLUX skies with the Brisbane
skyline on the horizon; Gravatt also has a sunset one, because John's
reference photo demanded it.
Suite green at 11 levels. Next burnout spot: the Gateway Bridge, when
the details arrive.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Visit The Shed and one of the locals is waiting on the driveway with a
broken shitbox and cash: their actual car model parked there under a
floating Label3D job sign -- who they are, what they reckon is wrong
("it makes a noise at church speed"), the honest fault name, and the
offer. Pull up beside it and hold still to take the job; the wrench
minigame opens on THEIR car.
The roster is the extended universe: Nanna, P-Plate Pepper, Mullet
Merv, Torque'n Tezza, the Self-Described Bathurst Legend, Your Mate
Dazza (don't tell Shazza), Karen from Number 12, and the Widowmaker,
who says nothing and pays cash. Roster and fault rotate
deterministically off jobs_done.
Settlement: full pay at 60+, a $50 tip at 85+, half below 60 -- and
SHED REP moves with the workmanship (+3 clean, -6 botched, cap 40),
scaling the next offer from 70% of shop rate at rep 0 to 100% at cap.
Rep shows on the menu and garage header. Customer jobs bank NO quality
buffs: the customer's car id might be a car the player owns, and
fixing Merv's Kingswood must not secretly tune yours -- the wrench
consumes Garage.ui_customer and routes _finish to customer_done()
instead of clear_fault/set_quality.
The shed guards the spawn (parent is Game and mode == cruise) so the
wrench scene's backdrop copy of the level never summons a customer
mid-job. The spare parked shitbox moves to the kerb; the driveway
belongs to commerce now.
Smoke: customer waits after a shed visit, holding beside the spot takes
the job (flag-guarded for headless), the driven wrench job pays, rep
rises, the driveway clears, and the customer's own-car quality stays
untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The 2D repair panel retires -- every fault is a wrench job on the real
car in the real shed now. Gearbox and gasket open with DIAGNOSIS: three
lit warning lights, one honest, the code reader pointing at it through
its cracked screen ("D!IV!TR!IN"); a wrong pick costs quality and makes
every nut in the job run a turn longer (penalty_turns feeds _need() and
the HUD torque arc).
The gearbox is the hero job. Without a hoist you drag the 60 kg box out
by hand and hold the steady ring so it doesn't land on you; with the
Cashies crane it's the ceremony -- hook the chain, pump it out -- and
the tier-3 gantry winch hooks itself up. The gasket job is the full
rite: bonnet, head bolts, old gasket out (mind the mayonnaise), seat
the new one square, torque the head IN the window, coolant back in.
Tool tiers: every line goes Cashies -> Supercheap -> SNAP-OFF
PROFESSIONAL (buy again to upgrade, garage shows [T2] UP $N). Tiers are
felt, not read: sockets scale turns 1.6x down to 0.5x and widen the
torque window 0.8 to 1.3 rad; the tier-2 compressor's RATTLE GUN
converts non-torque nut twists into BRRRT clicks (windows keep the hand
skill -- guns strip); ramps cut jacking 10 clicks to 3; the fluids
shelf speeds pours; the SNAP-OFF tablet skips diagnosis outright.
Pre-tier saves read as tier 1.
Workmanship reaches the strip: an 85+ gearbox rebuild raises box_limit
to 4 blown shifts, an 85+ gasket job lifts the overheat ceiling to
1.18. Both wired into the drag setup and asserted in the suite, which
now also covers tier upgrade/cap flow, wrong-then-right diagnosis, the
toolless 60 kg gearbox path, and a clean gasket run -- via one shared
driver that handles every verb including diagnose.
The := inference trap, visit four: indexing untyped const Arrays.
Typed the tables (Array[float]/Array[int]) so every index site infers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The repair game grows its 3D half (src/wrench.gd): flat tyre, oil
change and dead battery are done on the player's actual car model,
parked in the actual shed level, through five mouse verbs on projected
3D anchor points:
GRAB part follows the cursor on a ray-plane, drop at the target
TWIST circle the mouse around the anchor; torque steps have a seat
window (release inside = clean) and blowing past it STRIPS
the thread -- quality hit plus an extraction step inserted
PUMP rhythm clicks (jack up, jack down)
YANK press and flick (pop the wheel, bonnet up)
STEADY keep the cursor inside a wandering ring (line up the studs,
pour the oil)
Camera presets per step (wheel / under-car / bonnet), a screen-space
ring overlay with a live torque arc, and props spawned per job (spare,
tray, bottle, batteries). The battery job enforces RED THEN BLACK --
backwards earns a spark shower and commentary.
Workmanship is a stat: every job scores 0-100, and an 85+ fix BUFFS the
car through Garage.apply (tyres +0.2 grip, oil +3% power, battery +0.15
boost) until that fault recurs -- add_fault clears its quality entry, so
your last good fix is exactly as durable as your driving.
Faults now have gameplay sources: a red light at the tree flat-spots
the fronts, every 4th wreck rattles the sump loose (oil light, not in
junctions where wrecking is the game), and getting busted kills the
battery. All three are suite-inert by construction. New faults route to
the wrench scene via FAULTS[id].scene; gearbox/gasket keep the 2D panel
until phase 2. Wounds: flat -0.35 grip, oil -7% power, battery -0.3
boost (boost floor clamped at 0.4 -- the old ba>0 guard never subtracted).
Smoke plays a clean flat-tyre job through the API (7 steps, quality
90+, grip buff verified on the next boot) and a sabotaged oil job (blown
torque window -> stripped thread -> extraction step appears). The same
Variant-inference parse trap struck a third time (Dictionary index this
time); the suite caught it before it cost anything.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The game is now called Shitbox Infinity (project name, window title,
title screen, README). The Gitea repo keeps its name until John renames
it -- gitea redirects, and the remote gets a set-url then.
The Shed (levels/the_shed) is the payoff for the whole garage arc: a
drivable suburban block on a quiet cul-de-sac. Single-storey brick
house with a corrugated roof and a porch light that works at night;
paling fence (new FLUX texture) with a gate gap for the driveway; hills
hoist mid-spin with three towels on it; wheelie bins at the gate and a
spare fleet shitbox parked on the street; gums; neighbours across the
road so you feel watched.
The shed itself is a 10x12 corrugated double garage on a slab: FLUX
pegboard wall, workbench, fluoro batten (a real light at night), and a
painted bay. The tools you OWN (Garage.tools()) stand in it as the real
TRELLIS'd cashies models -- sockets and the code reader ON the bench,
the engine crane by the wall, ramps at the bay mouth -- while unowned
tools leave an oil-stained outline of where they'll go. The rest of the
tool library is permanent clutter via the new shared ToolProps helper
(dragway.gd refactored onto it too).
Roll into the bay in Cruise, hold still 1.4 s, and game.gd opens the
garage -- diegetic shopping. Headless suites have no current_scene to
swap, so the trigger sets garage_requested first and the smoke suite
asserts on that: owned-tool display (sockets present, ramps absent on
the test save), bay marker found, bay trigger fires. Suite covers 9
levels now.
Scale lessons baked in: facade_brick at 0.14 tiling reads as a
three-storey office (0.045 reads domestic), and corrugated iron at 0.35
has metre-wide ridges (1.4 reads like roofing).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dealgod.pro products database holds ~82k secondhand tool listings
with photos (69k cached on the VPS). This turns the good ones into game
assets: 15 tool classes curated from 45 candidates (socket set, air
compressor, chain block, car ramp, OBD reader, trolley jack, engine
crane, engine stand, toolbox, angle grinder, welder, jerry can, battery
charger, jack stands, grease gun), each run through the MODELBEAST farm
by the new tools/cc_to_glb.py: bg_remove_local cutout, then trellis_mac
image->3D (1024 tier). Retries with backoff after a transient queue 401;
the jerry can made trellis_mac exit 2 on two different photos and went
through hunyuan3d_mlx instead (--operator flag), which ate it happily.
Raw TRELLIS output is ~20MB per prop, so tools/slim_glb.py (headless
Blender) decimates to 18k tris and re-exports with 1024 JPEG textures:
the library lands at 27MB total for 15 props instead of ~300MB.
The Willowbank paddock strews the whole library as RigidBodies --
TOOL_SPECS in dragway.gd gives each class its real-world size (TRELLIS
output is unit-ish; the AABB is measured live and scaled) and an honest
mass, so clipping the 70kg engine crane is a different event to punting
the grease gun. The loader is directory-driven: drop a new GLB into
assets/tools/ and it appears in the paddock next boot.
Textures inherit whatever branding was in the source photos -- fine for
secondhand background clutter, flagged in the README for anything that
gets promoted to hero status. Smoke suite asserts every GLB in the
library spawns as a prop.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Carnage now follows the car home. Grenading the gearbox or blowing the
head gasket on the strip records a persistent FAULT in the garage save,
and the car boots WOUNDED everywhere -- gearbox: 80% power and leaking
oil patches; gasket: 85% power and steaming from the bonnet -- until
someone fixes it. The garage screen grows an "IT'S BROKEN" section with
two routes per fault: pay the shop's someone-else's-problem rate ($700
to $900), or GET UNDER IT for free in the shed.
Getting under it opens the repair minigame (src/repair_ui.gd, all code
like every other screen). Step one is diagnosis off the dash warning
lights: with the CASHIES CODE READER the fault name comes through the
cracked screen ("D!IV!TR!IN") and the right light glows amber; without
it you're on vibes, and a wrong pick adds two penalty turns to every
nut in the job. Then the hands-on steps: hold-and-circle the mouse to
spin nuts (direction enforced -- a full turn the wrong way earns
"OTHER WAY."), click to pump the jack, drag the dead box to the bench.
The shed skill tree pays off physically: ALDI SOCKETS halve every nut,
SUPERCHEAP RAMPS halve the jacking, the CASHIES HOIST deletes the 60 kg
drag-the-box step entirely, the ADDITIVE CRATE shortens the coolant
top-up -- and finishing a job without the right tools leaves three
bolts over ("they're spares now").
Mouse plumbing routes everything through pick_light/twist/pump/drop_at,
so the smoke suite plays a complete toolless gearbox swap headless:
wrong light penalised, right light advances, every step type exercised,
fault cleared at the end. Wounded boot, shop fix and the drag-finish
fault handoff are covered too.
Two traps re-confirmed on the way: `var x :=` cannot infer through
InputEvent.position (base-class Variant) -- the parse error took the
whole suite down as a silent hang; and a full-rect background ColorRect
eats every mouse event before root._gui_input sees it unless its
mouse_filter is IGNORE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
Six tools, bought once, global: SUPERCHEAP WHEEL RAMPS, CASHIES CODE READER
(one previous owner, screen cracked), ALDI SOCKET SET, BUNNINGS AIR
COMPRESSOR, CASHIES CHAIN HOIST (on wheels, definitely not stolen), SERVO
ADDITIVE CRATE. Each unlocks a per-car tune-up at labour prices: dodgy
alignment (+0.4 grip), check engine delete (+6% power, the light WAS the
problem), 60 PSI in every tyre, head skim & lumpy cam (+12%), octane booster
habit (+0.25 boost), and RETORQUE EVERYTHING -- the one effect parts can't
buy: it raises the car's panel-shed and wreck thresholds, which are now
per-instance vars instead of consts. Parts buy bling; the shed buys labour.
Garage screen grows three sections (parts / shed / tune-ups) with locked
states showing which tool a tune needs. Save schema extends compatibly.
Smoke covers the tool gate, double-sell refusal and panel hardening on a
live car.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Earn bucks from every mode (takedowns, outruns, escapes, derby kills, medals,
a cut of crash damage) and spend them on performance parts of deeply
questionable provenance: K-MART MEGA WING, GO-FASTER STRIPES, SERVO FLAME KIT,
BLINGY MAGS, SERVO NEONS, BUNNINGS DRAINPIPE, TURBO THRU THE BONNET. Every
part gives a real stat bump AND bolts a procedural eyesore onto the car, sized
off the model AABB so the same tat fits a BUBBLA or a Kingswood. Fully kitted:
+35% power, +1.1 grip, +0.55 boost.
Per-car, persistent (user://garage.save), player-only -- stats apply to a
DUPLICATE of the shared CarStats so tuning your Lazza doesn't secretly tune
every Lazza in the city, and the save path is redirectable so the smoke test
can never wipe real progression. Bolt-ons attach after the deformer snapshot:
the wing survives every crash, as is right and proper.
GARAGE button + bucks readout in the menu; shop screen with prices, blurbs and
FITTED states. Smoke covers the earn/buy/duplicate-stats roundtrip.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The last two design-doc gameplay items land:
- Road Rage: 90 s, wreck as many rivals as you can. They recover on their own
(no hold_wreck) so the supply never dries up, and a 220 m leash teleports
strays back to the road ahead of the player. Bronze/silver/gold at 4/8/12.
- Oncoming: driving against the RacePath tangent while actually on the road
(within 7 m of the line, above 12 m/s, heading dot < -0.55) trickles boost
with a periodic toast. Runs in cruise, race and rage.
Crashbreaker finally looks the part: layered Fx.explosion (70-particle additive
fire bloom, rising smoke, 60-spark shower) inside a thin additive shockwave
shell -- the old opaque orange bubble drowned the fire out completely, so it
became a fast-fading front-culled dome instead. Plus a 0.8 camera shake.
Menu is a title screen: FLUX-generated key art (battered sedan, flying hubcap,
bridge, jacarandas -- the hubcap is canon now) behind a scrim, outlined golden
title. Art prompt asks for no lettering; the plate gibberish is FLUX being FLUX.
Smoke coverage for both mechanics. The oncoming test taught a harness lesson:
setting global_position on a continuous_cd body SWEEPS it there, wrecking the
car before the test began -- teleport via PhysicsServer3D.body_set_state.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every WAV is synthesized from maths by tools/gen_sounds.py (run through Blender
for its bundled numpy) -- sines, noise and envelopes, seeded and reproducible,
licence-free by construction. Loops (engine, skid, boost, siren) are built from
integer-Hz components over exactly 1 s so the seam is mathematically silent;
noise beds get a crossfaded seam. Seam continuity is verified numerically.
Wiring: pitch-tracked engine loop on every car (idle burble to top-end scream,
bump while boosting), skid loop off slip, player boost whoosh, small/big crash
by jolt with glass on wrecks, two-tone siren on pursuit cops (derby brawlers
stay silent), Crashbreaker boom, gearbox clunk/bog, win/lose stings on
takedowns, outruns, escapes, busts and derby eliminations.
Loop flags live in code (sfx.gd), not per-file .import settings, so a
regenerated wav never silently loses its loop.
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>
Implements the algorithm the README has listed as "still to come" since v0.
A 3x3x5 lattice of control points encloses the car; an impact shoves nearby
points inward and mesh vertices follow via inverse-distance weighting
(W_i = 1/||p_j - c_i||^alpha, alpha=2), clamped to the PDF's bounding-box
safety limit so panels crumple rather than fold through themselves.
The weights depend only on original positions, so they're precomputed once per
car at setup -- each impact is then a plain weighted sum at 0.3 ms, with no
per-frame cost at all. Meshes are deep-copied per car so deforming one Kingswood
doesn't dent every other Kingswood sharing the GLB.
Measured on the Lazza: a hard nose-on hit displaces 11.9 cm, accumulating to
18.2 cm over repeat hits, well inside the 42 cm clamp. Only the player and
rivals carry a deformer; traffic and parked cars stay plain bodies.
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>
Built from his photos: white 5-door wedge, black bumpers + belt-line rubbing
strip, amber corner indicators, wide dark grille bezel (pale headlights vanish
on white paint without it), and the crown jewel -- rear hatch louvres, five
slats that shed one by one on impact like a dropped pie. New optional spec
keys: louvres, indicators, side_strip, wide_grille; build_cars.py now takes
`-- <id>` to rebuild a single car; screenshot harness gains cam=rear.
Reversed-stats rule applied: 54 kW carby IRL -> 21.0 power / 860 kg / 7.8 grip
here. Second-quickest thing in the game behind the Excel, and the chuckable-est.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two rivals now lap the RacePath in free roam. Pull alongside one at speed and
the duel arms: first to gap the other by 250 m wins. Straight-line distance
decides when it ends (side-street escapes are real); path order decides who
won (reversing away is a loss). Rubber-banded chase, takedown-tier boost
payout, R mid-duel forfeits, 8 s re-arm cooldown. Mechanics only -- no assets
from anywhere near an EA disk. Smoke test arms a duel and settles the win path.
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>
Stats quietly inverted: shitboxier IRL = better in game. Excel X3 is now the
fastest car; TURDRUNNER is the slowest. tools/import_shitbox.py converts
downloaded models (glb/gltf/fbx/obj/blend) to game GLBs -- normalizes scale,
yaw, ride-height origin. First two imports: Corolla mk7 and Morris Mini.
shitboxes/ stash gitignored + .gdignore'd (its .blend files broke Godot's
headless import scan).
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>