How Klanki is made
Klanki is a marble-machine building game for kids who cannot read yet. It ships in about one megabyte, contains no image files, talks to no server, and every level is guarded by tests that play it. This page is the engineering story.
This clip was not screen-recorded. The game re-simulated the machine offscreen and encoded it in about two seconds — more on that below.
Big machines, and a machine that plays a tune
Version 1.2 added a chapter where part of the machine is already bolted to the table and the child finishes it, and a xylophone part: every bar plays a note, so a staircase of bars plays a tune. Both clips below were rendered by the game itself, offscreen, in about two seconds each.
Version 1.4 made the sandbox bigger: one button unfolds the table to three screens wide and the camera follows the marble. Two new blueprints are built for it — Old MacDonald, the whole song played by a marble on 26 paper xylophone bars, and Everything, which puts all twelve parts into one machine. That brings the blueprints to seventeen, and the machine on the table is now kept between visits.
Why it exists
Klanki is made by one developer, and it started as a game for my daughter. She could not read yet, and I wanted her to have a building game that never stops to explain itself in words — one where a plank looks like a plank, the marble shows whether you were right, and nothing on the screen is trying to sell her anything.
She is still the first playtester. When she found the early levels too easy, the later chapters got harder; when she loved the sandbox but did not know what could be built in it, the blueprint cards appeared. Being a team of one is also why the engineering below looks the way it does: whatever could be generated, tested or left out, was.
The numbers
| Download size | about 1.1 MB (the .ipa) |
|---|---|
| Image assets | 0, apart from the app icon — and the icon is generated by a script too |
| Sound | 13 WAV files, 232 KB, synthesised by one stdlib-only Python script |
| Code | about 6,200 lines of Swift, SpriteKit inside a SwiftUI shell |
| Dependencies | 0 packages, 0 SDKs |
| Network calls | none of ours: only StoreKit and the iCloud key-value store |
| Data collected | none — the App Store label says Data Not Collected |
Paper drawn by a random number generator
Everything on screen is a vector path built at runtime. A plank is a rounded rectangle whose outline points are nudged by a point or two, stroked with a 3 pt ink line and given a hard offset shadow, so it reads as something cut out of paper by hand.
The nudging comes from a tiny seeded generator (splitmix64), and every object gets its own seed. That matters more than it sounds: with an unseeded generator the outline would be re-rolled on every redraw and the whole world would shimmer. With a seed, a plank wobbles exactly the same way every frame, on every device, and in every screenshot.
The side effect is the size. There are no sprites to ship, nothing to export at three resolutions, and the art scales to any screen for free.
Foley from the Python standard library
The clacks, thocks and boings are synthesised by one Python script that imports only math, random, struct and wave: short noise bursts through resonant filters for wood, a pitch-dropping sine for the springboard, filtered noise for cardboard. No sample packs, so no licences to track, and a sound can be retuned by changing a number and re-running the script.
Levels that are played by tests
A physics puzzle breaks silently. Change the springboard’s bounce to fix level 12 and level 24 stops being solvable, and nobody notices until a child is stuck. So each of the 36 levels ships with its authored solution, and the build has to pass four gates before it goes anywhere:
solve places the authored solution and drops marbles until one reaches the cup. playtest solves the level the way a child does — real drags from the tray through the same touch code a finger uses, deliberately missing the target by up to 40 pt. cheat is the lazy-child test: it removes each part of the solution in turn, and if the marble still gets home the level fails, because a part that is not needed teaches nothing. A fourth gate assembles every sandbox blueprint.
The gates have teeth. While fixing a bug where the springboard pushed a marble into itself when hit from below, a too-broad rule about edge hits broke level 12, whose jump leaves from the very lip of the board. The solve gate caught it three runs out of three.
There is also a report-only gate that asks a harder question — can a level be solved by hand with no hint outline at all? It perturbs every part by ±90 pt and ±10°, twenty times per level. It runs the physics offscreen without rendering, so 580 simulated attempts take about twelve seconds.
Video export by re-simulating, not recording
Children can film their machine. Screen capture would tie the result to the device’s speed, so the game does something else: it takes a snapshot of where the parts stand, rebuilds the scene offscreen, and steps it through SKRenderer at a fixed 1/60 s into a Metal texture backed by a pixel buffer that goes straight to the H.264 encoder. Sound is the same list of events the game would have played, mixed into PCM from the same WAV files.
In the simulator a twelve-second clip takes two to three seconds. SpriteKit physics is not deterministic, so a machine that worked for the child may miss on the retake; the exporter films up to five takes and keeps the first one that scores. Clips stay on the device until a grown-up shares them from behind the parental gate.
Data Not Collected as architecture
The privacy label is not a policy we promise to follow; it is a description of what the binary can do. There are no third-party SDKs, no analytics, no crash reporter, no accounts and no server of ours. Progress syncs through the family’s own iCloud key-value store. The only numbers we ever see are Apple’s aggregate sales and App Analytics reports. This site sets no cookies either.
The cost is real: we cannot see where children get stuck. The gates above are partly a substitute for the telemetry we chose not to have.
Try it
Chapter one and the starter sandbox are free on iPhone and iPad. Questions about any of the above: [email protected].
Download on the App Store