3 Commits
Author SHA1 Message Date
slaguru666andClaude Opus 5 4dd72c6248 Generated NPCs draw their posting's kit
generateNPC read R.core, R.support and R.label. It never read R.kit, so the
role card's DRAWS FROM STORES promised a Containment officer nine items and
the actor arrived holding a utility knife with a flat naturalArmour standing
in for armour it was never issued.

postings.mjs now owns the decision — drawKitFor(role, tier, {classify}) plus
a draw table per tier — because the engine resolves kit keys against the
compendium and check-generator resolves them against content.mjs, and the two
cannot import each other. Classification comes from catalogue membership and
never from the key: climbing_kit is "Breaching charges" and prybar is "Entry
bar", so anything reading a key's spelling is wrong in that posting first.

The weapon↔skill pairing table is gone. Each weapon item already names the
skill that fires it, so the skill is granted from the weapon, and a generated
NPC cannot hold what it cannot use. THREATS.attacks is now creature-tiers
only; those two keep their natural attacks on top of what they drew.

Armour is an item. naturalArmour drops to 0 on the four human tiers, where
the number was standing in for the item, and stays on the two creature tiers,
where it stacks with drawn armour as locationArmourFor already intends.

check-generator (guard 25) was written first and observed failing on nine
counts against unchanged source. One of its assertions was itself wrong —
it read for the creature-tier restriction after the loop instead of before
it, and so reported the fixed code as broken; re-scoped, it passes on the fix
and still fails against git show HEAD:ringbrp.mjs.

Measured with the new tools/npc-cohort.mjs, 2000 runs, seed 11, against the
party check-lethality freezes. Apex · Containment 68.2% -> 88.5% wipe,
Anomalous · Containment 0.3% -> 19.2%, and Dangerous · Field Lead got weaker
because its posting carries one pistol where the tier used to hand it a
rifle. Full table and three incidental findings in R-310.

Two of those findings are guards, not content. check-rules failed on a
comment that quoted the pattern it hunts for, so comment-only lines are
skipped now. update-readme held the guard list as a hardcoded array whose own
comments recorded it going stale twice; it reads the check script instead,
and so does the count-word rewrite that was separately capped at sixteen.

Not changed, and flagged in R-310: breach_suit and riot_shield declare no
coverage, so they armour every location including the head. The location
counterplay NPC_KIT_PLAN.md relies on does not exist, and that is a balance
decision rather than a side effect of this one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 00:08:12 +01:00
slaguru666andClaude Opus 5 d186d29238 NPC kit: creature tiers draw kit too, and their armour stacks
Anomalous and Apex now draw weapons, armour and gear from the posting on
top of the natural attacks they already carry. Their hide stays, and
locationArmourFor adds worn pieces to it, so Apex · Containment stands at
17 torso armour: 7 hide, 7 breaching suit, 3 riot shield raised. Mean
damage across the 61 weapons is 6.9 and the heaviest ordinary one means
9.0, so nothing but the Unmaker reliably breaks it.

Chosen deliberately with that number in hand. The spec records the
counterplay already in the rules — the shield only counts raised, and
exposedHideFor halves hide on a grounded creature outside the vital — and
obliges Phase 5 to simulate both tiers standing and grounded rather than
assert a lethality band.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 22:28:27 +01:00
slaguru666andClaude Opus 5 8b088fb3f0 NPC kit: design for issuing the posting's stores to generated NPCs
generateNPC reads R.core, R.support and R.label. It does not read R.kit,
which generateDialog prints as DRAWS FROM STORES and generateCharacter
issues. The card promises a marksman rifle and a breaching suit; the actor
gets a utility knife.

Design: the posting says what it carries, the tier says how much of it and
how good with it. Kit keys classify by which pack they resolve in rather
than by a second hand-written list. Attacks derive from the issued weapon's
own skillFamilyId/skillSpecialisationId, which retires the weapon-to-skill
pairing table. Armour becomes an equipped item and naturalArmour drops to 0
on the four human tiers, which moves the numbers and so gets measured.

check-generator.mjs is written first and observed failing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 22:15:57 +01:00