• TypeScript 85.1%
  • PLpgSQL 14.7%
  • JavaScript 0.2%
Find a file
L30n 470b987e3e
All checks were successful
Build & Deploy / web (push) Successful in 8m48s
Build & Deploy / android (push) Successful in 1h45m8s
fix: update forgejo workflows
2026-04-17 18:59:27 +02:00
.forgejo/workflows fix: update forgejo workflows 2026-04-17 18:59:27 +02:00
app feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
assets fix: update forgejo workflows 2026-04-17 18:59:27 +02:00
components feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
lib feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
screens feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
supabase feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
types perf: reduce network round-trips and re-renders. Closes #20 (#31) 2026-04-14 11:36:44 +02:00
.env.example Version 1.0 2026-03-23 14:25:46 +01:00
.gitignore Version 1.0 2026-03-23 14:25:46 +01:00
.npmrc fix: update forgejo workflows 2026-04-17 18:59:27 +02:00
app.json Version 1.0 2026-03-23 14:25:46 +01:00
eas.json feat: Forgejo CI/CD workflow for web and Android deployment 2026-03-25 10:39:42 +01:00
eslint.config.js Version 1.0 2026-03-23 14:25:46 +01:00
package-lock.json feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
package.json feat: fixes after second testplay 2026-04-17 16:08:57 +02:00
README.md Version 1.0 2026-03-23 14:25:46 +01:00
tsconfig.json Version 1.0 2026-03-23 14:25:46 +01:00

Challengers Draft

A mobile app (iOS, Android, Web) as a digital draft companion for the board game Challengers!. Multiple players can create a shared draft session, draw cards from various sets, and build their hand — without physically shuffling and distributing cards.

Features

  • Session system — create or join a session via a 6-character code
  • Real-time sync — all participants see deck changes live via Supabase Realtime
  • Three decks (A / B / C) — correspond to the difficulty tiers in the original game
  • Draft flow — draw 5 cards, pick the ones you want, discard the rest; redrawing is supported
  • Draw to hand — draw a single card directly from a deck into your hand
  • Set selection — admin chooses which of the 14 available sets are included before the draft starts
  • Automatic reshuffle — when a deck runs out, discarded cards are automatically reshuffled back in
  • Card preview — cards are rendered as sprites from the original card illustrations
  • Anonymous authentication — no account required, uses Supabase Anonymous Auth

Tech Stack

Layer Technology
Framework Expo (React Native, New Architecture)
Routing Expo Router (file-based)
Backend Supabase (Postgres, Auth, Realtime)
Language TypeScript
Platforms iOS, Android, Web

Prerequisites

  • Node.js >= 18
  • Expo CLI (npm install -g expo-cli)
  • Supabase CLI (for local development)
  • A Supabase project (cloud or local)

Setup

1. Install dependencies

npm install

2. Set environment variables

Copy .env.example to .env and fill in your values:

cp .env.example .env
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

3. Set up the database

Run migrations against your Supabase project:

supabase link --project-ref <your-project-ref>
supabase db push

Alternatively, run locally with supabase start and then supabase db reset.

4. Start the app

npm start          # Expo dev server (QR code for Expo Go)
npm run ios        # iOS Simulator
npm run android    # Android Emulator
npm run web        # Browser

Project Structure

.
+-- app/
|   +-- _layout.tsx          # Root layout, anonymous authentication
|   +-- index.tsx            # Home screen: create / join session
|   +-- session/
|       +-- [id].tsx         # Session route (lobby or draft depending on status)
+-- screens/
|   +-- SessionLobby.tsx     # Waiting room: participants, set selection, start draft
|   +-- SessionDraft.tsx     # Draft view: draw cards, pick, manage hand
+-- components/
|   +-- SpriteCard.tsx       # Renders a card from a sprite sheet
+-- lib/
|   +-- supabase.ts          # Supabase client
|   +-- session.ts           # Session actions (offerCards, keepCards, ...)
|   +-- types.ts             # Shared TypeScript types
+-- supabase/
|   +-- migrations/
|       +-- ..._schema.sql   # Tables, enums, RLS policies, Realtime
|       +-- ..._card_data.sql# Card data for all sets
|       +-- ..._rpcs.sql     # SECURITY DEFINER functions
+-- assets/
    +-- images/              # Sprite sheets (sheet_game_cards-0..3.jpg)
    +-- icons/               # App icons, splash screen

Database Schema

users           id, name
sessions        id, code, admin_id, status (waiting | drafting | finished)
participants    id, session_id, user_id
card_types      id, sheet, row, column, count, set, level (S|A|B|C)
card_assignment id, card_type_id, owner, session_id, card_position (deck|offered|player|discarded)

All write operations on card_assignment and sessions go exclusively through SECURITY DEFINER RPCs; the tables themselves are read-only for the client via RLS.

RPCs

Function Description
create_session(code) Creates a session and adds the creator as admin participant
initialize_draft(session_id, sets) Admin: inserts all cards as deck cards, sets status to drafting
offer_cards(session_id, level, count) Draws N random cards from a deck (idempotent)
keep_cards(session_id, card_ids) Moves offered cards into the player's hand
discard_cards(session_id, card_ids) Discards cards (offered or player -> discarded)
leave_session(session_id) Player leaves; transfers admin role or deletes session if last player
delete_session(session_id) Admin: deletes session including all dependent data (CASCADE)

Card Sets

14 sets are available (corresponding to the Challengers! expansions):

City Rainbow Castle Fairground Space Film Studio Haunted House Shipwreck Enchanted Forest Toy Store Mountain Peak Secret Lab University Beach Club

Draft Flow

  1. Players open the app — anonymous auth happens automatically
  2. Enter a name, then create a session or join one via code
  3. Lobby: admin selects sets and starts the draft
  4. Draft: each player draws cards independently
    • Choose a deck -> 5 cards are offered
    • Tap desired cards (highlighted in blue)
    • Keep & discard: confirm selection, the rest go to the discard pile
    • Redraw: keep already selected cards, draw new ones for the rest
    • +1 Hand: draw one card directly into your hand (no offer shown)
    • Remove a card from hand: tap the red X on the card
  5. When a deck runs empty, discarded cards are automatically reshuffled back in

Deployment

Builds are created via EAS Build:

eas build --platform ios
eas build --platform android

The EAS project configuration lives in eas.json.