Equipment & inventory: item schema, weapons/armor/gear catalog, character items, sheet panel#47
Conversation
…layer Rules layer: schema/items.ts (weapon/armor/gear discriminated union; M.D.C. armor rejects A.R., S.D.C. armor requires A.R. + pool), 34-item catalog transcribed from RUE pp.113/116/267-270/326-329, engine catalog with per-suit M.D.C. rolls (LLW concealed 2D6+32, p.113) and the p.287 absorb rule (armor takes the whole hit, floors at 0, never spills onto the body). Character: items[] with per-instance worn/rolledMdc state; current.armor is the worn suit's remaining pool (living-vitals pattern). deriveSheet resolves items, enforces armor-only worn/rolledMdc, one worn suit, roll-in-printed- range, and pool-below-max; surfaces equipment + worn armor on the sheet. Backend: addItem (rolls dice-capacity suits at acquisition, one transaction), removeItem (clears the pool with the worn suit), equipArmor (exclusive worn, fresh pool on change), applyDamage toArmor flag (strike-vs-A.R. adjudication stays with the GM until the combat resolver, like elapsed time in #41). PAGE_MAP.md gains the equipment chapter index.
The dossier grows the inventory surface: an EQUIPMENT — MANIFEST panel (rows with kind tags; weapons roll their printed dice into the telemetry log client-side, like skills and saves; armor rows wear/doff and discard), a catalog picker to acquire items, and a rust-toned worn-armor bar beside the vitals (amber family — armor is NOT magic) showing the live pool over the per-suit maximum with the printed dice range on hover. The Damage control gains an Armor toggle that routes the hit to the worn suit via the applyDamage toArmor flag; telemetry distinguishes the layers. All per-character control state (armor toggle included) resets on route-id change, per the navigation-state rules.
There was a problem hiding this comment.
4 issues found across 14 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/web/src/pages/character-sheet.tsx">
<violation number="1" location="apps/web/src/pages/character-sheet.tsx:344">
P1: A depleted worn armor suit can still keep body damage from landing when the Armor toggle remains on. The client keeps sending `toArmor: true` without checking the live armor pool, while the server floors a 0 armor pool back to 0 instead of treating future hits as body hits or refusing them.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…entory writes, honest refine message - applyDamage(toArmor) now refuses hits on a depleted suit: "it no longer affords protection. Any future attacks will hit the character''s body" (RUE p.287) — soaking at zero silently protected the body forever. - equipArmor is a no-op when asked for the state the character is already in, so a repeated [wear] click can never repair the worn suit by resetting its pool to max. - removeItem/equipArmor take the client''s instance snapshot (itemId + worn + rolledMdc) and refuse when the manifest shifted under an in-flight click — closes the whole stale-index bug class, not just discard. - The M.D.C.-armor refine message no longer says "both": either field alone is equally illegal on a Mega-Damage shell.
|
All four validated as real; fixed in 19105fb.
243 tests green, |
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Unequip (index: null) now requires and verifies the client''s snapshot of the suit it saw worn — a doff racing a swap refuses instead of blindly unequipping whatever became worn since. Doff with nothing worn stays a no-op (the desired state is already true, and there is nothing to verify against). Completes the instance-verification contract across all three index-based inventory writes.
There was a problem hiding this comment.
0 issues found across 3 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
Closes #43.
Items become first-class: a page-stamped catalog, character inventory with per-instance state, armor as a wearable ablative pool, and the dossier's equipment surface.
Rules layer
schema/items.ts— discriminated union overkind:category(future W.P. wiring), structureddamage(formuladice +sdc/mdtype, with the printed multi-setting sentence innotebeside the headline dice, likeppeNote), range/payload as printed strings.ar+sdcpool; M.D.C. armor =mdc.mainBodyas a dice formula, because the book prints both constants (Gladiator "70", p.267) and per-suit rolls (Ley Line Walker concealed: "2D6+32 M.D.C. main body", p.113). Refinements reject the contradictions at load: armor must be exactly one of the two shapes, and an M.D.C. shell cannot declare an A.R. (there is no A.R. on M.D.C. armor).content/items/items.json— 34 items transcribed from rendered pages this session: 8 armors (pp.113/267–268), 11 weapons (energy pp.268–270; conventional damage from the W.P. sections pp.326–329), 15 gear entries from the LLW Standard Equipment list (p.116). Counts pinned in tests.engine/items.ts— catalog load + id index,armorNeedsRoll/rollArmorMdc/armorMaxPoolfor per-suit capacity, anddamageArmorimplementing the printed absorb rule: "the armor absorbs the attack — subtract the damage from the armor's S.D.C." (p.287) — the suit takes the whole hit, floors at 0, and nothing spills onto the body; a depleted suit stops protecting future hits.items[](itemId+worn+rolledMdc) andcurrent.armor— the living-vitals pattern (feat: living vitals — current vs. max, P.P.E. spend on cast, damage tracking #40/Recovery rates & healing spells: rest/meditation/ley draw, treatment days, spell healing with targets #41): maximum on content (or the per-suit roll), live remainder on the character, illegal states rejected inderiveSheet(worn/rolledMdc are armor-only, one worn suit, roll within printed dice, pool ≤ max). The sheet surfacesequipmentand the wornarmorlayer.Backend
addItemrolls dice-capacity suits at acquisition (mutation randomness + one transaction, same rationale asrollVitals),removeItemclears the pool with the worn suit,equipArmoris exclusive and resets the pool on change (fresh suit at max; per-suit damage memory across swaps is future scope).applyDamagegrows an explicittoArmorflag: the worn suit absorbs the whole hit per p.287. Which hits strike armor (strike-vs-A.R. threshold, defender wins ties) is resolver scope (Combat resolution: strike constants + attack resolver #16/A.R. & armor damage in combat: strike-vs-A.R., armor ablation, the M.D.C. scope decision #44 companion) — until then the flag keeps it GM-adjudicated, the same philosophy as elapsed time in Recovery rates & healing spells: rest/meditation/ley draw, treatment days, spell healing with targets #41.deriveSheet;itemsis optional in the Convex schema for pre-inventory docs (the rules layer defaults it).Web
current / maxwith the printed dice range on hover.DAMAGEfromDAMAGE (ARMOR). All new per-character control state resets on route-id change.Verification
vp checkand rootvp testgreen: 241 tests (was 219), including pinned catalog counts, printed-value assertions with page cites, armor-shape refinements, absorb/floor/no-spill semantics, and backend equip/damage flows.Out of scope, per the issue: strike-vs-A.R. resolution and M.D.C. combat mechanics, W.P. proficiency bonuses, encumbrance, credits bookkeeping.
Summary by cubic
Adds a first-class equipment system with a page-stamped catalog and character inventory, plus a worn-armor layer that absorbs damage with no spill. Adds an equipment panel, a rust-toned armor bar, and an Armor toggle to route hits to a suit.
New Features
weapon/armor/gear), 34-item catalog with page cites, and helpers (getItem,itemsByKind,armorNeedsRoll/rollArmorMdc/armorMaxPool,damageArmorper p.287).wornandrolledMdc;deriveSheetenforces armor-only fields, one worn suit, roll within printed dice, andcurrent.armor≤ max; sheet shows equipment and the worn-armor bar.addItem(rolls dice-capacity suits at acquisition),removeItem(clears pool if the worn suit is dropped),equipArmor(exclusive; resets pool on change), andapplyDamagewithtoArmorto land hits on the suit.toArmortoggle); encumbrance/credits are out of scope.Bug Fixes
applyDamage(toArmor)now refuses hits on a depleted suit; GMs route those to the body per p.287.equipArmoris a no-op if the requested suit is already worn, so repeated clicks can’t “refill” armor.removeItem,equipArmor) verify the client’s instance snapshot (index +itemId/worn/rolledMdc) to avoid stale-index races.equipArmor(null, expect)), and is a no-op when nothing is worn.Written for commit 11920c7. Summary will update on new commits.