Public: anyone can read this; the crew can change it.

forked from trevato/cs

What each part of the engine costs, measured: the guide says what importing a group adds to a bundle #260

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`scripts/cost.ts` measures what each group behind the engine's door adds to a bundle: for every group `src/engine/index.ts` exports it generates a tiny entry that imports exactly that group and uses every name in it, bundles it with the settings `scripts/build.ts` gives a game — browser, minified, esm — and weighs the output raw and gzipped at level 9, the ruler the ceilings in `src/games.ts` alre…

shipped production is serving it deploy ae07c2d

opened this

scripts/cost.ts measures what each group behind the engine's door adds to a bundle: for every group src/engine/index.ts exports it generates a tiny entry that imports exactly that group and uses every name in it, bundles it with the settings scripts/build.ts gives a game — browser, minified, esm — and weighs the output raw and gzipped at level 9, the ruler the ceilings in src/games.ts already use. Groups are not independent, so each row also names the modules that came along and how many of the bundle's bytes are theirs, read off the build's source map rather than off the import lines: a module the bundler loaded and then shook away is charged to nobody, which is what makes "the range ships none of the WebGL" a number instead of a claim.

group                 raw   gzip-9  brings with it
----------------  -------  -------  --------------
the door, unused       53       73  net 31
math                 1814      860  —
trace                1008      599  math 83
physics              2699     1228  math 187
grid                 2494     1241  —
mesh                  916      496  —
texture               963      580  —
sound                1805      957  —
loop                  632      437  —
controls             2669     1148  math 29
fullscreen            650      356  —
escape                758      455  —
overlay              1184      731  math 29
scene                 961      543  —
effects               993      493  —
renderer             7351     3131  math 1049
page                 3120     1577  —
digest               1538      865  —
net                  2799     1193  —
learn                4967     2081  net 1223
the whole door      36118    14696  renderer 6204, learn 3716, page 3085, net 2774, controls 2587, physics 2474, grid 2439, sound 1755, math 1735, digest 1470, overlay 1121, effects 938, texture 908, scene 907, trace 870, mesh 866, escape 704, fullscreen 600, loop 579

The lines land in src/engine/GUIDE.md under each group's heading (Weight: 7.4 kB raw, 3.1 kB gzipped — including math, which comes with it.), with the whole door's number under the section heading and a short preamble saying how they were measured and what they are careful about. scripts/cost.test.ts measures again on every run: every group has a line, every line is under a heading that is a group, the numbers are within a tenth — or 100 bytes, the page's own resolution, whichever is wider, which is the rounding the page does — and the list of modules a group brings along matches exactly. I checked both rules bite by editing the page and watching them fail.

Two things worth looking at. First, the floor: importing the door at all costs 53 bytes, because net allocates a scratch Float32Array at module scope and a bundler may not drop an allocation it cannot prove nobody watches — so net shows up in every bundle for 31 bytes, and a module counts as brought along only when it beats the floor by more than 16 bytes of minifier jitter. That is why mesh is alone and learn is honestly charged 1,223 bytes of net. Second, renderer brings only math: mesh, texture and scene reach it as types, so a game that draws pays their lines separately — 7.4 + 0.9 + 1.0 + 1.0 kB, which is the 11.4 kB the example gained in #222, and the guide says so in words rather than with an untested sum.

What I chose not to do: no --write mode that edits the guide (the script prints the lines with --guide and a person pastes them, like scripts/surface.ts --write is a deliberate act), and I did not touch net's module-scope allocation to flatten the floor — it is a hot-path scratch buffer and this issue is measurement, not surgery. No dependency, no bundle, no game changed: only GUIDE.md, the README's script list and the two new files in scripts/. bun run test is green (1140 tests).

🤖 Generated with Claude Code

Closes #169

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs