Playtest feedback:
- Ball wedged in the bottom corners → the lower table is now deliberately
open: below the side walls it's all drain except the two flippers and
slingshots, so there are no enclosed basins. A displacement-based
ball-search still nudges (then, after 3 strikes, drains) anything that
does get pinned.
- "Needs more things to bounce off" → 5 bumpers (was 3) spread across the
mid-field + 3 small posts.
- "Gutter rails too large" → the long inlane rails are gone; short corner
guides only.
- "Can the ball go back to the launcher?" → yes: a ball that drains down
the right side returns to the shooter lane, no life lost. Left/centre
drains still cost a ball.
- Poké Ball now spins with its motion.
- Flippers stuck on mobile → per-pointer tracking (Map of pointerId→side),
drop on pointerup/cancel/leave/lostpointercapture, clear on blur/hide.
Two thumbs work; a missed pointerup can't leave a flipper held.
- Text selection on touch → user-select:none on the game, preventDefault
on pointerdown.
- "Looks rudimentary" → framed panel, playfield grid + accent glow,
concentric bumpers with a lit halo, slingshot triangles, flippers with
a highlight core and pivot caps, a drawn plunger, a shaded Poké Ball.
Also: canvas backing store is sized from the container × capped DPR (crisp
on any display) and `.pin__over` no longer sits blurred over the table
when hidden.
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