Commit Graph

24 Commits

Author SHA1 Message Date
m3ultra
d886188475 Fleet expansion: ute, wagon, muscle coupe, microcar (34 cars)
Four new archetypes, all one spec dict each:
- HARDON WB UTE: builder grows ute=True support -- cab glass ends behind the
  seats, open tray with visible floor, bulkhead and a det_ tailgate. The most
  load-bearing vehicle shape in Australian culture.
- HARDON WAGGO HJ: the roof refuses to end; vinyl cap, tan over brown.
- FALCODORE 351 GT-OH-NO: black bonnet, ducktail, and per the reversed-stats
  rule the worst grip in the game (4.6) under the most bark (1710 kg).
- BUBBLA 600: a jellybean with delusions. 640 kg, grip 8.2, second-quickest
  car in the game behind the Excel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 13:44:40 +10:00
m3ultra
63c32928ee Road Rage, oncoming boost, a real Crashbreaker fireball, title screen
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>
2026-07-30 11:39:00 +10:00
m3ultra
3070a96b41 Car bodies sculpted, wheels that spin, destruction that reads
Skin pass (build_cars.py, whole procedural fleet rebuilt):
- warp_obj() kills the slab: plan taper (nose/tail pull in), tumblehome (the
  glasshouse leans inward above the belt) and rocker tuck, applied to
  world-space verts so det_ panels stay flush with the body.
- Beveled body edges catch light instead of vanishing into flat shading.
- Wheels are tyre + rim with the mesh centred on the hub and the OBJECT at the
  hub -- the old wheels baked position into their verts, so a spinning wheel
  would have orbited the car's origin. Chrome det_hub hubcaps on every corner,
  dark arch shrouds so wheels sit in wells rather than under a slab.
- B-pillars over the one-piece glasshouse, licence plates, exhaust, door
  handles. Mirrors anchored to where the tapered flank actually ends up.

Destruction feel:
- Visual wheels spin with road speed and the fronts steer (rotation order YXZ:
  yaw then roll, so steered wheels roll about the steered axle).
- Shed panels burst outward with lift instead of just detaching; light hits
  ping a hubcap off first, saving doors for crashes that deserve them.
- Sparks on every impact, soft-puff smoke on wrecks and heavy damage, tyre
  smoke while drifting (src/fx.gd -- procedural particles, radial-gradient
  billboards, no textures). Camera shake on player crashes, applied after
  look_at so it reads as the camera being knocked, not re-aimed.
- Crumple strength up ~40% now that scratches and dulling ride on it.

Traffic and parked cars inherit all of it via the shared fleet GLBs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 11:06:45 +10:00
m3ultra
589e99c727 Procedural sound kit: the whole game has audio, no recordings
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>
2026-07-29 13:05:48 +10:00
m3ultra
aac4384c05 Per-junction medal targets, measured; fix the last unplayable junction
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>
2026-07-29 00:15:05 +10:00
m3ultra
0c13c82eac Pursuit, drag and derby modes; crash-damage paint; junction fixes
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>
2026-07-28 23:07:41 +10:00
m3ultra
59202c222c Crash deformation: control-hull vertex displacement from the design PDF
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>
2026-07-28 19:01:43 +10:00
m3ultra
e9717326f4 Smashable street furniture; fix levels losing every texture on rebuild
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>
2026-07-28 18:53:05 +10:00
m3ultra
1db71420a3 Scenery v4: traffic signals, power lines, local FLUX fallback
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>
2026-07-28 17:21:35 +10:00
m3ultra
6808710f31 Scenery v3: smashable street life, Brisbane colour, Southbank landmarks
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>
2026-07-28 16:42:14 +10:00
m3ultra
81ed13b1ff FLOORED LAZZA 1.5: John's actual first car, '82 KA Laser hatch
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>
2026-07-28 16:16:32 +10:00
m3ultra
da63829e9e Outrun mode: NFSU2-style roaming 1v1 duels in cruise
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>
2026-07-28 14:18:20 +10:00
m3ultra
82dae637a1 Scenery overhaul: real OSM street furniture, FLUX texture set v2, lighting pass
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>
2026-07-28 14:13:29 +10:00
type-two
565caa6f85 Crash Mode junctions: scripted convoys, Aftertouch, Crashbreaker, medals
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>
2026-07-28 00:14:33 +10:00
type-two
7fd11f3806 Four more Brisbane levels + FLUX textures: these scenes pop
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>
2026-07-27 23:48:55 +10:00
type-two
d9b69e688e Brisbane: Queen Street Mall crash-run level from OpenStreetMap
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>
2026-07-27 23:33:51 +10:00
type-two
c4f11cc7de Batch-import the whole shitboxes stash: 13 more real models
FX/EH/HR Holdens, Kingswood HZ, both Excel imports, 240Z, AE86, KE80, both
Minis, Minicab, Delica coach, Leyland bus (untextured ghost bus, still
menacing). import_shitbox.py grows pitch axis, 1K texture cap and 150k-tri
decimation (cars/ went 501MB -> 146MB). tools/import_all.sh is the rerunnable
manifest with per-pack orientation fixes. Cutlass pack was junk, skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 22:47:38 +10:00
type-two
4c5323ba60 Reversed stats pass + real-model import pipeline (CASSEROLA DX, MORRY)
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>
2026-07-27 22:24:36 +10:00
type-two
9a3b0c6c6a CHAEBOL HLYR dynasty (X1/X2/X3) + HARDON CMERE
Excel X1 boxy '86 sedan, X2 rounder '90s hatch; existing X3 renamed into the
family. Camira in head-gasket cream with black plastic bumpers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 22:06:42 +10:00
type-two
9a4d96ae54 MINI MERK, MAXI MERK (6 wheels), HARDON SHAGGEN panel van
New moke body style: open slab tub, no doors, exposed seats, windscreen,
rip-off det_roof canopy on posts, optional extra visual axles (physics stays
4-ray). New van style: cargo box from cab to tail with det_tailgate. Smoke
test ram made deterministic (re-aim loop instead of blind throttle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:48:37 +10:00
type-two
09c7b2b280 TURDRUNNER SLUR 500, FLOORED XD LOLTOP, DADSON 420YO repaint
Builder learns 2-door coupes, two-tone accent bonnets, vinyl roof caps and boot
spoilers. Datto repainted orange with vinyl roof per reference. Screenshot
harness gains cam=front for front three-quarter checks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:41:37 +10:00
type-two
99718774fd Ignore stray screenshot import file
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:29:57 +10:00
type-two
eb7c189c9f Gameplay systems + procedural Blender car fleet
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>
2026-07-27 21:29:42 +10:00
type-two
1c0b7efb32 Engine v0: Godot 4.6 data-driven arcade racer scaffold
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>
2026-07-27 21:03:45 +10:00