Baloot Lens
A mobile-first PWA that plays referee (حكم) for a physical Baloot table: players deal and play with real cards while the app tracks turns, detects plays via GPT-4o Vision, enforces Saudi Baloot rules (32-card deck, Hokm scoring, projects), and keeps a live scoreboard. Built with Next.js, TypeScript, Neon Postgres, and Drizzle ORM, tuned for an Arabic-first RTL experience.
A full-table scorekeeper for Baloot: four players sit with real cards, the app watches the table through the phone camera, detects cards with GPT-4o Vision, enforces Saudi Baloot rules (32-card deck, Hokm, projects like Abat, Tams, and Sawa, plus the Baloot bonus), and tallies the score automatically — no manual entry. The referee (حكم) is now software.
What it solves
- Keeping score in Baloot manually is error-prone — players argue over trick totals and project scoring.
- Saudi Baloot has complex rules: 32-card deck, trump scoring, five project types, and Baloot bonus. No referee app existed before.
- Mobile apps for Baloot either play AI, or are boring scorekeepers. None watch a live table and detect plays automatically.
Impact
GPT-4o Vision (optional)
32-card Saudi Baloot
Real-time trick & project tracking

Architecture
Data flow
- Four players sit at table with physical cards
- Setup: player names + seats → teams
- Deal 8 cards per player (32-card deck)
- Hokm declaration (player picks trump suit)
- Phone camera captures table (optional)
- GPT-4o Vision detects cards + confidence
Or manual entry
- Baloot engine validates move (follow-suit, overtrump)
- Trick winner resolved + stored in Postgres
- After 8 tricks: applyProjects() scores round
Abat, Tams, Sawa, Baloot bonus
- Live scoreboard updates in real-time
Engineering decisions
Pure rules engine (no side effects)
The Baloot engine in lib/baloot/engine.ts has zero dependencies on DB, React, or Date. This makes new project types and rule variants unit-testable in isolation, and lets the engine be ported to native mobile later.
GPT-4o Vision for optional card detection
Instead of training a custom detector, use GPT-4o Vision to detect cards from a phone snapshot with confidence scores. If OPENAI_API_KEY is unset, players manually enter plays. No hard dependency.
Server actions for all DB mutations
Game state changes are only made via Next.js Server Actions in lib/actions/game.ts. Prevents client-side cheating (e.g., manually changing scores) and keeps the engine as the source of truth.
Arabic-first RTL by default
Root layout sets lang="ar" dir="rtl"; all UI is in Arabic with English subtitles. Tailwind logical properties (ms-*, me-*) handle RTL/LTR flipping automatically.
Offline-tolerant with optional Postgres
If DATABASE_URL is unset, the app still runs in-memory — perfect for testing at the table without a DB. Persistence is optional, not mandatory.
Gallery


