Skip to content

vviseguy/frequency

Repository files navigation

๐Ÿ“ก Frequency

A peer-to-peer party game in the spirit of Wavelength. One player (the Psychic) sees a hidden target on a spectrum between two odd extremes โ€” "Hot โ†” Cold", "Culturally significant โ†” insignificant" โ€” gives a short clue, and the team drags a live shared dial to guess it. Closer = more points. Psychic rotates every round. Big celebratory finale. Then back to the lobby.

No server. No database. No accounts. No setup. Just open the page and play.

๐ŸŽฎ Play: https://vviseguy.github.io/frequency/

How to play

  1. One person taps Host a new game โ†’ gets a 4-letter room code + QR + share link.
  2. Everyone else opens the link (or enters the code) on their phone.
  3. The host taps Start โ€” no settings to fiddle with.
  4. Everyone writes a clue at the same time for their own hidden target on a weird spectrum.
  5. The game then cycles through each player's clue: everyone else drags the shared dial and taps Lock it in; the target is revealed and the clue-giver scores by how close the group got.
  6. Game length auto-scales with the room โ€” smaller groups give more clues each (3 per person โ‰ค4 players, 2 per person โ‰ค8, 1 in big groups). No options to set.
  7. A scoreboard breather between sets, then an animated recap builds to the champion and everyone bounces back to the lobby.
  • Hosting auto-falls-back: if the host closes their tab/loses signal, the most senior player (earliest to join) seamlessly becomes the new host and the game continues. Keep the host on a device that won't sleep for the smoothest ride.
  • Reactions (๐Ÿ˜‚๐ŸŽ‰๐Ÿ”ฅ) pop a sound and rain that emoji across everyone's screen โ€” a small budget per turn so it never gets noisy.
  • Top-left menu (the โ˜ฐ): light/dark mode, sound on/off, how-to-play, and leave-game. The drifting background calms to a freeze during focused play.

Editing the prompts

Prompts are organised into versioned topic packs under public/prompts/ โ€” currently 22 packs, ~880 spectrum pairs. The host can pick which topics are in play from the lobby (๐ŸŽฒ Topics).

  • prompts/index.json โ€” lists which pack ids are active.
  • prompts/<id>.json โ€” one topic pack: { name, emoji, version, prompts }.

To add prompts: open a pack file on GitHub, append a line, bump its version, commit to main. No IDs to manage โ€” they're derived automatically.

{ "left": "One extreme", "right": "The other extreme" }

To add a whole topic: drop a new prompts/<id>.json (same shape, with a name and an emoji) and add its id to prompts/index.json. It shows up as a card in the topic picker automatically. The site auto-redeploys in ~1 minute.

Local development

npm install
npm run dev      # http://localhost:5173/frequency/  (also exposed on your LAN for phone testing)
npm run build    # typecheck + production build into dist/
npm run preview  # serve the production build locally

To test multiplayer locally, open the dev URL in several browser tabs/devices โ€” create a room in one, join with the code in the others.

Tests

npm test          # Vitest unit suite (scoring, reducer/state machine, rounds, room codes, migration)
npm run test:e2e  # Playwright: real multi-peer WebRTC e2e against a local PeerJS broker

The e2e suite spins up its own local PeerJS server (no public broker, fully deterministic) and drives three isolated browser contexts through: a complete 2-round game (host โ†’ join โ†’ clue โ†’ guess โ†’ reveal โ†’ recap โ†’ lobby) and a host-migration scenario (kill the host mid-lobby; assert the most-senior player takes over and can keep running the game). CI runs both via .github/workflows/ci.yml, separate from the Pages deploy so a flaky network never blocks shipping.

Networking notes (optional)

P2P uses PeerJS's free public broker for signaling only; gameplay traffic is direct WebRTC between devices. Two situational env vars (create a .env file) help on hostile networks:

Var Purpose
VITE_TURN_URL / VITE_TURN_USER / VITE_TURN_CRED A TURN relay for strict/cellular NATs where direct WebRTC fails.
VITE_PEER_HOST / VITE_PEER_PORT / VITE_PEER_PATH Point signaling at your own self-hosted PeerServer instead of the public broker.

Neither is needed for normal play (same Wi-Fi / typical home networks).

Deployment

Push to main โ†’ GitHub Actions builds and publishes to GitHub Pages (.github/workflows/deploy.yml). Vite base is /frequency/; routing keys off the ?room= query so deep links survive a hard refresh.

Built with React + TypeScript + Vite + Tailwind + Framer Motion + PeerJS.

About

๐Ÿ“ก Frequency โ€” a peer-to-peer Wavelength-style party game. Zero backend, plays on phones.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages