v0.4 status — visual rework and a much bigger map, still not shipped
October 4, 2026
v0.4 is late. I do this in the hours I'd otherwise spend on CTFs or reading CVE writeups, so "late" means "the scope grew past what I budgeted," not "something's broken." What was going to be a couple of new scenarios turned into a rework of how the whole battlefield reads, and I'd rather hold it than ship it half-finished. Status dump below, same way I'd write up a project before handing it to the next shift.
Sprites, and the building/badge split
Every unit and building got redrawn — hand-composed pixel art this time, not the flat-shaded procedural shapes the first pass used. More interesting than the art itself is the classification rule behind it, because I ended up solving it the same way I'd triage assets in a real environment: by what the thing is, not by what it's called.
A node that's a place — SOC Headquarters, a file server, a database, anything you'd actually write into a crown-jewel asset register — gets a full isometric sprite with a hue-shift shader over it, so one rendered asset recolors to red or neutral-gray depending on who owns it at runtime instead of needing three hand-painted variants. A node that's a network control — firewall, gateway, a segmentation boundary — never gets a sprite. It's a flat hex badge with a glyph, full stop, because a firewall's job is what it does to a route, not its curb appeal. I kept that boundary strict even where it was tempting to blur it: a node that's internally called "firewall" but is actually a critical chokepoint still renders as a badge, because its role is still "controls a route," regardless of how important the thing behind it is. Anything without dedicated art yet just fails safe to the badge instead of throwing a missing-texture error. Same instinct as defaulting an unknown service to deny instead of allow.
Construction, unit deploys, and compromise spreading through a node's structure all got proper draw passes too, instead of instant pop-in and a flat recolor.
Audio exists now
Didn't before. It's all synthesized — sine and triangle tones with short envelopes, generated from a script, same "don't hand-import assets you can generate" policy the sprites used to follow before this pass. Split by event class so a scan sweep, a kill confirmation, and a compromise alert are distinguishable without looking at the screen: selection, orders, production, detection, danger, containment, resolution — basically log-level severity, but as sound design. Placeholder fidelity, real taxonomy. There's a hook already wired for per-unit acknowledgement lines; nothing's recorded into it yet.
The map got 6x bigger, and had to earn it
The old map fit on one screen, which meant zero real network segmentation — everything was in blast radius of everything else. The new Large Enterprise map is 7200x2400, 36 nodes, 10 of them strategic objectives, laid out in actual segments: internet edge, DMZ, corporate, identity, dev, cloud, data centre, SOC. A few mechanics only exist because the map finally got big enough to need them:
- You start knowing your own SOC enclave and nothing past it. No free visibility — everything else gets found by actually sending Analysts out to recon it, which is closer to how asset discovery works on a real network than "the whole map is lit up from turn one."
- Movement is in-zone (free) or inter-zone (routed over the gateway graph, shortest path, not a straight line). Red pathfinds the same graph. Segmentation cuts both ways, which is the point of segmentation.
- Scan stopped being "reveal every Red unit on the map" and became "reveal the area around whoever's running it." A SIEM query against your whole estate doesn't scale either — you scope it.
- Income comes off the strategic nodes you're actually holding, not off headcount, so territory is the economy instead of a side effect of having units.
Mistakes, for the record
Writing these down mostly for myself, but a status update that only lists wins isn't one I'd trust from anyone else either.
- Shipped a building that ballooned to roughly 12x its intended size the instant it finished construction. Root cause: one code path scaled sprites off their actual texture size, a second path (the per-frame "just came online" animation) still divided by a leftover hardcoded 32px constant from when every sprite actually was 32px. Worked fine in testing because every sprite still was 32px at the time I wrote that second path — the mismatch only became visible once one asset stopped being that size, and by then the two code paths had quietly drifted apart. Didn't catch it myself; a real playtest did.
- Built the building/badge classification rule twice. First pass keyed it off whether a node was flagged critical, which sounded right and was wrong — it meant an ordinary firewall on a high-value path would render as a full building just because the node behind it mattered, which is exactly the "importance leaks into presentation" confusion the rule was supposed to prevent. Had to scrap it and key off role instead. Should have modeled the actual decision — what IS this thing — before modeling a proxy for it.
- Had an asset silently failing to load for an unknown number of sessions because its import cache went missing and nothing errors on that, it just quietly falls back to a placeholder. No log line, no crash, just a slightly wrong building sitting there until someone looked closely enough to notice.
- Watched my own test tooling get bitten by a scripting-environment race: a one-off script that injects a scenario at startup ran before the engine's own scenario loader had initialized, so the first read of scenario state silently reloaded from disk and wiped what I'd just injected. Lesson that generalizes past this project: "set X then immediately read X" isn't safe to assume if something else also owns lazy-initializing X.
Why it's not shipped
Two structural changes at once — the building/badge split and a 6x map — is more surface area than I'd normally take live in one release, and a few of the larger systems on the new map are still running placeholder art instead of something dedicated. More to the point: the large map has only been exercised by a scripted bot opponent so far. No human has sat down and played a full match on it. I don't ship anything I haven't dogfooded, and this hasn't been dogfooded yet.
Next
Finish the remaining art, get a real human playtest of Large Enterprise logged, then ship. Join the wishlist if you want the ping when it's live.