Every game we deliver is one file. Not a folder, not an installer, not a link to a service. One HTML document containing the code, every image, and every sound, which you can email to somebody.
That is an unusual choice and it has real costs. Here is how it is done and why we think the trade is right for work that is meant to be kept.
Why bother
Consider what a normal web game is. An HTML file, a folder of scripts, a folder of images, a folder of audio, served by a host, at an address.
Every one of those is a thing that can go wrong later. The host lapses. The address changes. Somebody copies the HTML file to a memory stick and leaves the folders behind, so it opens to a page of broken images. A path that worked on one machine breaks on another because of a capital letter.
None of that matters for a game somebody plays this week. It matters enormously for a game somebody was given for their sixtieth birthday and wants to show a grandchild in 2034.
A single file has no dependencies to lose. It opens from a downloads folder with no internet connection at all. The failure modes are down to one: losing the file, which is the same failure mode as losing a photograph and one people already understand.
How assets get inside
The mechanism is a data URI: a way of writing a file's contents into a document as text.
An image is normally referenced by a path. Instead, the entire image is encoded into a long string of characters and written where the path would go. The browser decodes it back into an image. As far as everything downstream is concerned it is an ordinary image, because it is one.
The same applies to audio, fonts and anything else. In our builds, assets sit in a single object keyed by name, and each becomes an ordinary image object as the file opens. Drawing code asks for an asset by name and never knows the difference.
The cost is size. The encoding carries three bytes of original data in four characters, so everything is about a third larger than it would be as a separate file. Compression during transfer recovers most of that, because the encoded text compresses well, but the file on disk is genuinely bigger.

Assembling it
Doing this by hand would be miserable, so it is a build step.
Ours reads a configuration file describing the game and a folder of artwork, encodes every asset, substitutes them and the game's text into a template, and writes out the finished document. It uses only what comes with Node, so it runs anywhere without installing anything, which is the same durability argument applied one level up.
The template is a complete, working game with placeholders where the specific content goes: the title, the character's name, the artwork, the level layout, the strings shown at the start and the end. Building a commission is filling those in.
That is the honest structure of the work, and it is worth being plain about. A genuinely novel game per customer cannot be produced reliably at a sensible price. A strong shared engine with bespoke art, levels, names and jokes can, and that is what the tiers describe.
The loading problem
There is one real drawback and it needs handling rather than denying.
A twenty megabyte file is twenty megabytes before anything appears. With separate assets a game can show its first screen and load the rest in the background; with one file, nothing happens until enough of the document has arrived.
For a game opened from a link that has already been downloaded, this is a non-issue. For a game embedded in a web page, it very much is one, which is why the play pages on this site show a still image first and only fetch the game when somebody presses play. Nobody who is reading an article pays for a game they did not ask to play.
It is also why file size is a design constraint rather than an afterthought, and why one of our builds is 104KB and another is twenty megabytes. The arithmetic behind that gap is in why one game is 104KB and another is 20MB.
What it makes easy
Two things fall out of this that were not the goal and turn out to matter.
It works offline, completely. Not through a service worker or a caching strategy, but because there is nothing to fetch. A game on a phone in a car with no signal is the same game.
It is testable as a unit. The whole game is one artefact. A test opens the file, drives it and asserts it can be finished, with no server to start and no fixtures to arrange. That is what makes the acceptance testing in proving a game is actually finished practical rather than aspirational.
What it makes hard
Being fair about the other side.
Updating means resending. There is no patching. A fix is a new file, and anybody holding the old one keeps holding it. For a keepsake that is fine; for anything with ongoing content it would not be.
Nothing is shared between games. Two commissions with the same engine each carry their own copy of it. That is wasteful in the abstract and irrelevant in practice, because the engine is small and the artwork is not.
Large files are awkward to email. Twenty megabytes exceeds some mail limits, so delivery becomes a link to a download rather than an attachment. The file is still a file; only the handover changes.
What this means for a commission
You receive a thing, not access to a thing. The build is yours, it works without us, and it will keep working.
It is the reason file size is discussed at the brief stage. Style, number of scenes and whether music is recorded all land in the same number, and that number decides how the game is delivered.
And it is why the artwork is the budget. The engine is a rounding error. The paintings are the game, which is the trade explored in pixel art or painted.



