Skip to content

Repository files navigation

🎲 The Spillway

(formerly Party Pack)

Nine social-deduction and party games in one server. Everyone plays from their phone; one player hosts a room and shares a 4-letter code.

Game Players One-liner
🐺 One Night Werewolf 3–10 Secret roles, one night of chaos, vote out the wolf
🕵️ Spyfall 3–10 Everyone knows the location — except the spy
🃏 Coup 2–6 Bluff your way to the last influence standing
🔤 Codenames 4–10 Spymasters give one-word clues to their team
⚔️ Avalon 5–10 Good vs. evil, missions and hidden traitors
🐟 Fishbowl 4–12 Taboo → one word → charades, same phrases
🎲 Liar's Dice 2–8 Bid on everyone's hidden dice, call the liar
💰 Wits & Wagers 3–10 Guess the number, then bet on the best guess
🏦 QE 3–5 Blind-bid auctions with unlimited money — spend the most and lose

Play

One player taps Host a new room and reads out the 4-letter room code; everyone else joins with it. The host picks the game in the lobby. Rooms are independent — any number of parties can play at once.

Disconnects are forgiving: a dropped phone has 15 seconds to reconnect (it happens automatically when the page regains network) and rejoins mid-game right where it left off.

Run it

npm install
npm start          # http://localhost:3000, or PORT=xxxx

Deploy (Render free tier)

render.yaml is a ready Render blueprint: New + → Blueprint → point at this repo. The server reads PORT from the environment. Free-tier note: the instance sleeps when idle (first visit takes ~50s) and a sleep drops all active rooms.

Travel / LAN mode (no internet needed)

The server also runs happily on a laptop or Mac mini at a party with no internet — everyone joins the machine's LAN address. Two macOS-only extras for that mode:

  • SPEAK_IP=1 makes the machine speak its IP address through its speaker every 5 minutes until the first player joins (for when .local mDNS won't resolve on guests' phones).
  • Any unmatched URL serves the game page, so captive-portal probes auto-open the lobby when the box runs as its own access point.

Architecture

File Role
server.js Express + Socket.IO. Room registry + a createRoom() factory — each room owns its players, phase, game state, and timers. Sessions are token-based (survive reconnects); empty rooms self-destruct after 5 minutes.
games/*.js One module per game: meta, validateSetup, initGame, per-player state projection (getStateFor), action handlers, computeGameResult. Modules are pure-ish — they operate on a passed game-state object and never touch sockets.
public/index.html The whole client: one page, one screen per phase.
sim.js Headless Monte-Carlo harness (Werewolf): drives full games via socket.io-client and verifies win-conditions. ROOM_CODE=XXXX joins an existing room to play alongside humans; optional Ollama-backed LLM players.

Adding a game

Write games/yourgame.js exporting the module contract above, register it in the GAMES map and GAME_LIST in server.js, and add a screen + socket handlers in public/index.html. Grep for one of the smaller existing games (qe, liarsdice) as a template.

About

Nine party games on phones — Werewolf, Spyfall, Coup, Codenames, Avalon, Fishbowl, Liar's Dice, Wits & Wagers, QE. One server, room codes.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages