Skip to content

Seat-select navigator (versus / co-op) as an overlay view + WebHID hardening #101

Description

@petegordon

Summary

Build the versus/co-op seat-select navigator as a first-class overlay view (apps/overlay), reusing the controller-core slot lifecycle, and harden the WebHID paths it exercises in packages/core. This replaces the throwaway game-side mockup (tandemonium/tools/lobby-mockup) — the navigator becomes Tandemonium's real lobby and reaches the game via sync-controller-core.

Done (initial branch)

  • New view: apps/overlay/src/lobby.html + src/js/lobby-app.js (sibling to multi.html / multi-app.js).
  • Launch: npm run start:lobby (electron . --lobby; main.js stateKey lobby, LOBBY_WINDOW_SIZE).
  • Interaction on the manager slot lifecycle: press any button → claim slot → seat player; A = ready; B / hold-PS = leave (releaseSlotToPool); ◀▶ = switch team; Start = proceed. Join→ready gate on CHOOSE LEVEL.
  • DualSense lightbar + rumble per seat/team via driver feedback (feature-detected; other pads no-op).

Next: WebHID hardening in packages/core

Surfaced while building the view (renderer jank + unreliable recognition):

  • Steam Controller via Puck: lizard-mode suppression re-probes 5 HID interfaces repeatedly with NotAllowedError: Failed to write feature report, causing ~4s renderer jank. Cache the working interface / stop re-probing. (Direct USB-C pid 0x1302 avoids lizard mode.)
  • DualSense over Bluetooth: compatibility → full-report (0x31) handshake often needs several retries ("full report mode did not start after 5 attempts — gyro unavailable until reconnect").
  • electronAutoRequestDevice fails without a user gesture ("Must be handling a user gesture"); rely on the per-slot pair button + autoPoolApprovedHid, or rework boot pairing.

Notes

Design/UX (independent per-controller join, ready gate, LED/haptic) proven in the game-side mockup and ported.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions