Skip to content

Scribble app#92

Open
GaddamMeghana29 wants to merge 11 commits into
everest-engineering:mainfrom
GaddamMeghana29:scribble-app
Open

Scribble app#92
GaddamMeghana29 wants to merge 11 commits into
everest-engineering:mainfrom
GaddamMeghana29:scribble-app

Conversation

@GaddamMeghana29
Copy link
Copy Markdown

@GaddamMeghana29 GaddamMeghana29 commented Jun 4, 2026

Summary

Implements all four gameplay scenarios for the Scribble multiplayer drawing-and-guessing assignment on top of the provided starter, following the Spec Kit workflow (specify → clarify → plan → tasks → implement) for each scenario.

  • Scenario 1 — Room Setup & Lobby: Create/join rooms, lobby participant list, host-only Start Game gate, minimum 2-player validation
  • Scenario 2 — Game Start & Drawer Flow: Host starts game, drawer sees secret word, guessers see underscores, Lobby polls and auto-redirects to Game screen
  • Scenario 3 — Gameplay Interaction: Drawer draws freehand strokes on canvas (normalized coordinates, one POST per stroke); guessers submit text guesses with immediate correct/incorrect feedback; shared live guess history for all players; ~2 s polling throughout
  • Scenario 4 — Game End & Results: Correct guess atomically transitions room to "ended"; all players auto-redirect to Results screen via polling; Results screen reveals secret word, names winner, shows full guess history; host can Play Again (resets to lobby, all players redirect automatically); non-host sees waiting message

Architecture

  • Backend: Express 5 + TypeScript; in-memory Map<string, Room>; Zod schema validation; Vitest unit tests
  • Frontend: React 18 + TypeScript + Vite; React Router v6; HTTP polling at ~2 s intervals (no WebSockets per constitution)
  • State: All game state in-memory — RoomStatus extended to "lobby" | "game" | "ended"

Key changes

Area Changes
backend/src/models/game.ts Added StrokePoint, Stroke, GuessEntry interfaces; extended Room + RoomSnapshot; added "ended" to RoomStatus
backend/src/services/roomStore.ts addStroke(), submitGuess() (with atomic game-end), resetRoom(); updated toRoomSnapshot() to reveal word when ended
backend/src/api/rooms.ts Added POST /:code/strokes, POST /:code/guesses, POST /:code/reset route handlers
backend/src/services/roomStore.test.ts 46 unit tests covering all service functions and error paths
frontend/src/pages/GamePage.tsx Canvas drawing (pointer events, normalized coords), polling, guess input, guess history, redirect on "ended"
frontend/src/pages/ResultsPage.tsx New page: revealed word, winner, guess history, Play Again (host) / waiting message (non-host), polling
frontend/src/routes/index.tsx Added /results route
frontend/src/services/api.ts Added addStroke(), submitGuess(), resetRoom() API methods; updated RoomStatus type
specs/ Full Spec Kit artifacts for all four scenarios (spec, plan, research, data-model, contracts, quickstart, tasks)

Test plan

  • cd backend && npm run build — zero TypeScript errors
  • cd frontend && npm run build — zero TypeScript errors
  • cd backend && npm test — 46/46 tests passing
  • Two-browser-tab manual verification per specs/004-game-end-results/quickstart.md:
    • Tab A (Alice = host/drawer), Tab B (Bob = guesser)
    • Draw strokes → appear in Tab B within ~2 s
    • Submit incorrect guess → stays on Game screen
    • Submit correct word → both tabs redirect to Results within ~2 s
    • Results screen shows word, winner, history; survives page refresh
    • Host clicks Play Again → both tabs redirect to Lobby within ~2 s
    • New game starts cleanly from Lobby

Contributor

GaddamMeghana29 and others added 11 commits June 3, 2026 14:49
- Fix VITE_API_URL default (removed /bug suffix)
- Add isHost flag to Participant model and propagate through store
- Update room code format to 4 uppercase letters (A-Z only)
- Tighten playerName validation: trim + min-length via Zod
- Add case-insensitive duplicate name rejection (409 on join)
- Add startRoom() with host-only gate and 2-player minimum
- Add POST /rooms/:code/start route with error mapping
- Replace manual Refresh button with 2s polling in LobbyPage
- Show host badge and conditional Start Game / waiting message
- Add 16 unit tests covering all four user stories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extend RoomStatus to include "game" state
- Add drawerId and currentWord to Room model
- startRoom() mutates room: sets status, assigns drawer, selects word
- toRoomSnapshot() filters currentWord for non-drawers; adds wordLength
- createRoom() initialises drawerId/currentWord to null
- LobbyPage auto-redirects to /game when room.status === "game"
- GamePage: one-time fetch on mount; shows drawer identity and word
- Drawer sees secret word; guessers see underscore placeholder
- sessionStorage persists participantId across page refreshes
- 24 backend unit tests passing; both builds clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…essing, history)

- Add Stroke/GuessEntry entities to Room model and RoomSnapshot
- Implement addStroke() and submitGuess() service functions with validation
- Add POST /rooms/:code/strokes and POST /rooms/:code/guesses API routes
- Upgrade GamePage from one-time fetch to ~2s setInterval polling
- Implement HTML5 Canvas drawing for drawer (normalized coords, one POST per stroke)
- Add guess input with immediate isCorrect feedback and page-refresh restoration
- Add chronological guess history visible to all players
- 36 unit tests passing (12 new for addStroke/submitGuess/snapshot assertions)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extend RoomStatus with "ended" state; submitGuess() atomically
  transitions the room to "ended" when a correct guess is recorded
- Modify toRoomSnapshot() to reveal currentWord to all players when
  status is "ended" (word is no longer hidden after game concludes)
- Add resetRoom() (host-only) that resets room to "lobby" and clears
  strokes, guesses, drawerId, and currentWord while preserving participants
- Add POST /rooms/:code/reset route and resetRoomSchema for Play Again
- Add api.resetRoom() to frontend API client
- Add ResultsPage (/results): shows revealed word, winner name, and
  complete guess history; host sees Play Again button, others see
  waiting message; polls every ~2 s and redirects to /lobby on reset
- GamePage now redirects to /results when polling detects status === "ended"
- Update existing already_correct test: after a correct guess the room
  is "ended", so a second attempt returns not_in_game (not already_correct)
- Add 10 new unit tests covering game-end transition, word reveal,
  and resetRoom happy/error paths (46 tests total, all passing)
- Add Scenario 4 spec, plan, research, data-model, contracts, quickstart,
  and tasks artifacts in specs/004-game-end-results/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers all four scenarios, key technical decisions (atomic game-end,
polling-only real-time, snapshot word-reveal), and the Spec Kit
workflow experience. Fixes the pre-evaluation CI failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Organised around what the starter had, what was added per scenario,
the Spec Kit workflow, and what I'd do differently next time.

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