A multiplayer Tamil Scrabble game built with React and WebSockets.
- Real-time two-player multiplayer via WebSocket rooms
- Private game rooms (create + invite by link/code)
- Random opponent matchmaking queue
- Single-player mode with AI opponent
- Persistent usernames
- Persistent leaderboard/rating system (SQLite-backed; shown when data exists)
- Password-protected admin analytics inspector (
?analytics=1) - Tamil/English bilingual UI
- Large Tamil dictionary (
public/tamil_dictionary.txt) with server-side FST validation fallback - Dictionary preloaded at app startup; Play button stays disabled until dictionary is ready
- HTTP fallback FST validation for single-player (
POST /api/validate-words) - Drag-and-drop tile placement
- In-game chat
- Invite friends with a shareable link
- Node.js 18+
foma+flookupwhen rebuilding FST models or dictionary artifacts. Install withbrew install fomaon macOS orsudo apt-get install foma-binon Ubuntu/Debian. Compiled.fstfiles still require the externalflookupexecutable for runtime morphology validation.
Start the WebSocket server:
npm install
npm run fst:build # verifies the checksum-pinned 12-model morphology release
cd server && npm install && npm startStart the React app (in a separate terminal):
npm install
npm startOpen http://localhost:3000.
- Canonical FST architecture doc:
Docs/FST_ARCHITECTURE.md - FST patch/build/test workflow:
fst/README.md - One-command refresh (patched FSTs + dictionary + checks):
npm run dict:build - Full docs index:
Docs/README.md
Landing page modes:
New Game With Invited Opponent(creates a private room and auto-opens invite modal)Play Random Opponent(queue-based matchmaking)Play vs ComputerJoin Private Game(accepts either game code or full invite link)
Invite modal supports sharing:
- game code
- full invite link
- native Web Share API (when available)
The server exposes:
GET /health→ returns200JSON ({ ok: true, service, timestamp })
For Railway deployments, set the service Healthcheck Path to /health to reduce deploy-time 500s during rollouts.
- Set
ANALYTICS_ADMIN_PASSWORDin server environment variables. - Open the app with
?analytics=1(example:http://localhost:3000/?analytics=1). - Enter the admin password in the inspector UI.
Protected endpoints are served under /api/admin/* and require X-Admin-Password.
- Frontend: React, Redux Toolkit
- Backend: Node.js WebSocket server
- Validation: Two-tier system — client-side binary search + server-side FST fallback
- Validation transport: WebSocket in multiplayer + HTTP fallback in single-player
- Analytics: SQLite via better-sqlite3