This document details the architecture of the Royal Game of Ur project, focusing on its AI engine, frontend, deployment, and infrastructure.
This implementation stands out for several reasons:
- Ancient Game, Modern Tech: Brings a 4500-year-old game to life with cutting-edge web technologies
- Dual AI System: Features both a classic expectiminimax AI and a neural network AI, each with distinct playstyles
- Browser-Native AI: All AI runs locally in your browser via WebAssembly - no server calls needed
- Offline-First: Works completely offline once loaded, perfect for mobile or unreliable connections
- Performance: Rust-compiled AI provides desktop-level performance in the browser
- Evolutionary Architecture: Successfully migrated from hybrid client/server AI to pure client-side execution
- High Performance: Rust and WebAssembly for AI
- Offline Capability: Fully playable without internet
- Seamless UX: Modern, responsive UI
- Maintainability: Clear separation of UI, logic, and AI
- UI Components:
src/components/(React, Tailwind, Framer Motion) - State Management:
src/lib/game-store.ts(Zustand + Immer) - Game Logic:
src/lib/game-logic.ts(pure functions) - AI Services:
src/lib/wasm-ai-service.ts(Classic AI),src/lib/ml-ai-service.ts(ML AI) - Database:
src/lib/actions.ts(save games) - Statistics:
src/lib/stats-store.ts
- Classic AI: Rust, expectiminimax, compiled to WebAssembly
- ML AI: Rust, neural network, compiled to WebAssembly
- Performance: All AI runs locally in the browser (no server calls)
- Architecture: Pure client-side execution via Web Workers
The project has evolved from a hybrid client/server architecture to a pure client-side implementation:
Original Design (Early Development):
- AI computation could run on either client (WASM) or server (Cloudflare Worker)
- Server-side AI provided backup and potential performance benefits
- More complex deployment and infrastructure requirements
Current Design (Production):
- All AI computation runs client-side via WebAssembly workers
- Eliminates network latency and server infrastructure costs
- Enables true offline play without server dependencies
- Simplified deployment and reduced attack surface
Preserved Infrastructure:
- Cloudflare Worker code remains in
worker/src/lib.rsfor potential future use - Server-side AI endpoints (
/ai-move,/health) are inactive but available - Architecture supports easy reactivation if server-side features are needed
RoyalGameOfUr.tsxdetects AI turn- Calls
makeAIMoveingame-store.ts - Calls appropriate AI service (Classic AI or ML AI)
- Chosen move processed by
makeMoveLogic - UI updates
- Game state set to finished
- Local stats updated
postGameToServeraction runs- Game saved to DB
- Completion overlay shows stats
- Database: SQLite (
local.db) - ORM: Drizzle ORM
- Setup:
npm run db:local:reset
- Database: Cloudflare D1
- ORM: Drizzle ORM
- Migrations:
npm run migrate:d1
// src/lib/db/schema.ts
export const games = sqliteTable('games', {
id: text('id')
.primaryKey()
.$defaultFn(() => nanoid()),
playerId: text('playerId').notNull(),
winner: text('winner', { enum: ['player1', 'player2'] }),
completedAt: integer('completedAt', { mode: 'timestamp_ms' }),
moveCount: integer('moveCount'),
duration: integer('duration'),
history: text('history', { mode: 'json' }),
gameType: text('gameType', { enum: ['classic', 'ml', 'watch'] }),
});The game includes comprehensive statistics tracking:
Features:
- Win/Loss Tracking: Automatic recording of game outcomes
- Win Rate Calculation: Percentage of games won
- Local Storage: Statistics persist across browser sessions
- Database Integration: Games saved to database for analytics
- Real-time Updates: Statistics update immediately after game completion
Implementation:
- Statistics managed using Zustand with persistent storage
- Games automatically saved to database upon completion
- Privacy-focused: Player ID generated using
nanoid()for anonymous tracking
- Platform: Next.js on Cloudflare Pages
- Build:
npm run build:cf - Domain:
https://rgou.tre.systems
Set in public/_headers:
/wasm/*
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Status: Inactive (preserved for future use)
Available Endpoints:
POST /ai-move- Server-side AI computationGET /health- Health check endpoint
Potential Future Use Cases:
- Server-Side Validation: Validate client moves in multiplayer
- Analytics: Collect AI performance metrics
- Multiplayer Support: Centralized AI for unreliable clients
- AI Model Distribution: Dynamic AI selection based on device capabilities
Reactivation:
cd worker
wrangler deployServer-Side AI Advantages:
- Consistent performance across devices
- Reduced client load
- Centralized control
Server-Side AI Disadvantages:
- Network latency
- Infrastructure costs
- Offline limitations
- Scalability concerns
Current Decision: Client-side AI exclusively for performance, offline capability, and cost efficiency.
- Dev-only tools: AI diagnostics, AI toggle, reset/test buttons (only on localhost)
- Local database: SQLite for development
- Debug features: Enhanced logging and diagnostics
- Clean UI: No development tools
- Classic AI default: Most reliable AI opponent
- Cloudflare D1: Production database
- Optimized builds: Minified and optimized assets
- Modern, maintainable, high-performance architecture
- All AI runs locally in the browser (WASM)
- Clear separation of concerns
- Full offline and online support
- Comprehensive statistics tracking
- Privacy-focused data collection
- Preserved server infrastructure for future use cases