R-273: the opposed roll, built where the authority lives

The content has called for 'opposed POWx5' since before the rule existed -- the
hollow man's tactics, CLEAN GROUND twice, slice-text three times -- and rules.mjs
defined none. A scenario carried a local ruling that said in its own text it was a
ruling and not a rule.

Generalises that ruling rather than inventing another: both sides roll, the better
band wins, only the ladder the game already has. Ties go to whoever is being acted
upon, which is what defenceOutcomeFor has always said; the scenario's 'favour the
agent' gave the same answer only because no agent ever initiates one. Neither side
succeeding leaves the contest unsettled rather than won, which the two beats need
in opposite directions.

Two exports at the scenario session's request: opposedOutcomeFor compares graded
levels and carries both, so a caller can price a fumbled attempt without this file
deciding what a fumble costs; opposedContestFor runs it from ratings and rolls with
per-side difficulty, so 'resists at Difficult' does not put applyDifficulty back
into a document. Spot-checked against the real Act Four beat: 55 against 85 at
Difficult, which is 42.

Page 1 states it by asking it -- the tie-break and the margin are computed from the
rule at build time, so the book cannot drift from the engine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
slaguru666
2026-09-13 10:42:17 +01:00
co-authored by Claude Opus 5
parent d03b3208e5
commit cdbb2e34ee
5 changed files with 161 additions and 3 deletions
+49
View File
@@ -6160,3 +6160,52 @@ value and exactly why an assumption inside one is the least likely thing in the
questioned. Both new guards are therefore built to refuse rather than to record: one will not
write a censored measurement, the other will not let an unstable figure be cited. Neither can
be satisfied by re-recording.
## R-273 — the opposed roll the content had been calling for since before the rule existed
The hollow man's THE FILE IS YOURS NOW says "opposed POWx5". CLEAN GROUND calls for one
twice. `slice-text.mjs` uses the word three times. `rules.mjs` — the single authority —
defined no opposed roll at all, and a scenario was carrying a local ruling that said in
its own text that it was a ruling and not a rule. That is the honest way to hold a gap
open and it is not a way to close one.
**The rule is the scenario's ruling, generalised, not a new invention.** Both sides roll,
the better band wins, and it uses only the ladder the game already has. Two changes in
making it general:
*Ties.* The scenario said "equal bands favour the agent", which `rules.mjs` cannot say
because it does not know who is a player. It now says **ties go to whoever is being acted
upon** — which `defenceOutcomeFor` has always said, since a defence turns aside a blow of
its own quality or better. The scenario session checked every opposed beat in its document
rather than assuming there were two: in both, the antagonist is the aggressor, so the two
formulations give identical answers everywhere the game actually asks. Its version was
parochial and read correctly only because no agent ever initiates one.
*Unsettled is not a win.* If neither side reaches a success the contest is unsettled —
`{ winner: null, settled: false }` — rather than a win for the resister. The difference is
visible at the table, and the scenario needed both halves: the hollow man's swap is a
repeatable attempt within a scene, and the Act Four countdown row fires once and is marked
permanent. The rule carries the distinction and deliberately does not say which applies.
**Two things the scenario session required, both of which changed the shape.** It asked
for both sides' levels in the return, so a scenario can price a fumbled swap without this
file deciding what a fumble costs; and it asked for per-side difficulty, because its Act
Four beat is *Ashcroft resists at Difficult* — 85 to 42 — and a rule taking two flat
ratings would have forced `applyDifficulty` back into its prose, which is the arrangement
check-rules exists to forbid. So there are two exports: `opposedOutcomeFor` compares two
graded levels, and `opposedContestFor` runs the whole thing from ratings and rolls through
`resolveBands` and `gradeRoll`. Neither redefines anything.
**Spot-checked against a real beat rather than an invented one.** The Act Four contest is
in check-rules: POWx5 55 against 85 at Difficult, which resolves to 42, and the tie goes to
Ashcroft. 112 rules, 413 formulas.
**And it reaches a page, because a rule nothing reaches is this project's oldest defect.**
Page 1 of the player rules now has "When two people want opposite things", and it states
the rule by ASKING it — the tie-break sentence and the margin example are computed from
`opposedOutcomeFor` at build time, so the book cannot drift from the engine. That is the
arrangement the rest of that document already uses and the reason it has never been wrong.
`docs/scenarios/` is untouched by me. The local ruling is the scenario session's to delete,
and removing the line that says the game has no opposed roll would have been the obvious
courtesy and exactly the wrong one.