P-08 · BUILD / PROJECT · 2026 ACTIVE

麻將 Pro

Singapore mahjong in the browser: four AI difficulty tiers, online rooms, four rulesets.

STACK: JavaScriptSupabase RealtimeEdge FunctionsThree.js

What it is

A full Singapore-mahjong game that runs in a browser. Single player against AI, or online rooms against people. No download, no forced sign-up. You can open it and play as a guest, and it works offline.

I built it because the mahjong apps I could find either implemented a different regional ruleset or implemented Singapore rules badly, and mahjong is a game where “close enough” scoring is not a rounding error. It’s an argument.

The rules engine

The engine is plain JavaScript, ported exactly from an earlier single-file version I wrote. That original file still sits at the repository root as the reference implementation. When the ported engine and the reference disagree, the reference wins. It’s an unglamorous arrangement that has caught more scoring bugs than any test I wrote deliberately.

Keeping the engine framework-free is what makes the multiplayer work: the same rules code runs in the browser and inside Supabase Edge Functions. Clients get instant local feedback, the server holds authority, and there is exactly one implementation of the rules for both to agree on.

Four rulesets ship, including Simple Old School with the full 144-tile set, and Experimental Chaos with twelve jokers, which is either an abomination or the best variant depending on who you ask.

A hand in progress against the AI opponents

The AI

Four difficulty tiers, and they differ in kind rather than in handicap. The lowest tier plays its own hand and little else. It chases a win and ignores you. The highest counts waits, reads the discard pile for what opponents are collecting, and defends ruthlessly, folding a live hand rather than feeding a dangerous tile. Building the top tier taught me more about my own play than several years at the table did.

Four AI difficulty tiers, from chasing wins to reading discards

Around the game

Online rooms run on Supabase Realtime. There’s a coins economy and a cosmetic shop: table themes, tile backs, and procedurally generated Three.js characters, so the cosmetics are code rather than an art budget I don’t have. Guest play needs no account; cloud sync is available if you want it, and optional if you don’t.

Where it stands

About 176 files, five months in and still active. The rules engine is finished. The AI’s defensive play is not, and probably never will be.