Skip to content

Repository files navigation

Skyjo Action — Online Multiplayer

Play Skyjo Action with friends remotely. Built with Next.js, Supabase, and Web Push notifications.

Features

  • 🃏 Full Skyjo Action rules (action cards: -2 flip, -1 swap, 0 peek)
  • 🔄 Real-time board updates via Supabase Realtime
  • 🔔 Browser push notifications when it's your turn
  • 🎮 2–6 players per game
  • 📱 Works on desktop and mobile
  • 🔗 Invite friends with a shareable link or 5-letter code

Setup

1. Clone & Install

git clone <your-repo>
cd skyjo
npm install

2. Create a Supabase Project

  1. Go to supabase.com and create a free project
  2. Run the SQL in supabase/migrations/001_init.sql in the SQL Editor
  3. Copy your project URL and keys from Settings → API

3. Generate VAPID Keys (for push notifications)

npx web-push generate-vapid-keys

Copy the output into your .env.local.

4. Environment Variables

cp .env.local.example .env.local

Fill in:

NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
NEXT_PUBLIC_VAPID_PUBLIC_KEY=BF...
VAPID_PRIVATE_KEY=xxx...
VAPID_EMAIL=you@example.com

5. Run Locally

npm run dev

Visit http://localhost:3000


Deploy to Vercel

npm i -g vercel
vercel

Add all the environment variables from .env.local to your Vercel project settings.

For push notifications to work in production, Vercel must be on HTTPS (it is by default).


How to Play

  1. Host creates a game and shares the 5-letter code (or link)
  2. Friends join via the code at the home page or the invite link
  3. Once everyone is in, the host clicks Start Game
  4. Each player starts with a 3×4 grid of face-down cards
  5. On your turn:
    • Draw from the deck or take the top discard
    • Either place it on your grid (replacing one card) or discard it and flip one of your own face-down cards
  6. Action cards (placed):
    • -2: Flip one opponent's face-up card face-down
    • -1: Swap one of your cards with an opponent's
    • 0: Peek at any face-down card privately
  7. Completing a column: Three identical face-up values in a column → that column is removed!
  8. End of round: When a player has all cards face-up, everyone else gets one more turn. If the triggering player doesn't have the lowest score, their score is doubled.
  9. Game ends when any player reaches 100 points. Lowest total wins!

Project Structure

app/
  page.tsx                  # Home: create / join
  lobby/[gameId]/page.tsx   # Waiting room
  join/[gameId]/page.tsx    # Friend invite landing
  game/[gameId]/
    page.tsx                # Main gameplay
    results/page.tsx        # Final scores
  api/
    game/
      create/route.ts       # POST: new game
      join/route.ts         # POST: join game
      start/route.ts        # POST: start (deal cards)
      action/route.ts       # POST: all turn actions
    push/route.ts           # Push subscription save
components/
  GameCard.tsx              # Card, DrawPile, DiscardPile
  PlayerGrid.tsx            # 3×4 grid for each player
  Scoreboard.tsx            # Running scores table
lib/
  game-logic.ts             # Pure game rules (deck, scoring, columns)
  types.ts                  # TypeScript types
  supabase.ts               # Browser client
  supabase-server.ts        # Server client (service role)
  push.ts                   # web-push wrapper
public/
  sw.js                     # Service worker for push
supabase/
  migrations/001_init.sql   # DB schema

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages