Skip to content

fix(playtest): PLAYER_SEAT core.name + chargen heartbeat dot#162

Merged
slabgorb merged 2 commits intodevelopfrom
fix/playtest-2026-04-25-player-seat-and-chargen-heartbeat
Apr 25, 2026
Merged

fix(playtest): PLAYER_SEAT core.name + chargen heartbeat dot#162
slabgorb merged 2 commits intodevelopfrom
fix/playtest-2026-04-25-player-seat-and-chargen-heartbeat

Conversation

@slabgorb
Copy link
Copy Markdown
Owner

Summary

Two playtest follow-ups from the 2026-04-25 Mawdeep multiplayer session.

  • fix(mp) — PLAYER_SEAT silently no-op'd. The chargen-complete handler read charData.name but the server emits the Pydantic Character.model_dump() which nests as core.name. Without a seat claim, Room.seated_player_ids() stays empty and the multiplayer handshake never fans out. Read core.name first; keep the flat names as fallbacks.
  • feat(ui) — Heartbeat dot in the chargen-commit loading view. The all-text spinner reads as a freeze on a black viewport during the 30-90s narrator window. Mirrors the MultiplayerTurnBanner heartbeat idiom (w-2 h-2 bg-emerald-500 animate-pulse).

Test plan

  • vitest run src/components/CharacterCreation/ — 2/2 pass (new file)
  • Live MP repro: connect two clients to same /play/<slug>-mp, complete chargen, watch server log for session.player_seated player_id=… character_slot=… slug=… (was missing pre-fix). Blocked on the per-player chargen routing bug filed separately in the ping-pong (Player 2 currently auto-claims Player 1's character on slug-connect).
  • Visual: chargen-commit loading view shows the emerald pulsing dot next to "Waiting for the narrator..."

🤖 Generated with Claude Code

slabgorb and others added 2 commits April 25, 2026 01:42
…ires

The seat handshake silently no-op'd in multiplayer playtests. Server
emits character.model_dump(mode="json") whose Pydantic shape nests the
name under `core.name` (Character.core: CreatureCore in
sidequest-server/sidequest/game/character.py:69-94). The chargen-complete
handler in App.tsx was reading the flat `charData.name` /
`charData.character_name`, both undefined for the current emission, so
the `if (charNameForSeat && sendRef.current)` guard fell through and
PLAYER_SEAT was never sent. Server-side never logged
`session.player_seated`, no `mp_seat_span` event, no SEAT_CONFIRMED
broadcast.

Read `core.name` as the primary lookup; keep flat names as fallback for
back-compat with any alternative emission paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Playtest 2026-04-24 flagged the all-text spinner ("Considering your
words..." then "Waiting for the narrator...") as indistinguishable from a
crash — a black viewport with one line of italic text and no other
motion is read as a freeze, especially during the 30-90s
chargen-commit → opening-narration window.

OQ-1's MultiplayerTurnBanner already established the heartbeat idiom
for the in-game state. Mirror it for chargen: a w-2 h-2 emerald
animate-pulse dot next to the loading text. Same shape, same testid
prefix, distinct id (`chargen-heartbeat-dot`) so the two views don't
collide in tests.

CharacterCreation.loading.test.tsx — 2 cases:
  1. default copy renders the heartbeat dot
  2. genre-pack loading_text override still renders the heartbeat

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@slabgorb slabgorb merged commit eb53acd into develop Apr 25, 2026
1 check failed
@slabgorb slabgorb deleted the fix/playtest-2026-04-25-player-seat-and-chargen-heartbeat branch April 25, 2026 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant