This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
Every pixel above is drawn by code. The whole world file is 551 bytes of JSON: a cherry bank, then paddies, people who wander, and a village of ten with a stone lane, shops, a shrine and a temple. A model can write a file like that from one sentence, and then it is a game you can play and download.
What I Built
What it is. A small game builder on top of a world engine. You pick a world and a kind of game (or describe a world in a sentence and let a model make it), press Play, and download the game as one HTML file that runs offline, drawn entirely in code with no image files. The demo comes with prebuilt worlds you can play in your browser right now (link under Demo).
Who it is for. People who would like a living little world or game but cannot draw or animate: small game makers, teachers, anyone making a toy for a friend. And people building with small local models, who need a model's output to become something visual that reliably works.
The side hustle: games as a service, for many people, not just me. It empowers solo game makers and enthusiasts to build simple games with open models like Gemma 4, at a quality comparable to a cloud model's. The point is that other people can make a living with it:
- a language teacher turns each week's word list into a quiz world for their students;
- a D&D game master builds their campaign's town so the table can walk it before the session;
- someone starts a small business making games for a community, a shop, a classroom or a Discord server.
The tools are free to use, and free to make and sell games with. When one game has earned US$500 in total, it owes a royalty of 5% of its revenue above that: Unreal Engine's model, at the scale of small games. So a teacher or a game master never pays anything, and the project earns only when the people building on it do.
It is three open projects, each built on the one before:
- procedural-almanac: the techniques (noise, light, dithering, water, terrain, motion, genes), each with its sources and short tests.
- OpenWorldBuilder: worlds as data, drawn by the almanac's techniques: a top-down pixel style, a 3D outdoors mode, and side and island views.
- OpenGameBuilder: a world plus a small rules file becomes a game.
Demo
Play the prebuilt worlds in your browser (no account, nothing to install; making a world from a sentence needs a model, so that part runs where you set one up).
- Pick a world, or describe one ("a foggy harbour town where crabs run the market").
- Pick a kind of game: explore and collect, endless runner, photo safari, hidden object, fishing, lane racer, quiz (from your own CSV), creature keeper, point and click, island explorer. Eight of them play on the top-down worlds.
- Turn a few knobs, press Play, then Download: one HTML file, about 330 KB, that runs offline. With the 3D mode on it is about 1 MB.
From one sentence to a game: a model made this harbour, its knowledge base and its rules, then a bot played it and won.
The same worlds can stand up in 3D: an oblique camera that shows roofs and west walls, terraces and walls from the land's own heights, buildings with real roofs, sun shadows, windows lit at night.
Code
BlaiseLabs
/
procedural-almanac
Procedural drawing and motion techniques, each with its sources and short tests
procedural-almanac
Procedural drawing and motion for the canvas: walk cycles, flocks, noise-made land, light and projection, where every technique cites where it came from.
Version 0.2 holds 72 techniques, 36 established and 36 original, citing 60 sources and held by 150 checks. The full list, with every source and every test, is the catalog.
| module | techniques |
|---|---|
numbers |
clamp, lerp, smoothstep, wrap, angleDiff |
random |
hash32, fnv1a, hashString, indexRandom, SeededRandom, latticeHash, linearCongruential |
noise |
latticeRandom, valueNoise, fractalNoise, ridgedNoise, noiseLine, noiseTile |
colour |
hexToRgb, rgbToHex, rgba, mixColour, shade, luma, rgbToHsl, hslToRgb, hueToward, gradeColour |
pixels |
packRgb, mixPacked, packedHsl, packedToHsl, hueShiftTone, bayerThreshold, ditheredBorder |
light |
dayCycle, aerialPerspective, twinkle |
water |
waterTime, waterPixel |
land |
hillLine, islandHeight, levelCut, heightWater, wanderingHeading |
scatter |
scatterAlong, windowLit, blink |
projection |
parallax, turnedProjection, turnedDepth, faceShade |
limbs, gait, genes
|
twoBoneLimb; footStep, strideRate, gaitTiming; genomeFrom, crossGenomes |
motion |
flockStep, gridWalk, pulseRise |
particles |
particleField, fall, rise, hover, wrapAround |
growth |
branchingTree, swayingChain |
drawing |
partPath, fillInArt, drawRecipe, grain, vignette, glowSprite, |
BlaiseLabs
/
OpenWorldBuilder
Living worlds drawn by code from a JSON recipe; an open model on a laptop can write one
OpenWorldBuilder
Living worlds drawn by code, where a world is only data: a person can write that data by hand, and a language model even a small open one running on a laptop, can write it from a description.
Nothing here is a picture file. The ground and its hills, water you can see into, trees and stones standing with their
shadows, animals living their own lives, people by the trail, rain and snow and fireflies, day turning to night: all of
it is drawn by code, from a seed, by one engine (engine/). A world is one JSON file (worlds/*.json).
The top view
The main view is a world seen from above, drawn as pixel art. It is the engine of 言の葉 (Kotonoha, "leaves of words"), the procedural journey that plays behind the flash cards of 綴 Tsuzuri (Tsuzuri, "writing it…
BlaiseLabs
/
OpenGameBuilder
A small playable web game from a world, an idea or your own data
OpenGameBuilder
A small playable web game from an idea, a few choices or some data. Pick a world and a genre (or describe one and let a model make it), turn a few knobs, upload a file if you have one, press Play, and download the game as one HTML file that runs anywhere, offline.
It is a thin layer on two other projects:
- procedural-almanac: the techniques (noise, light, motion, drawing), each with its sources and tests.
- OpenWorldBuilder: living worlds drawn by code from a JSON recipe; a model, even a small open one, can dream one up.
OpenGameBuilder adds what a world lacks to be a game: a player, a goal, a way to win, and a genre's rules.
Run it
npm install
npm start # builds the game script, serves the builder at http://127.0.0.1:8124/builder/
Without a model, everything except "Describe" works (and the builder can be…
The almanac is MIT. OpenWorldBuilder and OpenGameBuilder are under a small community license: free to use, change and share, free to make and sell games with, and 5% of a game's revenue above US$500.
How I Built It
I built it with AI coding agents, several at a time, each on its own part, each held to tests and to films of what it drew. I set the direction and judged every result by looking at it: the first versions were flat side-on scenes, I called them what they were, and the top-down style, the villages and the 3D came from that. The open model is what the product itself runs on: Gemma 4 12B through Ollama, on a Mac mini on my desk.
Layer 1: the almanac
Every procedural technique OpenWorldBuilder and OpenGameBuilder use lives in one library, each with its sources and a set of short tests that validate it: drawing pixels, bodies that walk, terrain and water from noise, weather, light, paths. Today it holds 162 entries, 106 references and 268 checks. Moving a technique there changes no picture: every move was proved by drawing the same worlds before and after, 0 pixels different.
Layer 2: worlds as data
A top-down world is a list of lands and a route across them. A land is generated from a rule set, not a map:
| rule | what it says | for example |
|---|---|---|
| ground | the two tones of the ground and how they are textured | snow, hatch, rows of tea |
| water | how much of the land is water, and what kind | sea, pond, river, hot spring, paddy |
| flora | which plants grow, how often, and where | maples in groves, reeds on the shore |
| fauna | which animals live there, how many, and how they live | deer that graze, gulls that flock, people who wander |
| places | the wayside things | a well, a shrine, a lighthouse |
| village | a cluster of buildings along a lane | ten houses, two shops, a temple |
| motes | what drifts in the air | snow, petals, fireflies, steam |
Code turns the rules into an ecosystem with terrain, plants, animals, and weather.
The vocabulary is small and closed: 27 built-in lands, 23 plants, 25 body plans (people among them), 26 kinds of wayside place, 9 kinds of building, 21 ways of living. A checker answers every mistake in words a model can act on, such as a fish living on dry land or a boathouse with no water. A world can also be bounded, so a game's map has an edge: the sea, mist or mountains.
Layer 3: games as rules
A game's rules are a small JSON file beside the world. They never draw anything: they name the world's own animals, places and people by id ("meet the seals of the drift-ice sea", "find the cairn"), so the checker can tell at once whether a goal exists in the world. Each genre also has a bot that plays it. The test plays every genre on every world it fits, and all 324 games are won.
An open model on a Mac
The first version asked models to write whole worlds. Gemma 4 12B, on a Mac mini through Ollama, took up to 13 minutes a game world in the initial version of the builder.
So for small models the code does most of the writing. It lays out one built-in land for each place in the world's knowledge base, the nearest fit, and the model answers one small design: each land's colours, what drifts in the air, and which word draws each thing in the knowledge base. Gemma 12B now makes a clean world in under three minutes, in two calls and about 4.3k tokens, drawing 90 to 100 percent of its knowledge base. A town with a harbour and a temple village took 3.1 to 3.4 minutes.
Watching the agents with Sentry
Sentry 26.10.0 runs self-hosted on a mini PC beside the Mac: no account, and the traces never leave my network. Each world is one trace, each stage an invoke_agent span, each model call a chat span with its tokens (and, for Gemma, Ollama's own seconds for reading against writing), each check and repair an execute_tool span.
That is a whole world from one sentence ("a lantern-lit tea village on terraced hills where foxes carry letters between the farms"), made today by Gemma 12B on the Mac: 3.15 minutes and 9 spans in all. The Lorekeeper writes the knowledge base in one call (2.28 minutes), a repair tool tidies it in a millisecond, and the World Author answers one small design in one call (51 seconds). Nothing failed, so nothing was asked twice.
It did not start this lean. Two things the traces showed me. A 27-token answer took 56 seconds because Gemma was re-reading a 6.8k-token prompt on every call; a shorter prompt cut it to 33 seconds. And whole rewrites wasted most of the work: a draft from code with changes only drew the same knowledge base in 122 seconds instead of 369. Those two findings led to the design path above.
What it is not, yet
- The bots prove every game can be won. They win in seconds, so they say nothing about whether a game is fun; no person has played them all.
- There is no sound.
- The 3D buildings are simpler than hand-drawn art, and every building faces south.
- Runner and racer play only in the side view.
- Gemma's lands start from built-in ones, so its worlds are safe rather than surprising.
- The games' own words are thin: the lines a game says are made from templates, and my first user found them flat and in places wrong (see "My First User").
Why Does Open Innovation Matter?
Open innovation makes new economies possible. A closed tool sells games to people. An open one lets people sell games to each other. With an open model on their own machine, a teacher, a game master or a small studio can make games as a service for their own customers: their students, their table, their community. Their cost for one more world is electricity, not an API bill, so even a small price leaves them a living, and the license asks for nothing until a game has really earned.
The model lives where the worlds are made. Gemma runs on a small computer on my desk: no fee per call, no rate limit, nothing leaves the machine.
I could build around the model. With open weights I could measure where it spent its time, hold every answer to a schema made from the engine's own vocabulary, and shrink its job until it fit: three minutes instead of ten.
Open all the way down. Open weights, three plain JavaScript projects, worlds and rules as JSON a person can read and edit, and an open-source Sentry on my own machine. The art is code: no image model, nothing trained on anyone's paintings.
My First User
My first user is a customer in every way but one: they have not paid, because nothing they made has earned money yet, so under the license nothing is owed. They came with a game in mind and typed it in:
a medieval sky city where Laputa meets Arlathan (island explorer, five kinds of creature to talk to, three places to find)
It came back as two playable versions: one from a cloud model in 49 seconds, and one free, from Gemma on my Mac, in 6.5 minutes. Gemma's has elven purple woods, named folk like the Cloud Monk and the Cloud Strider, and a citadel town with a temple and a bathhouse.
It is not yet the sky city they imagined: nothing reads as sky, and in Gemma's version the bot could not reach the bathhouse and the temple, so the checker's promise that every game can be won has a gap to close.
They also played two games the night before the deadline, with nothing but the builder and its guide. They picked a world, a kind of game and a few settings, played, and wrote down what bothered them. I have left the code exactly as they found it until after the deadline, so this is their report, not a list of things already fixed.
Tea Hills in 3D, hidden object, 8 clues, no time limit, seed 1.
- A wrong click names what you clicked, and the English is off: "That is the trees", "That is the tufts".
- Some things answer a click with a description (the trees) and others (the animals) say nothing at all.
Glowing Reef Drift (a side-view reef), quiz in a world, 15 right answers to win, six screens wide, no file uploaded.
- The game asked the same few questions (four, by their count) over and over to reach fifteen. The cause is plain once you look: this world has no knowledge base and they uploaded no questions, so the quiz made its questions from the world's animals and plants alone, and there were only a handful to make.
- The score at the top right ("140") does not say out of what. "140/150" would.
- The win screen is too dry: "You won. You did it." Their words: "Be happy for the player's victory, thou must."
None of this would have shown up in my tests, and that is the point of a first user. All 324 bot games are won, and a bot does not mind a repeated question, a bare number or a flat "You did it." The checker proves a game can be won; it says nothing about whether its words read as if a person wrote them. The fixes are small and clear, and they are the first things I will do after the deadline: names that read as English ("Those are the trees"), every clickable thing answering, a quiz that never asks more questions than it has (and says so, suggesting you upload your own), the score as a share of the goal, and a win screen with some joy in it.
Prize Categories
- Gemma (Google): Gemma 4 12B, run locally on a Mac mini through Ollama, makes top-down worlds and towns in under three and a half minutes each, and the framework (a draft from code, one small design, the checker) is built so a small open model can do it.
- Sentry Agent Tracing: every model run is traced in a self-hosted Sentry, and the traces led to the design path. Setup, spans and findings are in "Watching the agents with Sentry" above.













Top comments (0)