Run the kill chain in order. The multiplier only pays when you cash out.
Hearthstone meets Mr Robot. Card deckbuilder built on MITRE ATT&CK framework (real-world cyber adversary tactics, techniques, and procedures)
What it is · Play it · Build it · The build log · Licence
Made with Claude Opus 5 over a weekend. Creative direction and game design is mine, heavy lifting of all code and development goes to Opus 5.
Every card sits on a rung of the kill chain. Climbing the rungs in order multiplies your eventual payout, and the multiplier pays on the cash-out and nothing else - so the whole game is one decision made over and over: climb one more rung, or bank it now.
| Rung | What it is for | |
|---|---|---|
◇ |
RECON | Cheap, quiet, draws cards. Opens the chain. |
▲ |
ACCESS | The workhorse damage, and the Access economy. |
◆ |
ESCALATE | Bigger hits, louder. |
» |
MOVE | Repositioning, and chain bonuses. |
■ |
PERSIST | Processes: things that keep ticking after you play them. |
▼ |
EXFIL | The cash-out. Pays the multiplier, resets the chain. |
Everything you do raises Heat. Heat is not a health bar - it is how loudly you are working, it never falls on its own, and when the trace lands the run is over. Lying low costs you a turn and buys quiet. The system fights back on its own clock with trace sweeps that escalate whether or not you are ready.
Three corporations, twelve systems, sixty cards (seven of them Zero-Days), eight Processes, two threat actors who play at completely different speeds - the Script Kiddie is loud and fast, the APT Operator is patient and cheap. There is a full run around it: a terminal login, a shell menu, target and route screens, a reward card after every system, deck purging, settings and save/load.
No illustrated art, by design. Every card's mark is generated from a hash of its id - 59 unique, always-identical sigils from one generator, and adding a card costs no art at all.
The CRT shader over all of it - scanlines, barrel distortion, chromatic aberration, phosphor bloom - is F1 to toggle, because fine text is harder to read under it and some people simply cannot stand scanlines.
In your browser is the intended way: https://brodsbytes.itch.io/chainofattack
- about 8MB over the wire, no download, saves to your browser's storage.
Binaries for Linux and Windows are attached to the GitHub releases. The Windows build has never been run - there is no Windows machine behind this project. It exports cleanly from Godot 4.3 and that is the whole claim being made for it. Play in the browser instead unless you have a reason not to.
Needs Godot 4.3 and nothing else - no plugins, no addons, no package manager.
godot --path . # play it from source
./run_tests.sh # 325 tests, ~1365 assertions, headless
./capture.sh # render a screenshot to screenshots/
godot --headless --export-release "Web" build/web/index.htmlThe web export is deliberately built without thread support, so it needs no cross-origin isolation headers and itch's "SharedArrayBuffer support" checkbox can stay off. The game is single-threaded on the compatibility renderer; threads buy it nothing and cost it browsers.
→ The build log - 2,500 lines of what was tried, what was measured, and what got thrown away, in the order it happened.
The short version: a heuristic bot plays thousands of runs to produce every balance number in this project, and the bot was wrong fourteen separate times. Each one is written up with what the wrong number claimed and what believing it cost. Three that stand on their own:
- The bot is the measuring instrument (and it was broken)
- the first time the balance numbers turned out to be describing the bot rather than the game.
- The instrument moved, the content did not
- one pass moved every win rate by up to twelve points without changing a single content value. The section that argues a diagnosis with no column behind it is a guess.
multiply_nexthad three problems and two of them were invisible- how a damage bonus on the wrong rung shipped a 165-damage one-shot.
The design it was built against is chainofattack-design-doc.md; what is left
in it is ROADMAP.md.
The UI follows §8's Hearthstone grammar - system top centre, Processes in a
ruled middle band, ratchet strip directly above a fanned hand, Access clustered
with End Turn bottom-right, negative space held in the middle per §8.5. See
chainofattack-design-doc.md for the design the § references point at.
src/game/Game.gd the session: content, run, settings, scene routing
src/game/Presentation.gd the §8.5 naming layer over already-clean ids
src/game/SaveGame.gd run persistence, between systems only
src/game/Settings.gd CRT toggle, text speed, volumes, hints seen
src/game/AudioDirector.gd every sound, and the bed that outlives the scene
src/game/Tutorial.gd the three rules a player cannot deduce
src/ui/BootScreen.gd §16 terminal login, typed and skippable
src/ui/MainMenu.gd the shell - a directory of executables
src/ui/ConfigPanel.gd c0nfig.ini, drawn as the file it is editing
src/ui/TargetSelect.gd §17 which corporation - where difficulty lives
src/ui/ActorSelect.gd §17 two-panel threat actor select
src/ui/SystemSelect.gd §17 run map - fixed sequence with progress
src/ui/ScreenChrome.gd ground + CRT pass, shared by every screen
src/ui/MenuUI.gd shared widgets for the out-of-combat screens
src/sim/HeuristicBot.gd the bot the balance numbers come from
src/ui/CombatTheme.gd palette + per-stage colour AND glyph
src/ui/SigilGenerator.gd deterministic per-card mark
src/ui/SystemPortrait.gd boss rack that corrupts as Firewall drops
src/ui/ChainLink.gd the chain drawn across the ratchet strip
src/ui/CardView.gd one card: portrait frame, hover lift, drag-to-play
src/ui/HandFan.gd arc layout, overlap, drag commit line, card launch
src/ui/Readout.gd floating terminal-style feedback
src/ui/StatBar.gd the Heat and Firewall bars, with their ghost trail
src/ui/CombatScreen.gd screen layout, overlays, tactility, resolution pacing
src/shaders/crt.gdshader scanlines, barrel, aberration, glow, §8.5 grade
Two parts, because they are two different things.
The code is MIT. src/, tools/ and tests/ - the combat state machine,
the heuristic bot, the whole measurement rig this README is about. Take it,
learn from it, build on it, no strings. That is the part worth reading and
there is no reason to fence it.
The game is not. data/*.json, the in-game writing, the design documents
and the name stay all rights reserved - see LICENSE-CONTENT.md, which
expressly permits reading, quoting, streaming, private modification and
contribution. What it does not permit is shipping the game, or a reskin of it,
on a storefront. The copyright would be mine under any licence, so this is not
about being able to sell it later; it is about not competing with free rebuilds
of it if that day ever comes.
GitHub will label this "Other" rather than "MIT". That is the cost of the split and it is worth paying.
The engine, the font and the sound effects carry their own licences, which
neither of the above touches: THIRD_PARTY.txt.



