Skip to content
QC Failed
GitHub ↗

Featured workCase file

Game / full-stack product

RuneSpace

active

A playful “RuneScape in space” idea, built into a real browser game one approved slice at a time — with a server that owns every outcome and a habit of reviewing the interface before calling it finished.

RuneSpace started as a joke with legs: what if the old-school MMO grind — mining, equipment, daily claims, long-term progression — happened in a blue-collar science-fiction world? It is a browser-first, mobile-friendly, low-fi RPG with an old-school progression influence, and it is deliberately not a RuneScape clone. The honest label is “active foundation”: authentication, character ownership, and a playable server-authoritative Crash Site Mining slice exist today, with more systems scoped into approved issues.

The interesting work was never the joke, though. It is turning that idea into a real product without letting the implementation become a disposable toy: deliberate scope, server authority, real persistence, preview review, and layered tests, delivered one trustworthy slice at a time.

  • Server-authoritative progression
  • Real PostgreSQL transaction coverage
  • Mobile-first browser journeys
  • Preview-reviewed interface revisions

Fig. 1Mobile capture

Checking the equipment loadout at the crash site

More shots

  • A failed mining attempt at the crash site

At a glance

Category
Game / full-stack product
Status
active
Source
public
Live
runespace.qcfailed.com
Stack
Next.js, TypeScript, PostgreSQL, Drizzle, Better Auth, Playwright
Proof points
  • Next.js and TypeScript product work
  • responsive game UI
  • server-backed progression
  • Playwright flows
  • Docker/Coolify deployment

01 / Story

Why it exists

I wanted to build something I would keep coming back to: a slow-burn browser RPG where progress is earned over weeks, not minutes. The old-school MMO loop — mine, claim, equip, travel, grind — is a proven shape for that, and putting it in a low-fi science-fiction setting gives it a personality instead of a theme-park fantasy.

The practical goal was durability. A playful idea only stays alive if the codebase stays pleasant to extend months later, so the funny idea gets the same engineering care as a serious product: a real database, real tests, and a real deployment pipeline.

02 / Story

The product and engineering problem

Persistent progression cannot be client-owned. If the browser decides what a mining run yielded, a refresh, a duplicate tap, or a modified request can rewrite the player's state. Mining outcomes, action timing, inventory changes, equipment state, travel, rewards, and retries all need to stay authoritative and consistent even when commands race, the page reloads mid-action, or work becomes due while another command is being submitted.

RuneSpace treats the browser as a view with controls, never as the source of truth. Gameplay outcomes are resolved by server-side domain logic and persisted in PostgreSQL before the interface is allowed to show them.

03 / Constraints

Constraints

The rules the build has to respect, issue after issue:

  • Mobile-first interaction — the game is played from a phone-sized screen before it is shown on a desktop
  • Server-authoritative progression — the browser is never trusted as the source of truth
  • Real PostgreSQL persistence — no localStorage stand-ins or in-memory worlds
  • One focused issue and draft PR at a time — gameplay and persistence changes ship as reviewable slices
  • No speculative generic game framework — infrastructure is added when a concrete feature needs it
  • Current-build features must fail safely and stay explainable — refusals say why, state never silently corrupts
  • Visual review happens against a real preview, not only against tests

04 / Decisions

Selected decisions

The architectural choices that make the authority boundary hold:

  1. Modular monolith with explicit boundaries

    Domain logic, server actions, and persistence live in separate layers with clear dependency direction, so a gameplay rule cannot leak into a component and a query cannot bypass the domain.

  2. Server actions accept narrow identifiers

    A command names what it wants — a character, a stack, an operation — while item facts, balance, ownership, and outcomes are resolved server-side. There is nothing for a hostile client to forge.

  3. Locking, optimistic validation, due-work reconciliation, atomic rollback

    Inventory and progression commands lock rows, re-check expected state after due work is resolved, and commit or roll back as one transaction.

  4. The UI renders server-confirmed projections

    Components display the state the server returned; they never calculate progression locally or assume an outcome.

  5. Risk-based testing

    Pure rules get fast unit tests, transaction behavior gets PostgreSQL integration tests, and the critical mobile journeys get Playwright. The canonical E2E runner builds and starts the production app once, then reuses it across journeys.

05 / Flow

Where authority lives

  1. STEP 01

    Browser/UI command

    Start mining, load a cell, drop a stack — narrow identifiers only, no client-trusted facts.

  2. STEP 02

    Server action / domain rules

    Authentication, character ownership, and gameplay rules are checked server-side.

  3. STEP 03

    Locked PostgreSQL transaction

    Rows are locked, due work is reconciled, and the change commits atomically or rolls back.

  4. STEP 04

    Authoritative state projection

    The interface re-renders from the confirmed server state — never from local calculation.

Every gameplay command flows through the same authority boundary; the browser only ever displays what the server confirmed.

06 / Story

A revision story: inventory item details

The Inventory item-details work (issue #58, merged via PR #60) is the clearest example of the review loop. The first completed implementation was functionally strong: selection, Power Cell loading, and stack dropping all worked, and the server command was authoritative from the start.

But the presentation had not passed inspection. The selected-item area was too tall, visually inconsistent with the inventory grid, and easy to miss after picking an item near the top of the drawer. Tests were green; the design was not — exactly the gap between “working” and “finished enough to ship”.

A human preview review led to concrete corrections: a compact fixed-height selected-item visual, a shared InventoryStackVisual used by both the grid and the details, an item-dossier information layout, automatic scroll and focus to the Item details heading after selection, and deliberate dismissal paths — toggle, empty slot, blank space, and an explicit Close details control. The authoritative loading and drop behavior underneath stayed untouched.

The lesson I keep applying: “working” and “finished enough to ship” are different standards, and a real preview is what makes the difference visible.

07 / Evidence

Evidence

The proof behind this case file:

08 / Story

How quality is proven

RuneSpace uses risk-based testing: pure rules live in unit tests, transaction behavior lives in PostgreSQL integration tests, and a small set of critical mobile journeys runs in Playwright. Each layer covers the failure class it is best at catching — the suite grows where the risk actually is, not evenly.

The CI policy separates fast draft feedback from the full merge gate. Draft previews get the quick checks; merge-relevant boundaries run the full PostgreSQL and canonical E2E validation. The canonical runner builds and starts the production app once and reuses it across journeys.

Every gameplay or persistence change ships as one approved issue and draft PR, with live Coolify previews for human review. Model-assisted planning and review passes inform the work, but the issue-first workflow keeps every decision reviewable and every merge a deliberate human act.

09 / Status

Current status and next direction

RuneSpace is an active foundation, not a finished MMO. The playable slice is real — Mining, persistent locations and timed Travel, the DeWhat? Emergency Power Annex with daily per-character Power Cell claims, equipment, carried inventory, Power Cell loading and boosting, item details, and stack dropping — and the boundaries around it are designed to hold as the world grows.

Next direction

  • Expand locations, progression, and inventory/equipment depth; add world systems on top of the same server-authoritative foundation; keep the authority boundaries and risk-based test layers intact.