Move Fast and Break Things

The deploy pipeline has two gates. This challenge trips both on purpose. Make note of your prediction before each run — the point is comparing what you expected the checker to say against what it said.

Break the spec

  1. Open dox/creeps.dox. Remove work from the BodyPart union. harvesterBody still uses it.
  2. Make note of what you think paradox check --path dox will say.
  3. Run it. Compare the rejection to your prediction.
  4. Put work back and run the check again.

Break the harness

  1. Open harness/main.ts. Change the comparison role === "harvester" to a role the spec does not declare — "miner" will do.
  2. Make note of what you think the build will say.
  3. Run nix run .#deploy-local. tsc runs inside the build and rejects the comparison; nothing ships.
  4. Restore "harvester" and deploy again. The bundle lands.

Stretch Goal

This goal needs the viewer. The spawn-energy readout from the client exercise’s last section shows the cost as it happens.

Make a change the checkers accept, and watch what it costs. The steps below run twice: once on the body the spec ships with, once on the body you change it to. Every number comes from the console tab, asked for directly, so nothing depends on catching the topbar at the right tick.

First pass, on the unmodified spec:

  1. Ask the console for the price table. The console prints objects as [object Object], so ask for it as JSON:

    JSON.stringify(BODYPART_COST, null, 2)
  2. Price the creep the world actually built — read its body and sum the parts:

    Object.values(Game.creeps)[0].body.reduce((sum, part) => sum + BODYPART_COST[part.type], 0)
  3. Wait until the topbar energy reads 300, then confirm it from the spawn itself:

    Game.spawns['Spawn1'].store.energy
  4. Retire the harvester:

    Object.values(Game.creeps)[0].suicide()
  5. Ask for the spawn’s energy again. The drop from step 3 is the price of the replacement the harness just ordered, and it matches step 2’s answer.

  6. Ask what the energy bought:

    JSON.stringify(Game.spawns['Spawn1'].spawning, null, 2)

    The reply names the creep under construction and the build time — 3 ticks per body part. While it builds, the topbar count stays at 0 and the energy creeps up by 1 per tick. That slow climb is the spawn refilling; the cost already left in step 5.

Second pass:

  1. In dox/creeps.dox, add a second work to harvesterBody.
  2. Run nix run .#deploy-local. Both gates pass.
  3. The running harvester still has the old body — step 2 run now still answers the old price. Repeat steps 3 through 6. This time the drop is 300, and the build runs 3 ticks longer.
  4. Watch the new harvester at the source. Two work parts harvest twice as much per tick, so it fills in half the time and the delivery trips come faster.

← Resume “Let’s Play Screeps”