Architecture

System Overview

Dracor is composed of four independent services that communicate through well-defined boundaries. Each service owns its domain and can be developed, deployed, and scaled independently.

Web App (Next.js)

The marketing site, account management, character creation, and play launcher. Server-rendered where possible, client-interactive where needed. Handles authentication flows via Supabase Auth and serves as the entry point for all player-facing content.

Game Client (Babylon.js + Vite)

A standalone single-page application built with Babylon.js 7 and bundled via Vite. Renders the 3D game world, handles player input, and communicates with the game server over WebSocket. Hosted separately at game.thedracor.com.

Game Server (Colyseus)

The authoritative multiplayer server. Runs game simulation at a fixed 20Hz tick rate, validates all player actions, manages room state, and broadcasts delta updates to connected clients. No game logic runs on the client.

Database (Supabase / Postgres)

PostgreSQL with Row Level Security for persistent data: characters, inventory, contracts, deeds, and reputation. Supabase provides authentication, real-time subscriptions, and storage. The game server writes state snapshots every 30 seconds.

Service Communication

The web app communicates with Supabase directly via the client SDK for auth and data queries. The game client connects to the Colyseus server over WebSocket for real-time gameplay. The game server reads and writes to Supabase via the service role key for persistence operations. No direct communication exists between the web app and the game server — the game client is the bridge.

  • Web App → Supabase: REST + Realtime (auth, characters, profiles)
  • Game Client → Game Server: WebSocket (inputs, state sync)
  • Game Server → Supabase: Service-role REST (persistence snapshots)
  • Web App → Game Client: URL redirect with character param

Domain Architecture

In production, services are exposed through subdomains of thedracor.com. The Next.js middleware handles host-based routing, rewriting subdomain requests to the appropriate path prefix. In local development, everything runs at localhost:3000 under normal path routing.

DomainService
thedracor.comLanding page and marketing content
play.thedracor.comGame launcher and play hub
account.thedracor.comAccount dashboard, login, and character management
dev.thedracor.comDeveloper portal and technical documentation
game.thedracor.comBabylon.js game client (separate Vite app)
server.thedracor.comColyseus game server (WebSocket)

Monorepo Structure

The project uses a Turborepo monorepo with pnpm workspaces. Shared packages (UI components, database types, shared utilities) are consumed by all apps. Each app has its own build pipeline and can be deployed independently.

apps/
  web/         # Next.js (thedracor.com + subdomains)
  game/        # Babylon.js + Vite (game.thedracor.com)
  server/      # Colyseus (server.thedracor.com)
packages/
  ui/          # Shared React components
  shared/      # Types, constants, utilities
  database/    # Supabase client, migrations, types