← Back to projects
In development

VOIDRIFT

Browser-based 2D space MMO with server-authoritative movement over WebSocket and Protobuf — Go backend, PixiJS client, in active development.

VOIDRIFT

VOIDRIFT is a browser-based 2D space MMO with server-authoritative movement and combat: a Go backend, a PixiJS client, PostgreSQL for storage, and a binary WebSocket protocol over Protobuf. The most technically demanding project in this portfolio — and explicitly an ongoing effort, not a finished product.

Gallery

Case Study

Situation

VOIDRIFT is an attempt to build a space MMO with real, server-authoritative rules in the browser — on a shared dev server with a documented history of memory issues, which made resource budget a design factor from the start rather than an afterthought.

Challenge

The client sends only movement intents, never a position — actual position, velocity, and rotation are computed server-side on every tick. An early version of client-side interpolation buffered the same object state multiple times, which made movement visibly snap to the tick rate instead of looking smooth. Hit detection on projectiles needed a segment-versus-circle test between the previous and current tick rather than a plain point-distance check, so small, fast targets couldn’t slip through between two ticks. Load testing also showed that the number of mutually visible connections — not the raw object count — is the limiting factor: the tipping point sat at around 60–80 mutually visible connections, well below an originally assumed figure that turned out to be a test artifact.

Approach

Go backend, split into a pure simulation layer free of networking and database access (unit-tested), a sector layer with a tick loop and interest grid, a gateway layer for WebSocket and Protobuf termination, and an auth layer with Argon2id. Data access via sqlc-generated code instead of an ORM, PostgreSQL 17 in Docker with migrations via goose. The PixiJS client, written in strict TypeScript, handles rendering, prediction for the player’s own ship, and interpolation for every other object. A hot-reload dev environment automatically rebuilds Go, watches for Protobuf changes, and starts the Vite client in parallel.

Decisions

Server-authoritative, without exception

The client sends only movement intents, never a position; every shot is revalidated against cooldown, range, and energy on every tick.

Protobuf instead of JSON

proto3 field presence distinguishes “not set” from “0,” which carries the delta encoding between ticks without needing a second, hand-maintained diff format.

A uniform grid instead of a quadtree for interest management

At the current scale, a full grid rebuild per tick is cheaper than an incrementally maintained tree.

Definitions in Git, ownership in the database

Balancing values live versioned in text files; anything two players could reasonably disagree about — inventory, for instance — lives in Postgres.

Redis deliberately deferred

No current feature needs cross-sector communication; an extra container on a host with a past history of memory issues wasn’t justified.

goose instead of golang-migrate

Single-file migrations and a pure Go library that pairs more closely with sqlc — a preference, not a correctness decision.

My contribution

Full design and implementation of the backend simulation, network protocol, authentication, database schema, PixiJS client, admin tooling, load-testing tool, and the complete deploy and operations infrastructure for the dev instance.

Results

Measured capacity limit
around 22 mutually visible connections stay under 10 ms p99 tick duration
Commits
352, since August 2026
Status
active development — explicitly a dev instance, not production

Search & navigation

Navigate Open Esc Close