It's not just probability. It's psychology, tension, and the right call at the wrong moment.
A real-time multiplayer strategy and risk game inspired by the aesthetics of underground casinos and cyberpunk corporate terminals.
Risk Bag is a digital, real-time multiplayer board game. Players take on the role of hackers at a high-stakes betting table, where every round demands a choice: pull more components from the bag, or walk away with what you already have before everything blows up.
Greed kills. But playing it too safe leaves you without resources. You decide.
Note: The game works best on stable connections. Since all state is synchronized in real time via Supabase, unstable networks may cause delays between players.
| Feature | Description |
|---|---|
| ⚡ Real-Time Sync | Table state synchronized instantly for all players via Supabase Realtime. |
| 🃏 Card System | Inventory items rendered as TCG-style playing cards with icons, types, and hover animations. |
| 🛒 Black Market | Between-round crafting phase with a 60-second timer — buy weapons, heals, and utilities with your resources. |
| 💥 Visual Feedback | Screen shake on damage, glitch effect on area attacks, card flash animation when drawing from the bag. |
| 🔊 Synthesized Audio | Sounds generated via Web Audio API — no external files, zero latency. |
| 🎲 Fair Turn Order | First player of each match and each round's opener are randomly drawn. |
| 📋 Match Log | Real-time event terminal and full podium with match history at game over. |
| 📱 Responsive | Interface optimized for both desktop and mobile. |
Lobby (all players mark Ready)
│
▼
Round begins with a randomly drawn player
│
▼
Your turn: Draw from the bag ──► Good material? → stacks in your hand
│ Short-Circuit? → 1 is fine, 2 = 💥 -1 HP
│ Virus? → 1 is fine, 2 = 🦠 lose your turn
▼
Pass turn → materials go to the Vault, threats return to the Bag
│
▼
All players played once → Black Market (60s) → craft items with resources
│
▼
New round with a different starter → repeats until 1 player remains
| Item | Type | Effect |
|---|---|---|
| 🛡️ Firewall | Defense | Absorbs 1 lethal hit or attack. Breaks after use. |
| 💉 Sec. Patch | Heal | Instantly recovers +1 HP. |
| 🌐 VPN | Utility | Safely skips your turn, keeping all gathered materials. |
| 🔁 Reboot | Utility | Returns 2 Short-Circuits/Viruses from your hand to the Bag. |
| 🎯 Trojan | Attack | Forces an enemy to draw 3 times on their next turn. |
| 📡 Phishing | Attack | Steals 2 resources from an enemy's vault. |
| 💀 Zero-Day | Fatal | Instantly removes 1 HP from a target. |
| 🌐 DDoS Attack | Fatal | Applies +2 forced draws to ALL enemies. |
| 🔒 Ransomware | Fatal | Steals 1 HP from a target (heals you simultaneously). |
| 💣 Logic Bomb | Fatal | Deals 1 damage to EVERYONE (including you). Ignores Firewall. |
| Home Screen | Lobby |
|---|---|
![]() |
![]() |
| Game Table | Black Market |
![]() |
![]() |
- Framework: Next.js 15 (App Router) + TypeScript
- Database / Realtime: Supabase (PostgreSQL + Realtime subscriptions)
- Styling: Tailwind CSS + CSS custom properties
- Animations: Framer Motion
- Icons: Lucide React
- Audio: Web Audio API (native synthesizer, no external assets)
- Deployment: Vercel (automated CI/CD via GitHub)
- Race Conditions: Turn logic performs a fresh database read before every write to prevent conflicts when multiple players interact with the bag simultaneously.
- Unwanted Scroll: The terminal's
scrollIntoViewwas moving the entirewindow. Fixed by usingscrollTopdirectly on the inner container. - Fair Turn Order: A shuffled
turn_orderarray is persisted in the database with a rotating index between rounds, ensuring no player opens two consecutive rounds. - Synchronized Timer: Local 60-second countdown in the Black Market with safe
clearIntervalcleanup and automatic fallback tohandleFinishCrafting.
# 1. Clone the repository
git clone https://github.com/samu-lls/saco-de-risco.git
# 2. Install dependencies
npm install
# 3. Set up environment variables
cp .env.example .env.local
# Edit .env.local with your Supabase credentials:
# NEXT_PUBLIC_SUPABASE_URL=your_url
# NEXT_PUBLIC_SUPABASE_ANON_KEY=your_key
# 4. Start the development server
npm run devOpen http://localhost:3000, launch two tabs with different player names, and create a room to test multiplayer locally.
risk-bag/
├── app/
│ ├── page.tsx # Home screen and login
│ ├── layout.tsx # Root layout
│ ├── globals.css # Design system and animations
│ └── room/[code]/
│ └── page.tsx # Full match logic
├── components/
│ ├── PlayerPanel.tsx # Player card with TCG inventory
│ ├── ShopCard.tsx # Black Market item card
│ └── TerminalLog.tsx # Real-time event terminal
└── lib/
├── items.ts # Definitions for all 10 game items
├── patchnotes.ts # Version history (editable)
├── sounds.ts # Audio synthesizer via Web Audio API
└── supabase.ts # Configured Supabase client
I'm Samuel, an IT Analyst and tech enthusiast. I built Risk Bag as a personal project to explore real-time synchronization, game system design, and the intersection between software engineering and user experience.
If you want to talk development, games, or tech setups, let's connect.



