Summary
#14 made a raised block absorb bullets. That is the right rule, and it moves a
number nobody has measured: can a sword fighter now simply hold RMB and walk
down a gunner?
This issue is a measurement, not a change. It may well conclude that nothing
needs doing — but right now the answer is an opinion, and the project's rule is
that a tuning claim is settled with numbers.
The argument on each side
It is fine. Every cost of blocking is still paid: it covers one side only,
it slows you to 55% walk speed, it does nothing against an uppercut or a Massive
Strike, and — decisively — it requires the sword stance, so a fighter absorbing
shots cannot return fire. A gunner's answer to a guard is to move around it.
It might not be. Closing distance is the gunner's whole problem, and a guard
that costs the approacher nothing but time converts the gun from "a range
advantage" into "a delay". 55% of 220px/s is still 121px/s, which crosses the
arena in well under seven seconds while taking zero damage from the front.
How to measure it
The training room can answer this directly, which is most of why it exists:
await __training.run({
name: "guard walks down a gunner",
config: {
behaviour: "slash", // in gun stance the attack beat fires
dummyStance: "gun",
facing: "foe",
// Opposite ends of the clear lane between the pillars.
spawn: { player: { x: 330, y: 480 }, dummy: { x: 470, y: 480 } },
timing: { periodMs: 300 },
},
steps: [{ intent: { block: true, right: true }, holdMs: 4000, aimAngle: 0 }],
});
Report player.damageTaken on arrival, and the same run with the block dropped
as a baseline. Keep both fighters clear of the pillars — PILLAR_LEFT
(x 280-304) and PILLAR_RIGHT (x 496-520) eat bullets, and a run staged across
one measures cover rather than a guard. That mistake has already been made once
here, in the first version of the bullet battery row.
Worth measuring across a few starting distances, and in AI vs AI: the brains now
have a defensive option against the gun they did not have before, so
diagnose.mjs --mode=online --runs=3 may show the ranged game shrinking. Read
bulletSummary.tracked and the meleeSummary counters, not the verdict.
If it is a problem
The fix is a cost on blocking, not a revert — a guard covering bullets is
correct, and the same rule as melee. Candidates, in rough order of preference:
- Slow the walk further while blocking (currently 55%). The cheapest lever
and the one that directly prices "advancing behind a guard".
- A stamina or duration cap on a held guard. Introduces a new resource,
which is a much larger design change than it looks.
- Chip damage through a blocked bullet. Cheap to implement and a real
fighting-game convention, but it introduces a second damage concept that
exists nowhere else in this game.
Whatever changes, specs/melee.md and specs/combat.md change with it, and the
number's justification goes in the spec — a tuning constant without a recorded
reason is the thing that rots.
Definition of done
- A measured answer, with the numbers in this issue.
- If nothing needs changing, say so here and in
specs/combat.md, so the
next person to wonder does not have to re-run it.
Summary
#14 made a raised block absorb bullets. That is the right rule, and it moves a
number nobody has measured: can a sword fighter now simply hold RMB and walk
down a gunner?
This issue is a measurement, not a change. It may well conclude that nothing
needs doing — but right now the answer is an opinion, and the project's rule is
that a tuning claim is settled with numbers.
The argument on each side
It is fine. Every cost of blocking is still paid: it covers one side only,
it slows you to 55% walk speed, it does nothing against an uppercut or a Massive
Strike, and — decisively — it requires the sword stance, so a fighter absorbing
shots cannot return fire. A gunner's answer to a guard is to move around it.
It might not be. Closing distance is the gunner's whole problem, and a guard
that costs the approacher nothing but time converts the gun from "a range
advantage" into "a delay". 55% of 220px/s is still 121px/s, which crosses the
arena in well under seven seconds while taking zero damage from the front.
How to measure it
The training room can answer this directly, which is most of why it exists:
Report
player.damageTakenon arrival, and the same run with the block droppedas a baseline. Keep both fighters clear of the pillars —
PILLAR_LEFT(x 280-304) and
PILLAR_RIGHT(x 496-520) eat bullets, and a run staged acrossone measures cover rather than a guard. That mistake has already been made once
here, in the first version of the bullet battery row.
Worth measuring across a few starting distances, and in AI vs AI: the brains now
have a defensive option against the gun they did not have before, so
diagnose.mjs --mode=online --runs=3may show the ranged game shrinking. ReadbulletSummary.trackedand themeleeSummarycounters, not the verdict.If it is a problem
The fix is a cost on blocking, not a revert — a guard covering bullets is
correct, and the same rule as melee. Candidates, in rough order of preference:
and the one that directly prices "advancing behind a guard".
which is a much larger design change than it looks.
fighting-game convention, but it introduces a second damage concept that
exists nowhere else in this game.
Whatever changes,
specs/melee.mdandspecs/combat.mdchange with it, and thenumber's justification goes in the spec — a tuning constant without a recorded
reason is the thing that rots.
Definition of done
specs/combat.md, so thenext person to wonder does not have to re-run it.