A real, buildable game engine (not a single HTML file): static, client-side, deployable to Vercel or GitHub Pages. A Super Mario Bros-style 8-episode campaign with story, power-ups, a boss and end credits — grown without ever rewriting the engine. Governed by Matrix Builder contracts and the Ruslan Magana Definitions (RMD).
IT design by Ruslan Magana Vsevolodovna · coded by GitPilot — under a Matrix Builder contract
The Realm of the Matrix runs on Contracts — but the Drift has corrupted the realms. You are the Builder, sworn to the Definitions. Restore each contract, episode by episode, run and leap and reclaim the Matrix Gate, and climb to the Architect's Sanctum to face the Rogue Architect and end the Drift.
![]() |
![]() |
| Per-episode narrative card | Episode I — parallax city, contract panels, round Contract Coins |
Controls — ←/→ or A/D move · Space/↑/W jump (variable height; double-jump when earned)
· Enter advance. On touch devices, on-screen buttons appear.
A full campaign that ramps like a classic platformer: gentle introduction → moving platforms and hazards → atmosphere and verticality → the final boss.
| # | Episode | Theme | Introduces |
|---|---|---|---|
| I | The Build Fields | Awakening | run, jump, Contract Coins, the Matrix Gate |
| II | The Dependency Cavern | Tangled paths | tighter platforming, Prompt Slimes |
| III | The Validation Gate | The verdict | the Shield power-up, tougher enemies |
| IV | The Parallax Heights | Ascend | moving platforms, the Double Jump |
| V | The Cache Marshes | Stale ground | wider gaps, mixed enemy waves |
| VI | The Pipeline Foundry | Build · Test · Deploy | long level, dense coin arcs |
| VII | The Drift Expanse | Into the Drift | the hardest platforming gauntlet |
| VIII | The Architect's Sanctum | The Rogue Architect | boss fight → Victory → Credits |
Beat the Sanctum and the game rolls scrolling end credits — Game design & direction: Ruslan Magana Vsevolodovna, GitPilot, Matrix Builder, and the RMD rules.
This is the point of the repo. Adding an episode = adding one config object. The engine never
changes. Each episode is a small, scoped, validated, additive entry — a batch in another form —
so a whole team (or a fleet of contract-bound AI agents) can add episodes, enemies and mechanics in
parallel while the engine, the standards, and the mb check gate stay fixed.
// src/levels/episodes.ts — one entry per episode; buildEpisode() reads it. No engine edits.
{
id: 4, title: "IV — The Parallax Heights", subtitle: "Ascend",
story: ["The spires of the old build pierce the dusk.", "Climb. The higher contracts await."],
width: 3000, platforms: 10, enemies: 5, slimeRatio: 0.5,
moving: true, coinArcs: 4, djump: true, accent: 0x00f0ff, seed: 44,
}A deterministic seed means each episode always generates the same hand-tunable layout. That's how this scales from a 56 KB demo to a real title the same way you'd grow a 10-million-line engine: content scales, governance holds.
npm install → 144 packages
npm run typecheck → clean (tsc --noEmit)
npm run build → dist/ produced (Phaser bundle ~343 KB gzipped)
headless browser → 8 episodes load, hero moves/jumps, round coins, ZERO runtime errors
It runs immediately with original pixel-art generated programmatically — hero sprite sheet, Bug Bot, Prompt Slime, mossy/metal tiles, round Contract Coins, RMD Star, Matrix Gate, parallax sky + two city skylines, glow, vignette, embers, HUD icons. (All original art — no copyrighted assets.)
This game is already a static Vite app: Phaser runs entirely in the browser, assets live under
public/assets/, and there is no backend or secret runtime configuration. The Vercel-ready setup is:
vercel.jsontells Vercel to install withnpm ci, runnpm run vercel-build, and publishdist/.npm run vercel-buildrunsnpm run typecheckbeforenpm run build, so a broken TypeScript build does not deploy.vite.config.tsdefaults tobase: "/", which is the correct asset base for a Vercel project domain or custom domain.- A catch-all rewrite serves
index.html, keeping the deployment safe if future scene URLs or routes are added. /assets/*receives long-lived immutable caching because filenames inpublic/assets/are versioned by repository changes.
- Push this repository to GitHub, GitLab, or Bitbucket.
- In Vercel, choose Add New → Project, import the repository, and keep the detected Vite framework preset.
- Confirm these settings, which are also encoded in
vercel.json:- Install Command:
npm ci - Build Command:
npm run vercel-build - Output Directory:
dist
- Install Command:
- Deploy. Vercel will provide a public HTTPS URL that anyone can open to play the game.
- Optional: attach a custom domain in Vercel Project Settings → Domains. No code changes are needed for root-domain hosting.
npm ci
npm run vercel-build
npm run preview -- --host 0.0.0.0Open the preview URL and verify the title screen loads, controls respond, and assets render.
GitHub Pages base: Vercel uses
/by default. GitHub Pages still needsVITE_BASE=/contract-quest/; the included GitHub Actions workflow sets that environment variable during its Pages build.
git clone https://github.com/ruslanmv/contract-quest
cd contract-quest
npm install
npm run dev # → http://localhost:5173/ (hot reload)
# or
npm run build && npm run preview
python3 scripts/gen_assets.py # regenerate the original pixel-art setDeployment base: Vercel works with the default
/base. For GitHub Pages, setVITE_BASEto/<your-repo>/so asset URLs resolve; the included Pages workflow uses/contract-quest/.
contract-quest/
├── index.html # canvas mount + footer credit
├── vite.config.ts # deployment base path (Vercel root by default)
├── vercel.json # Vercel build/output/SPA routing configuration
├── src/
│ ├── main.ts # Phaser config (pixelArt, Arcade physics, FIT scale)
│ ├── scenes/
│ │ ├── Boot/Preload # generate/load the original pixel-art set
│ │ ├── TitleScene # splash · rotating RMD tips · "design by Ruslan Magana V."
│ │ ├── StoryScene # per-episode narrative card
│ │ ├── GameScene # episode-driven world: parallax, coins, enemies, boss, gate
│ │ ├── VictoryScene # "The Matrix Gate reclaimed" + final score
│ │ └── CreditsScene # scrolling end credits
│ ├── levels/
│ │ ├── episodes.ts # ← the campaign DATA (8 episode config objects)
│ │ └── builder.ts # seeded buildEpisode(cfg) → world (engine, never per-episode)
│ ├── entities/ # Player (variable + double jump, shield), BugBot, Slime, Coin
│ ├── ui/ · utils/ # HUD, touch controls, palette/tuning, textures
├── scripts/gen_assets.py # PIL — generates all original pixel-art assets
├── docs/ARCHITECTURE.md · docs/ASSET_PROMPTS.md
├── .github/workflows/deploy.yml # CI: typecheck → build → deploy to Pages
└── MATRIX_*.{yaml,lock,md} # the contract identity + RMD governance + batch plan
To reach an exact concept-art look, replace the PNGs in public/assets/ with an image model — same
names/sizes → zero code changes. See docs/ASSET_PROMPTS.md.
The engineering was written by GitPilot (Claude or watsonx —
your choice) one governed batch at a time: mb next → mb prompt --coder gitpilot → gitpilot generate → mb check. Each batch is scoped to an allow-list of files and fail-closed —
if the model writes outside scope or misses an acceptance criterion, mb check returns
needs-repair and nothing ships. The campaign then grew the same way: each episode is just another
additive, validated batch.
- RMD-101 — AI coders are workers, not architects.
- RMD-103 — Control files are protected.
- RMD-111 — Acceptance criteria are law.
Full design (data models, asset pipeline, batch plan) is in
docs/ARCHITECTURE.md and the MATRIX_* files.
TypeScript · Vite 5 · Phaser 3 · Arcade physics · ESLint/Prettier · Vercel · GitHub Actions → Pages. No backend, no runtime AI calls. AI is used only to assist writing code. No API keys are committed.

