Building the Equipped Panel & Carry
When you build gear for SPAECIMH you are building nodes the sheet can weigh, not sentences. The Equipped panel and the Inventory panel are two faces of one rule — the Weight vs Carry indicator — and your job as a builder is to give the sheet honest inputs so that comparison always lands on a number it can defend.
The reference web still rules
Everything a character carries points at a real Equipment file. A row is (item, quantity) where item resolves to a gear file — never a silhouette of prose on the character. The direction is unchanged: characters carry gear; gear does not carry characters. When the party picks up something with mechanical weight, it earns its own Equipment file before any inventory row or Equipped slot points at it.
The Equipped panel is the same web, arranged by body part. Each slot is an array of references, and — the part that makes the pickers behave — every wearable item carries an equipSlot tag that decides which slot offers it:
| Equipped slot | Holds | equipSlot that fits |
|---|---|---|
head · neck · body · back · rightHand · leftHand · gloves · legs · feet | several each | Head / Neck / Body / Back / Right Hand / Left Hand / Gloves / Legs / Feet |
rings | ×4 (maxItems 4) | Ring |
belt | ×4 (maxItems 4) | Belt |
Because the body slots are arrays, a character wears a helm and a visor and a headset on their head at once — exactly the way a vehicle mounts several weapon modules. Tag each item with one equipSlot value (the slot it wears in), the same way vehicle modules carry one moduleType.
Weight is computed, never hand-typed
The whole point of the indicator is that the sheet does the math. You author the inputs — the weight on every Equipment file and the attributes/origin on the character — and the sheet derives:
carryingCapacity = (strength ?? 0) × 5 × (origin ?? 1) [kg]
totalWeight = Σ(all equipped slot weights) + Σ(inventory weights) [kg]
overloaded = totalWeight > carryingCapacity
When the sheet reports [ПЕРЕГРУЗКА], that is a computed statement, not typed text. To change it you change the inputs — drop the weight on a piece, raise ST, re-route a reference — never the derived number, exactly as with every other computed field on the Character type.
Wiring it into the Character type (the intended shape)
The Character type carries an equipped object whose slots are arrays with reference filters, mirroring the vehicle-slot pattern. Each slot's filter pins the picker to gear of the right equipSlot:
"equipped": {
"type": "object",
"properties": {
"head": {
"type": "array",
"items": {
"type": "string",
"reference": { "targets": [ {
"fileTypeSlug": "equipment",
"filter": { "op": "eq", "left": { "path": "equipSlot", "scope": "target" }, "right": "Head" }
} ] }
}
},
"neck": { ... filter "right": "Neck" },
"body": { ... filter "right": "Body" },
"back": { ... filter "right": "Back" },
"rightHand": { ... filter "right": "Right Hand" },
"leftHand": { ... filter "right": "Left Hand" },
"gloves": { ... filter "right": "Gloves" },
"legs": { ... filter "right": "Legs" },
"feet": { ... filter "right": "Feet" },
"rings": { "type": "array", "maxItems": 4,
"items": { ... filter "right": "Ring" } },
"belt": { "type": "array", "maxItems": 4,
"items": { ... filter "right": "Belt" } }
}
},
"totalWeight": {
"type": "number",
"expression": "sum($self.equipped?.head ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.neck ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.body ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.back ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.rightHand ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.leftHand ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.gloves ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.legs ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.feet ?? [], i => load(i)?.weight ?? 0) + sum($self.equipped?.rings ?? [], r => load(r)?.weight ?? 0) + sum($self.equipped?.belt ?? [], b => load(b)?.weight ?? 0) + sum($self.inventory ?? [], e => (load(e.item)?.weight ?? 0) * (e.quantity ?? 1))"
},
"overloaded": {
"type": "boolean",
"expression": "($self.totalWeight ?? 0) > ($self.carryingCapacity ?? 0)"
}
And on the Equipment type, the missing piece — the tag that makes the filters real:
"equipSlot": {
"type": "string",
"enum": ["Head", "Neck", "Body", "Back", "Right Hand", "Left Hand", "Gloves", "Legs", "Feet", "Ring", "Belt"]
}
Name the slots by what players reach for and keep rings/belt capped at maxItems: 4. Because every slot is a filtered reference array, the sheet hydrates real gear and computes totalWeight from it; the master reads the overloaded flag the moment a body-heavy roll is attempted.
Checklist
- Every item the party can carry is a real Equipment file with a real
weight. - Each wearable item carries an
equipSlottag; non-worn gear leaves it empty (so it never pollutes a slot picker). -
inventoryrows andequippedslots reference Equipment files (plain slug orequipment/<slug>) — never prose labels. - Electric/vehicle modules are tagged
moduleType(Engine/Fuel/...), notequipSlot— the two tag systems stay separate. -
carryingCapacity,totalWeight,overloadedstay computed; you edit gear weights, attributes and origin, not the numbers. - Rings and Belt are capped at 4 slots in the schema.
- Body slots are arrays with
equipSlotfilters, so a helmet + visor + headset can all live on the head and each slot's picker only offers matching gear. - The player-facing rule itself lives once in the Player's Handbook (Equipped, Inventory & the Weight You Carry); this chapter only says how to build the web it runs on.
Build the inputs honestly and the indicator is free — the machine weighs the world and tells the truth about whether you can still run.