Three of the things we build games with, ported to JavaScript and put on the page
where you can drive them. No download, no plugin, no engine runtime. Change a number
and watch what it does.
A studio site can describe its level generator or it can hand you one. These are the
second thing. The solvers are the same algorithms that run in our Unity projects,
rewritten in plain JavaScript rather than filmed, and all three together come to
36 KB over the wire.
That size is the point as much as the content is. The whole site is hand written flat
files with no build step and no dependencies, and a playable page had to arrive without
breaking that promise. Everything here loads with the page and works on a phone.
Procedural generation
Wave function collapse
Every cell starts able to be any tile. Collapse the most constrained one, propagate
what that rules out, repeat. When propagation empties a cell the solver has painted
itself into a corner, and it walks the decision back rather than starting over.
This is an interactive wave function collapse solver. It needs JavaScript, which is
currently blocked or still loading.
The rules are data
A tile declares four edge sockets and a weight. Two tiles may sit next to each
other when the sockets they present to each other match, and that is the entire
constraint system. Switch the tileset and the same solver produces circuitry or
dungeons, because neither is written into it.
Backtracking, visibly
Most demonstrations restart on a contradiction and hope. This one snapshots the
wave before each decision, and on failure restores it and forbids the tile that led
nowhere, so the search takes a genuinely different branch. Turn backtracking off in
the panel and watch how quickly a tight grid becomes unsolvable.
Seeds mean something
The generator draws from a seeded pseudorandom stream, not from
Math.random. The same seed and the same settings give the same board
every time, on any machine. That is what makes a generated level something you can
file a bug against.
Progression
Lock and key worlds
A metroidvania is a promise that everything you can see, you can eventually reach.
The generator below builds a world that keeps that promise by construction, and then
a separate validator that knows nothing about how it was built tries to break it.
This is an interactive world generator and progression validator. It needs
JavaScript, which is currently blocked or still loading.
Two halves that do not trust each other
The generator orders rooms by distance from the spawn, cuts that order into
regions, and locks the way into each region behind the ability sitting in the one
before it. Solvability follows by induction.
The validator ignores all of that. It starts at the spawn holding nothing, walks
only the doors it can actually open, picks up whatever it finds, and goes again
until it stops making progress. Then it reports what it reached and in what order.
A generator that grades its own homework always passes. Separating the two is what
turns "should be reachable" into "was reached, in this order, from a cold start".
What the colours mean
Rooms are tinted by region. Coloured bars across a doorway are ability gates, and
they clear as the validator picks the ability up. The circle is where an ability
lives, the triangle is the boss, and S is the spawn.
Anything the validator could not reach gets outlined in red. On a world built the
way this one is, that outline should never appear, which is exactly why it is worth
drawing. Our own 404 page makes a joke about this. The generator really does refuse
to build a room the player cannot reach.
Playable
Ember Run
A small platformer whose level is carved out of a collapsed wave. It is not a
screenshot of the solver above, it is running the solver above. Change the seed and
you are somewhere else.
This is a playable platformer. It needs JavaScript, which is currently blocked or
still loading.
Controls
Click the game to give it focus, then arrows or WASD to move,
Z to jump, X to attack and Shift
to dash. A gamepad works too. Nothing is captured until you click, so the page
still scrolls normally.
The air is the point
A grounded hit launches. A hit on something already airborne keeps it up, for
slightly less height. Strings only count while you or the target are off the
ground, which is the one Gleamwood mechanic small enough to fit here honestly.
The level is proved, not hoped
Connected open space is a claim about tiles, not about the player, and a level can
pass it while hiding a ledge nobody can reach. So a reachability model walks the
level using walking and jumping only, assuming no wall jump and no dash, and the
exit is placed at the furthest point it proved. A seed that cannot show most of
itself reachable is thrown away rather than served.
Tooling
The panel beside every demo
None of the three demos above has a control panel of its own. They all declare their
tunable values and one shared component builds the interface, which is a port of our
Unity package
Runtime Debug UI, on GitHub
The claim the package makes is that you should declare a tunable field and have the
panel follow, with no interface code written anywhere. Letting you tune three unrelated
programs through the same panel is a more convincing demonstration of that than a
paragraph would be. Values persist in local storage, saving is debounced so dragging a
slider does not thrash it, and Reset puts everything back.
The game's panel uses the declarative path and the solver's uses explicit control
configuration, because the solver wants live readouts and ranges that depend on other
controls. Both are the same component. That split is deliberate, and porting it here
is how the button control type and a fix for a panel that swallowed clicks got proved
out before going back into the C# package.
Also on the shelf
Things that do not fit in a browser
The rest of what we build for ourselves. These are real packages with real consumers,
which in a couple of cases means us.
Unity package
Runtime Debug UI
Data driven debug panels for Unity. Tabs, sliders, toggles and readouts declared as
configuration rather than built by hand, with values that persist between runs.
Installable by package manager git URL. The panels on this page are its port.
Logging for Unity that compiles out entirely in a release build. Console, file and
on screen targets, with the scripting define symbols managed automatically per
build type so nobody has to remember to turn it off before shipping.
A C++17 runtime on OpenGL 3.3 with a dockable editor, a standalone player and an
asset cooker. Cascaded shadows, physically based rendering, swappable physics and
scripting backends. There is more about it on the
services page.
Procedural generation, tooling and the unglamorous systems work that makes a team
faster. That is most of what we do when we are not making our own games.