Who Said That? — game backend (Go) + web client (React). Spec/content live in mercury/WhoSaidThat.
  • Go 61.4%
  • TypeScript 37.4%
  • Shell 0.4%
  • Dockerfile 0.3%
  • CSS 0.3%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-11 15:35:29 -04:00
backend Add Docker build + docker-compose with SPA file serving 2026-09-11 15:09:38 -04:00
scripts M0: lobby skeleton — Go backend (create/join/state + WS broadcast) + React frontend (Home/Lobby views) 2026-09-02 12:17:56 -04:00
web Session 4: server-random superlatives, result/scoreboard updates, timer extension, decoy guess fix 2026-09-11 01:55:29 -04:00
.gitignore M0: lobby skeleton — Go backend (create/join/state + WS broadcast) + React frontend (Home/Lobby views) 2026-09-02 12:17:56 -04:00
analyses.md Session 3 cleanup and bug fixes 2026-09-10 22:04:19 -04:00
BUG_FIX_CHECKLIST.md Session 3 cleanup and bug fixes 2026-09-10 22:04:19 -04:00
CONTEXTMAP.md Session 4: server-random superlatives, result/scoreboard updates, timer extension, decoy guess fix 2026-09-11 01:55:29 -04:00
CURRENT.md Session 4: server-random superlatives, result/scoreboard updates, timer extension, decoy guess fix 2026-09-11 01:55:29 -04:00
DECISIONS.md Session 4: server-random superlatives, result/scoreboard updates, timer extension, decoy guess fix 2026-09-11 01:55:29 -04:00
docker-compose.yml docker-compose: env vars for port/deck/network; add sample.env 2026-09-11 15:35:29 -04:00
Dockerfile Add Docker build + docker-compose with SPA file serving 2026-09-11 15:09:38 -04:00
README.md docker-compose: env vars for port/deck/network; add sample.env 2026-09-11 15:35:29 -04:00
sample.env docker-compose: env vars for port/deck/network; add sample.env 2026-09-11 15:35:29 -04:00

Who Said That? — Game App

The app for Who Said That? — a private, friends-only online party game. A question appears, everyone writes a funny answer, then players drag guesses of who wrote what and vote a superlative ("Classic Karl", "Grossest"…). Loaded Questions / Fibbage hybrid — zero right answers, low-stakes hang.

This repository contains the application (backend + web client). The game design spec, question content, and validation pipeline live in the companion content repo:

Quickstart (local dev)

Backend (Go, :8080):

cd backend
go build -o /tmp/wst-server ./cmd/server/ && /tmp/wst-server

Deck files: By default the server loads data/deck.json (Reddit-sourced questions). A separate Caleb-authored deck with 50 questions across 4 categories is available at data/questions_caleb.json. Use it instead:

DECK_PATH=data/questions_caleb.json go run ./cmd/server

All categories are shuffled together each round — you'll get variety automatically. Both files use the same v2 schema so swapping is zero-config.

Frontend (Vite, :5173 — proxies /api and /ws to :8080):

cd web
npm install
npx vite --host

Open http://localhost:5173. Create a room, share the code, join from another browser. Only port 5173 needs forwarding if you're testing from another machine (Vite proxies the backend).

Current gameplay behavior (2026-09-11 playtest build)

  • Superlative is chosen randomly by the server each round (13-entry list) and shown to all players during the answer phase — no picker.
  • Clicking the timer in any phase adds 15 seconds (extend_timer).
  • Result phase: 60s timer, "Next Round →" bypasses it; each answer shows who guessed it correctly vs. wrong; scoreboard shows this-round points + cumulative total with tie-aware medals.
  • Deck: questions_caleb.json (50 Q / 4 decks) is copied from the user's working file — see CONTEXTMAP.md for the exact path. No mapping file.

Project docs — read these first

File Purpose
CURRENT.md Live state — what's done, what's next. READ FIRST.
CONTEXTMAP.md Where everything lives.
DECISIONS.md Why it's built this way (app-level decisions).
README.md This file.

Docker (quick start on another machine)

git clone <repo-url> whosaidthat-app
cd whosaidthat-app

# Optional: customize with a .env file (see sample.env)
cp sample.env .env
docker compose up -d

Open http://localhost:8206. The container serves the frontend and API on a single port — no separate frontend dev server needed. Uses the questions_caleb.json deck by default.

.env file — copy sample.env to .env to customize:

Variable Default Description
QUESTIONS_FILE data/questions_caleb.json Question deck file (relative to backend/data/)
PORT_UI 8206 Host port mapped to container's :8080
NETWORK_NAME (none) External Docker network (for Caddy in separate compose)

Container env vars (set automatically, but can be overridden):

Variable Default Description
PORT 8080 Backend listen port (inside container)
WEB_DIR web/dist Static frontend directory
WST_DISCONNECT_DROP 30s Drop disconnected lobby players after this
WST_SWEEP_INTERVAL 10s How often to sweep stale lobby connections

To use the original Reddit-sourced deck instead, set QUESTIONS_FILE=data/deck.json in your .env.

Game-design decisions (rules, scoring, anti-cheat) live in the content repo's decisions.md — that's the design ledger. This repo's DECISIONS.md covers app-architecture choices (stack, repo layout, persistence).

Repos at a glance

  • mercury/WhoSaidThat (content, private): spec, decisions, scrape.py → data/deck.json, validation/ webapp.
  • mercury/whosaidthat-app (app, public): backend/ Go, web/ React.