← Back to work
Multiplayer board gameLive beta · Payments not open

Market District

A shared game state

A live beta negotiation board game for remote game nights, with Google sign-in, Classic and Team modes, and a Premium Host membership workflow.

Role

Solo full-stack developer and game systems designer

Outcome & status

Deployed a permanent Cloudflare beta with a bilingual landing page, Google authentication, Classic/Team rooms, and manual Premium Host order and approval workflows. Automated checks cover a full six-round Worker/D1/Durable Object/WebSocket match; real payment verification and commercial release remain pending.

Overview

The problem to solve.

Market District is a live beta negotiation game with Classic 3–5 player matches and Team formats 2v2, 3v3, and 2v2v2. A bilingual public landing leads into Google-authenticated rooms, while server-authoritative trades, hidden information, and income preserve a shared match. Premium Host order and approval workflows are implemented; paid launch and legal clearance remain pending.

Problem

Physical negotiation board games are difficult to play across different homes because their hidden information, simultaneous deals, shared board state, and turn transitions do not translate cleanly to a video call.

People

Small groups of friends playing private online board-game sessions

Decisions

Key decisions.

The permanent workers.dev URL is a beta environment, separate from the legacy private deployment. Payments remain disabled until owner-verified transfer and admin setup; deployed multiplayer/hibernation playtests and legal review are still release gates. No revenue or commercial clearance is claimed.

  • Preserving hidden information while keeping every browser synchronized to one authoritative match
  • Making multi-asset trades atomic so money, lots, and shop tiles cannot partially transfer
  • Translating a dense physical board and reference tables into a readable responsive interface
  • Handling reconnects, duplicate commands, stale versions, and host controls without desynchronizing the room
Market District multiplayer trade phase with the shared district board, player states, shop reference, hand, and atomic trade desk.
Live trade phase: players negotiate money, lots, and shop tiles while the authoritative room state keeps every browser synchronized.
Implementation

What I built.

The monorepo separates React/Vite, a pure rules engine, Zod protocol, UI, and Worker. Better Auth uses Google OAuth and D1 for accounts and sessions; D1 also stores orders, subscriptions, reservations, and admin audits. SQLite-backed Durable Objects coordinate versioned WebSocket commands and private player snapshots.

  • Modeled the complete six-round game loop as a reusable TypeScript engine covering property selection, trading, placement, income, pause/resume, and final scoring.
  • Built password-protected rooms, signed player sessions, reconnectable WebSocket state, per-player hidden views, and host-only room controls on Cloudflare Workers and Durable Objects.
  • Designed the dense desktop game table, responsive player drawers, ledger, shop reference, board interactions, trade desk, and final-results experience.
  • Added an Indonesian/English landing page, Google OAuth through Better Auth and D1, account-bound room recovery, and server-enforced one-room Premium Host limits.
  • Built manual bank-transfer orders, admin approval/rejection/revocation, transaction uniqueness, atomic 30-day renewal, and customer email drafts without automatic payment or email delivery.
System architecture +

React/Vite → Worker → Better Auth/Google OAuth and D1 account/billing storage; match intents → Zod validation → SQLite Durable Object → viewer-specific WebSocket snapshots.

Results

Results, with context.

Completed a playable end-to-end match flow with original visual assets, automated engine and security tests, and browser-level coverage. A five-player UAT completed all six rounds, then retested fixes for currency input and shop-income clarity, lot and tile hover labels, thinner selection indicators, and the shop dictionary.

5

UAT players

6

Rounds completed

4

Feedback fixes retested

Lessons & next steps +
  • Multiplayer game UI must expose server state clearly without leaking private player information
  • A pure rules engine makes complex turn transitions easier to test than logic embedded in React components
  • Multiplayer playtesting exposed rule and visual-discoverability gaps that automated coverage could not reveal
  • Hosting a beta is distinct from validating real payments, demand, and commercial readiness
Technical details

Under the hood.

Technologies & features +

React / TypeScript / Vite / Cloudflare Workers / Durable Objects / Cloudflare D1 / Better Auth / Google OAuth / WebSockets / SQLite / Zod / Vitest / Playwright

  • Google-authenticated Classic and Team rooms with optional passwords
  • Bilingual public landing, account, checkout, and administrator screens
  • Manual bank-transfer Premium Host workflow; payments not yet open
  • Real-time WebSocket synchronization and reconnectable sessions
  • Server-authoritative six-round game engine
  • Hidden property and shop hands projected per player
  • Atomic money, property, and shop-tile trade offers
  • Interactive district board with shop placement and ownership states
  • Automatic shop income, ledger history, and final ranking
  • Account-bound reconnect and host-only pause, resume, and room controls

Keep exploring.