The short version
The game began in a private chat in Station, then moved into a hands-on build session with an AI coding agent. It was not made by asking an image model to produce a finished game in one shot.
Station already held useful knowledge about Loryan, his projects, homelab, interests, and earlier conversations. Rufus could search that knowledge while building, so the game started with relevant context instead of requiring a long briefing or rediscovering every detail from scratch. That made the first playable version substantially faster to produce.
Loryan supplied the premise, personal context, references, corrections, and taste. Claude Opus 5, running inside the Rufus coding environment, turned that direction into a specification, source code, art tools, generated and digitised assets, tests, browser QA, Git commits, and deployment. Azure Foundry gpt-image-2 painted the source artwork; ordinary Python image processing then made it look like a 1993 VGA game.
The initial playable game took about 1 hour 46 minutes. The complete version spanned 33 hours 59 minutes, mostly overnight or waiting for feedback. Session telemetry identifies about 6 hours 55 minutes of active work, or approximately 7–9 active agent-hours depending on how idle gaps are counted.
The session ledger assigned US$270.03 of metered language-model usage to the build. That is not the amount Loryan personally paid. The work used a combination of self-hosted resources, Azure subscriptions funded with credits available through the Microsoft MVP program, and Loryan’s existing Claude Max 20× subscription. Image generation and hosting were outside the Rufus model ledger, so the report does not claim an exact out-of-pocket total.
Measured project facts
| Measure | Result | How it was measured |
|---|---|---|
| First prompt | 28 Aug 2026, 00:03 AEST | Rufus event log |
| First playable result | 28 Aug 2026, 01:49 AEST | First completed agent turn |
| Final round completed | 29 Aug 2026, 10:02 AEST | Last completed build turn |
| Full elapsed span | 33h 59m | First prompt to final build result |
| Active work | 6h 55m measured; roughly 7–9h | Ten activity clusters, split after 15 minutes idle; 10-minute and 15-minute gap caps give 8h 19m and 9h 10m |
| User messages | 18 | Rufus event log, through the final build result |
| Agent turns | 11 top-level turns, 938 model iterations | Rufus and provider transcripts |
| Tool calls | 900 | Rufus event log, through the final build result |
| Commits | 29 | Git history at the end of round five |
| Tracked files | 90 | Git index |
| Source | About 7,095 lines | JavaScript, Python, shell, CSS, and HTML |
| Repository size | About 1.1 MB | Tracked files only; raw art is deliberately excluded |
| Metered language-model usage | US$270.03 | Rufus cumulative metering; usage value, not cash paid |
“Active work” is necessarily a definition rather than a stopwatch reading. The 6h 55m figure groups events into work sessions and treats any gap longer than 15 minutes as inactive. A more generous method that caps every gap at 10–15 minutes produces 8h 19m–9h 10m. It includes planning, art generation, testing, debugging, deployment, and documentation—not just typing JavaScript.
Models and token usage
Coding, writing, debugging, and orchestration
Every completed build turn used Claude Opus 5. It did the planning, code generation, comedy writing, image-pipeline code, browser-driven verification, debugging, Git work, and deployment orchestration.
The provider transcript records:
| Token category | Tokens |
|---|---|
| Uncached input | 1,782 |
| Cache creation input | 6,989,388 |
| Cache-read input | 361,705,884 |
| Output | 738,331 |
| Total processed, including cache reads | 369,435,385 |
The very large total needs context. This was one long, tool-heavy session whose project history and tool results were repeatedly supplied through prompt caching. 361.7 million tokens—98% of the recorded total—were discounted cache reads, not 361.7 million freshly generated or fully priced input tokens. The provider-metered US$270.03 is useful for comparing usage, but it is not an invoice or the project’s cash cost: Claude access came through an existing Claude Max 20× subscription.
The peak live context reached about 998,000 tokens before compaction. Keeping one continuous session made decisions and prior feedback available, but it also increased context and cache traffic. A cost-optimised recreation should use shorter, well-scoped sessions and durable specs.
Artwork
Azure Foundry gpt-image-2 generated the large source paintings and character sheets. It was used through both generation and edit endpoints; the edit path accepted a reference photograph where likeness mattered.
It did not create the final pixels unaided. Python and Pillow then:
- cropped each painting to 8:5;
- reduced it to 320×200;
- colour-graded it toward the Space Quest V palette;
- quantised it to 256 colours; and
- applied Floyd–Steinberg dithering.
Later portraits and logos were not generated at all: they were digitised from supplied reference material and passed through the same VGA pipeline. This change followed a failed review in which generated portraits did not resemble their intended characters.
The exact image-model usage is not available in the Rufus ledger, so it is excluded from the US$270.03 figure rather than estimated. Image generation and Azure Static Web Apps hosting used Azure subscriptions with credits available to Loryan through the Microsoft MVP program. Self-hosted Rufus, Station, Gitea, Playwright, Vaultwarden, and supporting services ran on Loryan’s own homelab. Those resources have real subscription, hardware, electricity, and opportunity costs, but this report does not pretend they were per-project cash charges.
Tools and technologies
Product code
- Vanilla JavaScript and ES modules—no framework and no bundler.
- HTML Canvas for the 320×200 game screen, sprites, bitmap text, UI, and scene composition.
- Web Audio API for a hand-authored two-operator FM synthesiser, sequencer, music, and sound effects. No audio-generation model was used.
- CSS for the responsive page shell and integer-scaled canvas presentation.
- Python + Pillow for generation scripts, resizing, palette conversion, dithering, sprite slicing, chroma keying, and reference-image digitisation.
- Azure Static Web Apps and a custom domain for the public deployment.
- A small nginx/Docker/Dockhand deployment was also created during development.
Development and QA
- Rufus provided the isolated worktree, tool permissions, model session, telemetry, and access to services.
- Git + Gitea provided version control and the canonical repository.
- Playwright drove the real browser for desktop and approximately 380px-wide verification, full playthroughs, screenshots, hotspot checks, and regression testing.
- Station supplied the private original design conversation and a searchable knowledge base of relevant personal, project, and homelab context. That reduced both the initial briefing and repeated research.
- Vaultwarden supplied credentials to scripts at runtime without putting secrets in prompts or commits.
- Shell tools and small purpose-built debug hooks (
?scene=,?debug=hotspots, and?debug=1) made scenes directly testable.
OpenDesign was investigated because earlier attempts had failed there. It was not the successful art path: its image-provider chain lacked usable credentials. The working build called the configured Azure image model directly through a small, version-controlled pipeline.
What the workflow actually looked like
This was iterative product development rather than a single prompt:
- Start with the conversation and recover the context. The project began in a private Station chat. The agent turned that conversation into a concrete game specification and acceptance criteria, then searched Station’s existing knowledge for relevant people, projects, infrastructure, and personal references. This avoided a long context-setting interview and made the first build much faster.
- Choose a deliberately small architecture. A static site, a tiny scene engine, data-driven hotspots, and no build step kept the game inspectable and easy to deploy.
- Build one playable path. Engine, four rooms, jokes, puzzles, inventory, deaths, and the ending were implemented together so the concept could be tested early.
- Create an art pipeline, not isolated images. Prompts were committed as text files; raw paintings remained private and reproducible; deterministic post-processing created the final style.
- Test in a real browser. The agent played the game, checked every hotspot/verb combination, and captured desktop and mobile-width screenshots.
- Use feedback as new rounds. Feedback added music, a more authentic title sequence, hints, public hosting, optional rooms, a side quest, portraits, a Claude logo, and copy corrections.
- Record failures. The specs document bad scaling, unreachable hotspots, incorrect portraits, an invented beard, layout overflow, a stale preview server, and other defects—not just the final solution.
- Deploy only the public artefact. The deployment script explicitly stages the game, this build report, and their browser assets; raw source paintings, personal photographs, prompts, and credentials do not go to the public site.
The decisions that mattered most
“Generate, then crush” made the visual style work
A high-resolution AI image still looks like a modern AI painting. Hand-drawing a few pixel shapes in Canvas looks procedural. Generating a painted source and then putting it through constraints similar to a 1993 asset pipeline produced the convincing result.
The browser also displays the 320×200 canvas only at whole-number scale factors. Fractional CSS scaling made one-pixel stems vary in width and immediately spoiled the period look.
The game content is data-driven
Each room defines its background, walkable band, hotspots, and one response per verb. Most writing changes therefore do not require engine changes. Responses can be strings, escalating arrays, or functions for the few interactions that alter state.
Debuggability was designed in
Direct scene jumps, hotspot overlays, and a scripted debug API allowed targeted testing. Those hooks exposed real defects, including dead clicks, door-state errors, inventory overflow, and a debug-only boot deadlock.
Human review remained essential
The largest quality failures were not syntax errors. They were taste and identity errors: art that did not resemble its subject, a face with a beard the real person did not have, captions that described visible pixels instead of introducing characters, and a title screen that did not evoke the intended reference. Automated checks could not make those calls. Direct review and specific corrections did.
What it cost in effort—not just dollars
The first version was fast, but the last 20% contained much of the quality:
- period-correct title and hero screens;
- hints for a puzzle that was technically solvable but practically opaque;
- responsive and mobile-width QA;
- music and sound design;
- public deployment and leakage checks;
- optional rooms and personal references;
- replacement of plausible-but-wrong generated portraits;
- fixes found only during full completionist playthroughs.
That is the main lesson for estimating similar work: a prototype can appear in under two hours, while a polished, personal, shareable version may take four or five times the active effort.
How to build something similar
- Start with a one-page contract. Define play time, room count, interaction vocabulary, ending, visual references, and explicit non-goals.
- Keep the first game tiny. Four rooms and one repeated puzzle mechanic are enough to prove an adventure-game loop.
- Pick a model that can use tools. It needs filesystem, shell, Git, and browser access—not just chat output. A capable coding model matters more than asking for a complete game in one prompt.
- Put the agent in a real repository. Require small commits, version-controlled prompts, specs, and reproducible scripts.
- Separate generated source from shipped assets. Keep raw generations and personal references private; deploy only processed game assets.
- Automate style constraints. Resolution, palette, dithering, crop, and scaling should be code, not prose in every image prompt.
- Give every interaction a response. In a point-and-click game, a funny wrong answer is content; a dead click feels broken.
- Add test hooks early. Scene jumps and hotspot overlays are cheap and save repeated manual navigation.
- Require visual QA at two widths. The model must actually open and inspect the running game. A successful build command is not visual verification.
- Review identity-sensitive assets beside references. Generate contact sheets that put source and result together. Do not approve from memory.
- Use fresh sessions for major rounds. Carry decisions in specs and issue descriptions instead of keeping nearly a million tokens live. This should materially reduce cache traffic and cost.
- Budget for iteration. The first playable result is the beginning of review, not the end of development.
Scope and caveats
- The report covers the successful Rufus build session from 28–29 August 2026 and the repository state at commit
a787988. - It excludes earlier Station/OpenDesign attempts except where they informed the successful design.
- “Coding time” is reconstructed from event activity, not a human time sheet.
- US$270.03 is the recorded Claude language-model charge. It excludes image generation, cloud hosting, existing homelab infrastructure, and the value of human review time.
- Token totals come from provider usage records deduplicated by message ID. They include prompt-cache reads and therefore should not be compared directly with an uncached chat transcript.