KINDLEFALL Play free
Part 13

Art built in code

Every boon icon and a bestiary of monsters are built by code, not by hand. So we tested how far that goes: a knight built in code, next to the real one.

Most of what you see in Kindlefall comes from the CC0 KayKit packs: the heroes, the skeletons, the dungeon walls and the barrels. Everything the packs don't have was made in code. That covers all 237 boon icons, the bone spiders of Floor I, the molten creatures of Floor IV and the colossus that rules them. None of it was drawn in an art program. It was written, mostly by AI coding agents, and checked by eye.

This post covers what's already in the game, then an experiment outside it: how close can code-built 3D models get to the kit itself, and can they stand next to it without looking out of place?

237 icons, and every one is code

Part 12 told how the living style was picked: five art directions tried on ten boons. What it didn't cover is what came next: every boon, duo, relic and blessing redrawn the same way, all 237 of them.

An icon is a short piece of JavaScript that writes an SVG. A shared kit, src/icon_style.js (175 lines), holds the house style: the dark outline, the three-tone gradient bodies lit from the upper left, contact shadows, cream highlights instead of white, and the recurring characters (the Emberbolt, a skull foe, the hero, a sword, a flame). It also holds the motion primitives: spin, beat, bob, a sequence, a ring, an orbit. Each icon calls icon({...}) and gets two images back: a still for the HUD and lists, and a live one with its motion layer for the cards where your eye rests. Here is Lance of Embers, whole (lightly re-wrapped to fit):

// lance · Lance of Embers: the Emberbolt pierces a whole line of foes,
// bursting on each one.
lance: icon({
  defs: E + FIREBALL + BONE + BLAST + GLOW('gw', '#ff8a2a'),
  body: `${H()}${glowStroke('M5 57 L50 17', '#ff7a1c', 3)}
    <path d="M5 57 L50 17" stroke="#ffc04a" stroke-width="2.2"
      stroke-linecap="round" opacity="0.85"/>
    ${[[17, 46, 0.62], [30, 34.5, 0.7], [42, 24, 0.78]].map(([x, y, s], i) =>
      `<g class="b b${i + 1}">${blast(x - 1, y, 10 * s + 3, 5 * s + 2, 8)}</g>`
      + skull(x + 1.5, y + 2.5, s)).join('')}
    ${emberbolt(51, 16, 7, -41, 0)}`,
  css: M.seq('b', 3, 1.6, 0.14, 0.45),
}),

Three skulls on a line, a blast behind each, and the Emberbolt leaving at the top. The last line is the whole animation: the three blasts go off one after another, in a 1.6 second loop.

The icons are split into nine files by school (src/content/icons_ember.js, icons_storm.js, icons_relics_legends.js and so on), about 3,000 lines in all. That split is what let the work run in parallel: seven teams of agents, each owning its own files and nothing else. They worked from one rulebook, docs/ICONS.md:

A script turns each file into a contact sheet and fails on the guardrails (too big, any white, any filter). Then there's the review page: every boon in the game, the old icon frozen on the left and the new one, animated, next to it, with the 28 px HUD still beside them. Anything that looks wrong gets a flag and a note, and the notes export as a list for the next pass.

The Boon Icon Review page filtered to the Ember school: Lance of Embers, Wildfire, Deep Reserves and Soul Harvest, each with its old icon, its new icon and a small HUD-size version, plus a Flag button
The review pageBefore, after and the 28 px still for every boon. It loads the game's own modules, so it shows exactly what the game draws. All 237 shipped in build .42.

Monsters with no model

The same habit runs through the bestiary. No pack has a spider made of bones, a lava spider or an eel that lives in molten rock, so those were built in code, and they're in the game now, animating in every run. The Ossuary Spider on Floor I is a skull for a head, a ribcage for a body and six long jointed bone legs. Nothing about its walk is keyframed: each leg is procedural two-bone IK, and the legs plant and step in a tripod gait, three at a time, so the body glides while the feet stay put. Before it pounces it rears up and lights the lane it's about to take.

Floor IV reuses that walk. The Cinder Crawler is the same six-legged rig in a cracked molten shell. The Magma Eel lives in the lava itself: the spot boils, it surfaces, spits three molten lobs that land in rings, and sinks again. And the floor's boss, the Forge Heart, is a colossus whose two arms are the same IK at a giant scale: the code places the fist where it should slam and works out the elbow, and all four arm segments are drawn in a single instanced call. Underneath, each of these creatures rides a hidden KayKit body, so hits, burning, elites and room clears all work on them like on any other enemy. Part 3 tells their floors' stories.

The Knight surrounded by four Ossuary Spiders, skull-headed bone spiders whose six jointed legs step in a tripod gait; two rear up behind a glowing lane and pounceOssuary Spider
Two Cinder Crawlers, molten-rock spiders on six jointed legs, chase the Knight beside a lava river; one rears up, lights a lane and pouncesCinder Crawler
A Magma Eel surfaces from a lava river where the lava boils, spits three glowing molten lobs that land in fiery rings around the Knight, and sinks againMagma Eel
The Forge Heart, a molten colossus in a lava pool, slams one giant jointed fist and then the other into the arena, each with a shockwave ring and a burst of lightThe Forge Heart
Built in code, moving in the gameRecorded by the test bot from the game's own camera, pulled in a little. The spiders play at 0.6x speed so you can follow the legs.

That raised a question. These creatures work because nothing in the kit looks like them, so there's nothing to compare them with. Could code also make the kind of thing the kit does have, well enough to sit beside it?

The experiment

An agent spent a few hours finding out, in a separate folder, without touching the game. The setup was meant to make the comparison fair. The renders use the game's own character and world materials and its own renderer (toon shading, bloom, the colour grade, the vignette) under Floor I's lighting, so any difference is in the models, not the lights. The benchmark was the kit's Knight, the hero you start with.

A knight, twice

Two knights were built in code. The Warden is an original design in the kit's style, about 270 lines of lathes, rounded boxes and extrusions. The replica is the same code with a Knight-like helmet, sword and colours, built to copy the real one as closely as it could.

KnightTrianglesDraw callsBuilt at load in
KayKit (model file)5,2961n/a
Warden (code)8,7201 (+1 glow)about 25 ms
Replica (code)9,9821about 28 ms

Up close, you can tell. The agent's own estimate was about 65 to 70% of the kit's quality: clearly the same style family, but not the same artist. Its notes on why:

From the game's camera it's a different story. The faces shrink to a few pixels and the seams vanish, and the estimate there was 85 to 90%. A player wouldn't pick the code knight out as "not from the pack".

The KayKit Knight and the code replica seen from high above at the game's camera angle: two small grey armoured figures with red shields that look nearly alike
The same pair from the game's cameraThe angle you actually play at. The KayKit Knight is on the left.

Borrowing the kit's skeleton

The most useful result wasn't about looks. Every code-built humanoid was placed on the Knight's own joint positions and skinned to the kit's skeleton, each part weighted rigidly to one bone, which is how the kit's own models are built. So it plays every animation the kit has: the Knight's 17 clips plus the 44 shared ones. Walk, run, chop, block, spin, cheer, hit and death all deform cleanly, with no retargeting and no animator. A new character only needs its body built.

The KayKit Knight and the code-built Warden side by side, both raising their swords in the same frame of the same attack animation
Same clip, same frameThe KayKit Knight and the Warden mid-attack, driven by one animation.

That makes variety cheap. Seven characters came out of the same hero function with different options: a Warden, a Berserker, a Hooded Rogue, an Archmage, a Dwarf King, a Black Knight and a Lantern Warden. The options are helmets, weapons, shields, robes, beards, bulk and a palette. Each is 5,900 to 9,000 triangles, all seven build in about 100 ms, and once the hero function existed a new one took the agent two to five minutes.

Seven code-built characters in a row against a dungeon wall: Warden, Berserker with a horned helm, Hooded Rogue, Archmage in a tall purple hat, Dwarf King with a crown and hammer, Black Knight with glowing eyes, and Lantern Warden
One function, seven charactersEach plays a different kit animation. The Archmage, Dwarf King and Black Knight look the most finished.

Not all of it works. The Hooded Rogue's hood reads like a green helmet. And they all share one face: the kit varies face shape per character, and these only vary hair, beard and colour.

Can you tell who made what?

The real test of cohesion is a room. This one mixes the two: the kit supplies the floor, walls, torches, barrels, crates, chest, a pillar, the Knight and a Skeleton, and code supplies everything else. Have a look before you press the button.

A dungeon room from the game's camera: barrels, crates, a chest, a rock golem, a spiked beetle, a sarcophagus, an anvil, a brazier, glowing crystals, a weapon rack, a gate with a raised portcullis, a knight and a second armoured figure The same room with each object labelled KIT or CODE: the barrels, crates, chest, pillar, Knight and Skeleton are KIT; the arch gate, treasure, weapon rack, anvil, brazier, Cinder Golem, Grave Beetle, sarcophagus, crystals and Warden are CODE
Kit and code in one roomFrom the game's camera. Even the agent that built it had to label the image to tell them apart.

From up here the code pieces blend in. The arch gate, the sarcophagus and the anvil look like they could ship. Two things give them away when you look closely. Their surfaces are too clean: kit props have small chips and irregular bevels. And some parts are too thin: the brazier legs and the weapon-rack poles are thinner than the kit would draw them.

Creatures, and one sculpted from clay

The creatures were the strongest result, for the same reason the Floor IV monsters work: with no kit model to compete with, code only has to match the style. A Grave Beetle on its own 17-bone rig with a tripod gait, an Ember Drake whelp with flapping wings and a sinuous tail, and a Shroomling that hops with squash and stretch. The Cinder Golem is rough rocks on the kit's rig at one and a half times scale, so it plays the kit's two-handed attacks. It works in motion, and standing still it reads as a pile of rocks.

Four code-built creatures between the KayKit Knight and the KayKit Skeleton: a dark beetle with glowing eyes and a horn, an orange dragon whelp with spread wings, a red-capped mushroom, and a round rock golem
Grave Beetle, Ember Drake, Shroomling, Cinder GolemThe kit's Knight and Skeleton stand at the ends for scale.

The golem's problem, organic shapes made of primitives, got its own try. The Mire Hulk started as 19 shapes blended together like clay (signed distance fields), turned into a mesh of 14,800 triangles, simplified to 4,200, given flat facets and painted regions (the belly, the mouth, the brow), then skinned to a skeleton automatically by each point's distance to the bones. Tusks, glowing eyes and mushrooms went on last. The whole thing builds in about 190 ms when the page loads.

Three stages of the Mire Hulk: a smooth yellow clay-like blob, the same shape as a simplified wireframe, and the finished green ogre with tusks, glowing eyes and mushrooms, next to the KayKit KnightFrom clay to creature
The Mire Hulk with both arms raised for a slam; its shoulders stretch and the painted belly region has ragged edgesMid-slam: the weak spot
The Mire HulkNo hand modelling at all. It reads as a creature in the kit's colours; in the slam pose the shoulders stretch, because automatic skin weights are crude.

This is the path to "any organic monster". To ship, it needs better skin weights and cleaner painted regions.

Weapons, robots and the easy cases

Weapons turned out to be the easiest category of all: rigid, simple, and they attach to the hand bone. Twelve were made, from a 216-triangle spear to a 2,220-triangle lantern. Sleek sci-fi was the second-easiest style, because clean bevelled shapes are that style: a walking mech and a scout drone are some of the best-looking things in the set. Vehicles (a mine cart, a hover bike, a toy tank) came out fine but plain. They'd need panel lines, rivets and decals.

Twelve code-built weapons on stone plinths: a bone scythe, sword, crossbow, axe, dagger, warhammer, spear, lantern, staff, war horn, a glowing ember greatsword and a blasterTwelve weapons
Code-built sci-fi pieces on a dark tiled deck: troopers in visor helmets, a yellow two-legged mech, a white scout drone and a blue mushroom, with the KayKit Knight for scaleOff-theme: sci-fi
The easy casesEach weapon is one merged mesh. The troopers are on the kit's rig and play its aiming clip.

What it costs

Code models start heavier than the kit's, and there's a cheap fix: one setting scales the number of segments on every round part. At the middle level the Warden has fewer triangles than the kit's Knight and looks the same from the game camera.

WardenLooksTrianglesBuild time
Full detailthe baseline8,72027 ms
Level 1identical from the game camera3,8549 ms
Level 2a slightly faceted helmet2,8447 ms

In motion, 40 animated Knights took 3.29 ms a frame and 40 animated Wardens 3.84 ms: 65% more triangles each cost 17% more time. Both use the same 41-bone skeleton, which suggests the bones, not the triangles, set most of the cost. And a code model doesn't have to be built at load at all. The Warden exports to a standard model file (1.6 MB uncompressed, which the game's optimizer would cut to roughly 150 to 250 KB), loads back with its skeleton intact, and plays the kit's Cheer clip like any kit character.

Measured onReal-GPU Chrome with Metal on a MacBook Pro, Apple M3 Max, renders at 1920×1080. Frame times with a forced GPU sync each frame. Build times are the experiment's own measurements and vary by a few milliseconds between runs. The quality percentages are the agent's estimates from looking at the renders, not a measurement.

What we'll do with it

Nothing from the 3D experiment is in the game yet. It was one-off code, built to answer a question, and the answer is a clear split:

One finding applies to what's already shipped. Next to kit characters, a code-built creature in the kit's palette and toon material sits more naturally than one that glows by its own light, like Floor IV's molten skin. And the experiment found three things that would close most of the close-up gap: a pass that roughens chosen surfaces so they stop looking too clean, faces painted into the texture instead of built from shapes, and better automatic skin weights for sculpted bodies.

The icons went the same way. Code couldn't paint like an illustrator, and it didn't have to. It drew 237 small pictures to one set of rules, each one checked side by side against what it replaced.

Play Kindlefall

In your browser, with a keyboard and mouse or a controller.