Commit Graph

6 Commits

Author SHA1 Message Date
m3ultra
2f1a1250cc Pinball: data-driven table spine (3 tables, 11 part kinds)
Replaces the single hand-built .tscn table with the Floorplan/Levels pattern from
Destroyulator: Table.gd builds a playfield from a spec, Tables.gd holds the specs,
Main.gd orchestrates. A table is now a Dictionary you can diff and hot-swap (T),
parallel work doesn't collide in one scene file, and a headless autotest builds
every table and proves the flippers swing.

Part vocabulary: flipper, bumper, sling, target, drop (banked, with cleared
detection), spinner (scores per revolution), saucer (captures + ejects), rollover
(lit lanes/glyphs), ramp (speed-gated, scores only at the top), wall, post.

Three ORIGINAL tables — NEON ARCADE (wide open, 3-bank, spinner lane), THE GROTTO
(narrow, open outlanes, a 5-bank guarding the only ramp), THE FOUNDRY (long, twin
ramps, upper flipper, 2x3 target array). Not traced from the vendored decomp.

Main also centralises the engine divergence: Box3D's hinge motor runs opposite to
Jolt/GodotPhysics, so flip_sign is resolved once at boot from the engine name
rather than authoring two sets of tables.

Caught by the new autotest: Godot's HingeJoint3D spins about its own local Z, so a
flipper built in code needs the joint stood on end to swing about world Y. Commanded
correctly and utterly motionless until fixed. AUTOTEST now: 3 tables, 7 flippers,
68-84 deg swing, ALL TABLES OK.

Rules/Juice/Hud are spawned by class name if present, so those lanes land independently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 17:24:07 +10:00
m3ultra
5fa6bbf67b Add Box3D upstream research notes; note godot-box3d is single-threaded
Engine notes from the eval session (Apple Silicon 24-P-core worker cap, the
benchmark harness, binding gaps, provenance), linked from the README.
Annotated with a verified fact: the binding hardcodes workerCount=1, so the
E-core trap cannot trigger through Godot until it grows a task system.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 09:03:34 +10:00
m3ultra
804e4c0fb8 Add Box3D upstream research notes for the testbed
Findings from the engine evaluation that led to this project, kept separate from
the table's own A/B results:

- Apple Silicon threading: Box3D gets SLOWER past the performance-core count on
  the M3 Ultra (30 workers 5158ms -> 32 workers 5646ms, 24P+8E). A physics step
  is a barrier, so a share of the work on a third-speed E-core makes the whole
  step wait. Read hw.perflevel0.physicalcpu, never hw.ncpu. Applies to any
  threaded physics on this fleet, not just Box3D.
- The benchmark harness: the CMake option is BOX3D_BENCHMARKS (plural), the
  scene/flag list, upstream's M2 Air + AMD baselines, and a warning that a full
  sweep runs over an hour on 32 cores — always pin -b and -w.
- What the binding does NOT implement (Generic6DOF, ConeTwist, SoftBody3D,
  per-pair exceptions) plus the silent Area3D-vs-trimesh divergence.
- Why pinball and not the ragdoll game: ~/Documents/alright is the better fit but
  is BLOCKED — its ragdoll is built from Generic6DOFJoint3D. Watch that upstream.
- Provenance: Box3D is serious (Catto, MIT, s&box + Esoterica adoption); the
  binding is five weeks old with zero releases and self-declares experimental.
  This is a testbed, not a bet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 08:54:25 +10:00
m3ultra
2ca67bb28b Add Godot 4.7 physics testbed: Box3D/Jolt/GodotPhysics A/B pinball table
Playable table (hinge-motor flippers, plunger, bumper, drain) plus a headless
probe harness that measured, per engine: tunneling of a fast ball through a
1 cm wall with CCD off/on, and hinge-motor drive. Findings in godot/README.md:
Box3D never tunnels even with CCD off, but its hinge motor sign is inverted
vs Jolt/GodotPhysics, and Jolt blows through angular limits that Box3D holds.
Ships a from-source macOS arm64 libgodot-box3d.dylib (upstream has no
releases). Also gitignore the remaining Microsoft media at repo root.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 05:33:07 +10:00
type-two
43d7e9ac8e Add DAT inspector; scope the other two Full Tilt tables
Investigating "make the engine play all the .dat types". Answer: the container
parses for all three tables, but playability is a per-table reverse-engineering
project, not a loader fix. Evidence recorded in CLAUDE.md so it isn't re-derived.

- tools/datdump.py: parse and diff PARTOUT(4.0) DATs — groups, component type
  ids, float attribute ids. Asserts its own entry walk stayed in sync, since a
  desync silently turns every later field into garbage.
- loader: add query_float_attribute_opt for genuinely optional attributes.
  Dragon/Pirate ramps omit wall0 (1303), which Cadet always carries; treat a
  missing wall as no wall instead of a fatal load error.

Cadet and Full Tilt Cadet verified unchanged after this.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 14:27:52 +10:00
type-two
b671975742 Vendor SpaceCadetPinball, build for Apple Silicon
Reverse-engineered reimplementation of 3D Pinball for Windows - Space Cadet
from k4zmu2a/SpaceCadetPinball (MIT), upstream cb9b7b8, vendored rather than
submoduled so local patches are just edits.

- CMakeLists: stop hard-setting CMAKE_OSX_ARCHITECTURES so the documented -D
  override works; brew's SDL2 is arm64-only and universal linking failed.
- gitignore original .DAT/.MID assets, which are not ours to redistribute.
- CLAUDE.md: build line, upstream deviation, and where game data goes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 19:05:12 +10:00