Skip to content

Implement scribble game scenarios 1 to 4#123

Open
anirudhbs wants to merge 28 commits into
everest-engineering:mainfrom
anirudhbs:assignment
Open

Implement scribble game scenarios 1 to 4#123
anirudhbs wants to merge 28 commits into
everest-engineering:mainfrom
anirudhbs:assignment

Conversation

@anirudhbs

Copy link
Copy Markdown
Member

Summary

Full implementation of a multiplayer Scribble-style drawing and guessing game, built incrementally across four spec-driven scenarios on top of a minimal Express + React starter.

Scenarios

  • Scenario 1 — Room Setup & Lobby: Host flag (isHost) on participants, name trimming + blank-name rejection (frontend inline errors + backend Zod), 404 on unknown room codes, 2-second setInterval polling in
    LobbyPage (with cleanup on unmount), host-only "Start Game" button disabled until ≥ 2 players.

  • Scenario 2 — Game Start & Drawer Flow: POST /rooms/:code/start transitions room to "playing", assigns drawer (first participant by join order) and deterministic secret word (first entry in word list);
    drawer receives secretWord in the snapshot, all others do not; polling in LobbyPage navigates all clients to the Game screen on state change.

  • Scenario 3 — Gameplay Interaction: DrawingCanvas upgraded from a static

    to a real with freehand mouse-event drawing and a "Clear" button; POST /rooms/:code/guess trims input, rejects empty
    with 400, compares case-insensitively to secret word, awards 100 / 0 points, appends to room.guesses; strokes and scores synced to all clients via existing 2-second poll.

  • Scenario 4 — Result, Restart & Final Validation: POST /rooms/:code/end (host-only) transitions to "result"; POST /rooms/:code/restart (host-only) resets to "lobby", clearing
    secretWord/drawerName/guesses/scores/strokes while preserving participants; new ResultPage shows secret word, per-player scores, and full ordered guess history; polling in all three pages handles all state
    transitions.

Notable decisions

  • Host identity via playerName — matched against participants[0].name rather than tokens/cookies; consistent with how guesses and strokes already identify the caller.
  • "result" as a third RoomStatus value — minimal change to the existing union; all consumers already switch on status.
  • Full result data always visible in "result" state — toRoomSnapshot exposes secretWord unconditionally once the round is over; no viewer filtering needed post-game.
  • Scores reset on restart — spec explicitly scoped out cross-round accumulation; simpler data model.
  • 2-second polling retained throughout — no WebSockets; acceptable latency for a local dev game and consistent with what was already in place.
  • Full stroke replay from snapshot — canvas redraws all strokes from the poll snapshot on each tick; no incremental delta sync needed at this scale.

Contributor

anirudhbs and others added 28 commits June 10, 2026 12:12
feat: add isHost to Participant type and tighten playerName validation

- Add isHost: boolean to Participant in backend models and frontend api types
- Update createParticipant() to require name and isHost (removes optional fallback)
- createRoom sets isHost=true, joinRoom sets isHost=false
- Tighten createRoomSchema and joinRoomSchema: trim + min(1) required
- Add Spec Kit artifacts: constitution, spec, plan, tasks, data-model, contracts, quickstart

feat(us1): client-side name validation and host indicator in lobby

- Trim and reject empty player name before API call in CreateRoomPage
- Show "(Host)" label next to the host participant in LobbyPage

feat(us2): client-side name validation and 404 error message on join

- Trim and reject empty player name before API call in JoinRoomPage
- Trim room code before join request
- Map "Unable to join room" 404 response to user-friendly inline error

feat(us3,us4): auto-polling lobby and host-only start game gate

- Add pollRoom() to RoomStore: silent fetch, no loading indicator
- Replace manual Refresh button with setTimeout-after-response polling (2s)
- Polling stops on component unmount via useEffect cleanup
- Derive isHost from participantId; render Start Game only for host
- Disable Start Game until room has >= 2 participants

chore: mark completed tasks in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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