Added #/pinball-editor — a temporary drag-to-edit layout board (points,
bumpers/posts, flipper pivot+tip, mirror lock, add/delete nodes,
rubber-band multi-select, live JSON export/autosave). Used it to
redesign the table by hand instead of guessing coordinates, then
rebuilt TABLE in pinball.js from the exported layout:
- Real outlane tubes on both sides (inboard of the outer wall) instead
of a sealed funnel — a ball can miss the flipper and drain, same as
a real table, verified to have no wedge points.
- Flippers same length, mirrored pivots and rest angle; slingshots and
outlane tubes are exact mirrors of each other.
- Everything (outlanes, slings, bumpers, posts, flippers) recentred on
the whole table width — including the shooter lane — rather than
just the playfield-minus-lane, so it isn't visually lopsided.
- Bumper/post sizes back to a consistent set after some experimentation
drifted them apart (15/16/15/12/12 and 7/7/8).
- Physics: heavier gravity (was floaty), stronger slingshot kick (the
rubber wasn't doing anything), eased back down slightly after the
first pass felt too fast, flipper length is now per-flipper.
- The "gravity only goes down" trap-safety test (added last session)
now runs against this hand-edited geometry too and passes clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
A small canvas pinball engine (src/lib/pinball.js): fixed-timestep physics
with 5 substeps, circle-vs-segment collision, two rotating flippers whose
angular velocity drives the ball, 3 pop bumpers, 2 slingshots, a charged
plunger, 3 balls. Lighting all 3 bumpers "catches" a random Pokémon for a
bonus. Ball-search kicks a wedged ball toward centre; three strikes and it
drains. High score in pdx.pinball.
Hidden like "Who's that Pokémon?" — no nav entry; the two games
cross-link from each other's back-nav, or reach it at #/pinball.
Controls: ← / → (also A/L, Z) flippers, hold Space / the Launch button for
the plunger; on touch, tap the table's left or right half.
Rendering: the canvas is sized from its container with a DPR-capped
backing store (crisp on any display). `_frame()` is exposed so the physics
can be driven headlessly. 3 unit tests for the geometry helpers.
The physics are stable and the game loop is complete; feel (flipper
strength, ball speed, table balance) still wants hands-on tuning.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu