Lullwood, our free browser horror game, ships one 3D model file and no audio files. A cold first load of the game, measured in a real browser, fetched 676 KB. That one model, a 226 KB .glb, was 153 KB of it, which makes it the second-largest download after the engine itself. Here is what we counted, how we counted it, and the part that is awkward.
What the repository ships
We read everything from our release branch at commit b03da13.
- Models: one.
public/models/letter-balloons.glbhas 26 meshes (the letters A to Z), 8,224 vertices, 12,435 triangles and no textures. It spells the leaderboard record-holder's name in the sky. It is a third-party CC BY 4.0 model that we trimmed and credit. - Audio files: none. The sound is built in the Web Audio graph.
createOscillatorappears on 53 lines of the engine,createBufferSourceon 19, andnoise()fills a buffer withMath.random(). - Textures: no
TextureLoaderanywhere.CanvasTextureappears five times; the sky backdrop is a 4 by 512 pixel canvas painted with a gradient. The only image files the game itself draws are 30 country-flag PNGs, 56 KB in all, drawn into the balloon's canvas. - Video: one,
death.mp4, 61 KB. - The forest and the animals: a tree is a six-sided
CylinderGeometrytrunk and twoConeGeometrycanopies, instanced per map chunk. Wolves, bears and lions all come from one function that calls onlySphereGeometry,CylinderGeometryandConeGeometry. Species differ by a few numbers in a spec table, not by a model.
The number, labelled
Lullwood has no separate game page. The game and a short text page share /, so it is easy to quote the wrong figure. Fetching the home page with curl and adding the script and style files its HTML names gives about 201 KB. That is the page, not the game: the engine, the model and the video load afterwards.
So we measured the game in a browser. Chrome for Testing 151, driven by Playwright, empty cache, a 1280 by 720 window, summing the encodedDataLength of every Network.loadingFinished event from the DevTools Network domain (bytes on the wire, headers included). The window runs from navigation to 16 seconds after the click that starts play. Nothing more downloaded after the click.
cdp.on('Network.loadingFinished', (e) => { total += e.encodedDataLength; }); Result: 675,829 bytes in 23 requests, and 675,844 and 675,856 on two repeats.
- Engine and three.js, one script: 215,807 (795,397 decoded)
- React, Next.js and interface scripts, ten files: 206,697
- The model: 153,478 (22.7% of the load)
-
death.mp4: 61,320 - Document, stylesheet, icons, one resized screenshot: 23,596
- Cloudflare analytics beacon and its report call: 10,955
- One flag PNG and two API calls: 3,976
The awkward part
The model is bigger than every script we ship except the engine bundle, and the glTF loader runs during engine setup, so every player downloads those 153 KB of letters before anyone has looked at a leaderboard. If the load fails, the game draws the nickname on a canvas instead. We have not decided whether that trade is right.
What this does not show
It is bytes, not time. It is one desktop browser on one network on one day, not a mobile run, and we have no frame-rate or memory comparison against an asset-based game. So there is no speed claim here and no claim that code-built art is better. A wolf drawn from spheres looks like what it is.
The full version, with a line number for every claim, is the Lullwood devlog post this one is cross-posted from. You can also play Lullwood free in your browser and watch the network tab yourself.
Disclosure: we are the studio behind Lullwood. This post was drafted by an AI agent, checked by a second agent against our written brand rules, and published by the studio.
