Skip to content

upneja/assumption

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pregame.lol

No-auth multiplayer party games — synced across every phone in the room via WebSockets.

One person hosts on a big screen. Everyone else joins on their phone with a 6-letter code. No accounts, no app install, no waiting. Real-time state is pushed to every client over Supabase Realtime the moment anything changes.

Live at pregame.lol


Games

Assumptions

Each player is secretly assigned another person in the room to impersonate. When you hit the hotseat, you answer questions as that person. Everyone else votes on who you were pretending to be.

  • 3–20 players, 15–30 min
  • Phases: LOBBY → ASSIGNMENT → INTRO → WHEEL → HOTSEAT → VOTING → REVEAL → SCOREBOARD → COMPLETE

Guess the Imposter

Civilians know the secret word. Imposters don't. Give clues, sniff out who's faking, vote to eliminate. Imposters win if they reach parity with civilians.

  • 3–20 players, 10–20 min
  • 1 imposter (3–7 players) or 2 imposters (8+)
  • Phases: LOBBY → SECRET_REVEAL → CLUE → VOTING → REVEAL → GAME_OVER

How Real-Time Sync Works

Every game action follows the same pipeline:

Client action (e.g. host clicks "Start Game")
  → HTTP POST to Next.js API route
    → Server validates state transition
      → Postgres write (Supabase)
        → Server broadcasts event on Supabase Realtime channel
          → All subscribed clients receive broadcast
            → React state updates → UI re-renders

Key design decisions:

  • Server-authoritative broadcasts — clients never write to the Realtime channel directly. Only API routes broadcast, which prevents spoofing.
  • self: true on channels — the broadcaster also receives its own event, so all clients (including the host) follow the same update code path.
  • State machine validation — every phase transition is validated server-side against an explicit VALID_TRANSITIONS map before any DB write. Bad requests fail fast with a 400.
  • Session IDs, not auth — players are identified by a UUID stored in localStorage. Zero friction to join, and identity survives page refreshes.
// Supabase Realtime channel (one per room)
supabase.channel(`room:${roomCode}`, {
  config: { broadcast: { self: true } }
})
.on('broadcast', { event: 'room_updated' }, ({ payload }) => {
  setRoom(payload.room);
})
.subscribe();

Tech Stack

Layer Technology
Framework Next.js 16 (App Router)
UI React 19, TypeScript 5, Tailwind 4
Real-time Supabase Realtime (WebSocket pub/sub)
Database Supabase (PostgreSQL)
Mobile Capacitor 7 (iOS/Android)
Testing Vitest, Testing Library, Playwright
Deploy Vercel (web), Capacitor (iOS)

Project Structure

web/
├── src/
│   ├── app/
│   │   ├── page.tsx                  # Home — game picker + room create/join
│   │   ├── room/[code]/              # Assumptions game client
│   │   ├── imposter/room/[code]/     # Imposter game client
│   │   └── api/
│   │       ├── rooms/                # Assumptions REST endpoints
│   │       └── imposter/rooms/       # Imposter REST endpoints
│   ├── components/                   # Phase views (LobbyView, HotseatView, etc.)
│   ├── lib/
│   │   ├── gameEngine.ts             # Pure state machine logic (no I/O)
│   │   ├── realtime.ts               # Supabase Realtime subscriptions
│   │   ├── roomService.ts            # DB read/write helpers
│   │   └── imposterService.ts        # Imposter game DB helpers
│   └── types/index.ts                # Shared TypeScript types
├── supabase/
│   └── schema.sql                    # Full database schema
└── capacitor.config.ts               # iOS/Android build config

API Endpoints

Assumptions

Method Route Auth Description
POST /api/rooms Create room, returns room + host player
POST /api/rooms/[code]/join session Join room
GET /api/rooms/[code] Get room state snapshot
POST /api/rooms/[code]/start host Start game, generate assignments
POST /api/rooms/[code]/spin host Spin wheel, select hotseat player
POST /api/rooms/[code]/vote session Submit vote for hotseat target
POST /api/rooms/[code]/next host Advance phase

Imposter

Method Route Auth Description
POST /api/imposter/rooms Create room
POST /api/imposter/rooms/[code]/join session Join room
GET /api/imposter/rooms/[code] Get room state snapshot
POST /api/imposter/rooms/[code]/start host Start round with topic + secret word
POST /api/imposter/rooms/[code]/vote session Vote to eliminate player
POST /api/imposter/rooms/[code]/advance host Advance phase

All endpoints: return consistent { error, code } on failure, broadcast state update on success.


Local Development

Prerequisites

  • Node.js 18+
  • A Supabase project (free tier works)

Setup

# Clone and install
git clone https://github.com/upneja/assumption.git
cd assumption/web
npm install

# Configure environment
cp .env.example .env.local
# Fill in your Supabase URL and keys

# Run the schema
# Paste web/supabase/schema.sql into the Supabase SQL editor and run it

# Start dev server
npm run dev
# → http://localhost:3000

Environment Variables

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key   # server-side only, never exposed to client

NEXT_PUBLIC_API_URL=                               # leave empty for local dev

Commands

npm run dev           # Dev server on localhost:3000
npm run build         # Production build
npm run lint          # ESLint
npm run test          # Vitest unit tests
npm run test:coverage # Coverage report
npx playwright test   # E2E tests
npm run type-check    # TypeScript check

Deployment

The web app deploys to Vercel automatically on push to main. Add the four environment variables above in the Vercel project settings.

For iOS: see CAPACITOR_SETUP.md.


License

MIT

About

Pregame — no-auth multiplayer party games with realtime sync (pregame.lol)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors