Short, illustrated explanations of how things work.
An interactive guide to what a working software system is actually made of — the client, the edge, the gateway, identity, services, databases, caches, queues, models, secrets, telemetry and the platform underneath — and how to decide which of them you actually need. It is built around The Works, a low-poly isometric simulation in the spirit of the 90s city builders, which runs as the page's live background.
Source: docs/ · Live site: https://everyways.github.io/how-to-software/
(once GitHub Pages is enabled, see below)
Companion to how-to-sdlc, which is about how a change gets built and released, and to how-to-internet, which is about the wires in between.
A green public town sits on the left: the client district, the name desk, the edge. A moat runs down the middle with exactly one bridge — the gateway — and everything beyond it is a paved private campus laid out as a grid of districts.
That single line is the point of the whole picture. Everything west of it runs on hardware you did not choose, on a network you cannot predict, in an environment a determined person can modify. Nothing that crosses the bridge may be believed without being checked again on the far side.
The campus is arranged in three columns: the front door (gateway, identity, observatory, secrets vault), the application (cache, service hall, queue yard, platform yard), and the heavy, stateful half (model works, database vault, worker sheds, object store). The dashed cables belong to the buildings that touch everything — telemetry, the platform and the vault — and they run through the interiors of the blocks rather than along the roads, because they are relationships rather than request paths.
| Scenario | What it demonstrates |
|---|---|
| One request, end to end | The whole map, one hop at a time, with the millisecond cost of each |
| The same request, cached | The layers of cache, and what invalidation actually costs |
| An AI feature answers | Retrieval, streaming, checking the output, and the bill |
| Work that cannot happen now | Queues, workers, retries and idempotency |
| A hostile request arrives | Rate limits, filtering, and why authorisation is a separate question |
| A dependency goes down | Timeouts, circuit breakers and deliberate degradation |
| Traffic multiplies by ten | Autoscaling, and the bottleneck moving to the thing you cannot copy |
The canvas is pinned behind the article rather than boxed inside it, and it stays interactive while you read:
- The article can be hidden. A Hide the article toggle sits in the top-right corner at all times: press it and the whole text container fades away, leaving the campus the entire viewport. Press it again — or esc — and the words come back at the scroll position you left them. The toggle never hides itself, so it cannot become a mode you get stuck in.
- It follows the article. Scrolling to a section highlights the building it is about and switches the simulation to the matching scenario. Uncheck Follow the article to drive it yourself.
- Drag the margins to pan, without interrupting reading — the text panels are the only pointer-catching things on the page.
- Click a building for what it does and a link to the section about it.
- Keyboard: ← → rotate, + − zoom, space pause, esc bring the article back.
Three static files, no build step, no dependencies, no external requests:
docs/
├── index.html the article, the controls and the building inspector
├── styles.css the two-layer page: a full-viewport map with panels floating over it
└── sim.js the isometric renderer, world model and scene director
The simulation is plain JavaScript on a 2D canvas. There is no WebGL and no 3D library: buildings are axis-aligned boxes projected isometrically and drawn back-to-front with a painter's algorithm, which is how the games it borrows from did it too.
Key pieces in sim.js:
- Projection —
rotXYrotates world tiles into one of four camera orientations,projectflattens them to screen space,depthOfgives the sort key. - World —
NODES(buildings) andLINKS(roads and the cross-cutting cables, as polylines) describe the map; routes are lists of node ids resolved byroutePoints. - Terrain — tile kinds, the moat, the perimeter wall and the scenery are computed
once into
KIND_GRID, then cached into an offscreen canvas that is only redrawn when the camera moves. Since the map fills the viewport, this is what keeps the frame cost flat. The wall is the exception: it spans the whole map, so it is depth-sorted a segment at a time along with the buildings. - Packets —
spawnputs a cube on a route with a speed, an optional delay, an optionaldropAt(for requests that are refused or time out mid-journey) and anonArrivecallback used to chain the next hop. - Director —
SCENARIOSholds the scripted steps; each step writes the narration, spawns packets, and completes when they have all landed.
Several buildings draw their own state rather than being described: the service hall
draws one pod per running instance, the queue yard draws one crate per queued job,
and the cache silo draws its fill level. Changing NODES.api.instances or
NODES.queue.depth from a scenario step is enough to make that visible.
To add a step, add an entry to a scenario's steps array. To add a building, add a
node, a link in LINKS, and a draw function in BUILDERS.
Any static server works:
cd docs
python3 -m http.server 8000 # then open http://localhost:8000The site lives in docs/ so it can be published either way:
- Simplest: Settings → Pages → Source: Deploy from a branch, branch
main, folder/docs. - Or via Actions: the included
.github/workflows/pages.ymldeploysdocs/on every push tomain— choose Source: GitHub Actions.
The explanations are deliberately simplified. Real systems have more buildings, more partial failures and at least one component nobody can explain; the latency figures are plausible rather than measured; and the section on models describes a practice that is still moving. Every section is accurate in outline; none is complete. The links at the bottom of the page go to the rigorous versions.