3 Commits

Author SHA1 Message Date
richard 02aec4249f Make the Controls options menu device-aware
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled
Showing both a keyboard key and a gamepad button on every ability row
(and WASD movement rows that never had a gamepad equivalent anyway)
cluttered the list once a controller is in play. The rebind list now
shows only the relevant set for whichever device the player is
actually holding: on a gamepad, movement rows disappear entirely
(the D-pad/stick isn't individually remapped, so there's nothing to
show) and each ability shows only its gamepad button; on keyboard,
the reverse. Uses the same Controls.using_gamepad() last-input
heuristic as the HUD's ability keycaps, not mere connection presence,
so a controller left plugged in but unused doesn't hide keyboard
binds from a mouse-and-keyboard player. The list (and its hint text)
also swaps live if the player switches device while the panel is
open, skipped while a rebind capture is in progress so it can't be
torn out from under them.

Verified headlessly: keyboard mode shows all 8 rows, gamepad mode
shows only the 4 ability rows, and the hint text swaps between them —
confirmed with a real screenshot of both states.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
2026-09-10 19:42:59 +03:00
richard 431ee295ae Full Xbox/PlayStation controller support: glyphs, remapping, vibration toggle
Extends the earlier Xbox-only ability glyphs into full brand-aware
controller support, following standard practice (position-based
button mapping, safe defaults for unrecognised pads, no per-device
special-casing):

- Controls detects PlayStation pads (DualShock/DualSense) from
  Input.get_joy_name() via a name-substring heuristic, checking for
  "xbox" first so a Bluetooth-connected Xbox pad (reports as "Xbox
  Wireless Controller") can't be misread as PlayStation through the
  generic "wireless controller" hint. Unrecognised/generic pads read
  as Xbox-style, matching the browser's Standard Gamepad Mapping.
- Ability-bar keycaps and the options menu now show ✕/○/□/△ for a
  detected PlayStation pad instead of A/B/X/Y — no index remapping
  needed, since PlayStation's face buttons sit in the exact same
  four positions as Xbox's.
- The options menu's Controls section gains a gamepad rebind button
  next to each ability's keyboard one (movement stays on the D-pad/
  stick, not individually remapped, matching convention). Clicking it
  captures the next joypad button press, mirroring the existing
  keyboard-rebind flow exactly (Esc cancels either). Gamepad rebinds
  persist to controls.cfg alongside keyboard ones and survive a
  reload.
- Added a player-facing "Controller Vibration" toggle (Settings...
  Gameplay section) — Controls.vibrate() now checks it alongside the
  existing DP debug flag, so either can silence rumble.

Verified headlessly end-to-end: default bindings show correct
brand-agnostic glyphs (kick=X, dash=A, ...), rebinding kick to a
different button through the real options-menu flow changes only
that action's glyph, leaves its keyboard binding and other abilities'
gamepad bindings untouched, and survives a reload from disk. Sanity-
checked the PlayStation name heuristic against realistic controller
name strings from Xbox, PlayStation (Windows/macOS/Bluetooth
variants), and other brands.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
2026-09-10 19:33:02 +03:00
richard 09d4a60f43 Reorganize into role-based folders and consolidate art
Move every script and scene into role-based directories (actors/, systems/, ui/,
levels/, props/) and all raw art under art/ (grouped by role, snake_case,
Extract-Textures GLBs), dropping Blender version-suffix noise. Filenames are
snake_case (PascalCase reserved for class_name) to avoid case-insensitive
filesystem aliasing on the web/macOS targets. Routes the bull's hits through the
typed DamageEvent pipeline and wires the bull's abilities to the Fx library.
Updates CLAUDE.md's folder-layout overview to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:56:22 +03:00