Attributes and Skills
Accessory attributes and skills are not computed by EmakiAccessory itself; they are registered into the public extension points of EmakiAttribute and EmakiSkills. Both are optional dependencies, so the corresponding half simply switches off when one is absent while the accessory panel keeps working.
Attributes into EmakiAttribute
EmakiAccessory registers a contribution provider with EmakiAttribute, feeding accessory attributes in as a distinct source. It registers no custom equipment slot and writes nothing onto the player's vanilla attributes.
The reported source ids:
| Source id | Meaning |
|---|---|
emakiaccessory:accessory | Attributes of an individual accessory. |
emakiaccessory:set | Accessory set bonuses. |
Attribute values are read through EmakiAttribute's AttributeCatalog#itemSnapshot — the same parser the equipment path uses. An accessory and a helmet carrying identical data therefore produce identical numbers, and parent-attribute expansion plus range-spread companion keys come along with it.
Range-spread companion keys are summed like any other key; otherwise a ranged accessory would keep its lower bound and lose its spread.
Skills into EmakiSkills
EmakiAccessory registers a skill source with EmakiSkills. Equipment skill payloads on an accessory are read by EquipmentSkillPdcCodec, the same PDC contract Item, Forge, Gem and Strengthen write.
Skills listed in an accessory set's thresholds[].effects[].es_skills take effect through that same path.
Slot Restriction Criterion
Accessories support active_slot declarations just like equipment. The accessory-side matching rule:
The item's active_slot | Result |
|---|---|
| Absent or "all" | Active in any accessory slot. |
A part id, such as ring | Active in any cell of that part. |
A slot instance id, such as ring_1 | Active only in that cell. |
| Anything else | Inactive. |
When an item declares several slots, every declaration must be satisfied by the current cell, otherwise the whole item's contribution is dropped. This matches the equipment path's behaviour of dropping the whole item's contribution when a declared slot does not match.
The accessory-side gate is a separate implementation because itemSnapshot performs no slot filtering while the equipment path's own gate is internal to EmakiAttribute. The accessory side additionally accepts a bare part id. If the equipment-side rules ever change, this copy must be updated to match.
When Recomputation Happens
Contribution snapshots are recomputed when accessory contents change: a GUI edit, a completed data load, or a reload.
Recomputation deliberately does not happen inside the provider callback. EmakiAttribute's combat snapshot collector calls the contribution provider while computing its cache signature, meaning the provider runs on every combat snapshot read; parsing PDC there would put item deserialisation on the combat hot path.
Threading
Recomputation must run on the owner thread of the player holding the items: the attribute parser writes its result back into item PDC as a cache, so it is not safe off-thread.
Behaviour With Modules Missing
| Missing module | Effect |
|---|---|
| EmakiAttribute | Accessories grant no attributes; the panel and set piece counting keep working. |
| EmakiSkills | Accessories grant no skills. |
| EmakiItem | unique deduplication falls back to vanilla material matching and stays active; accessory sets relying on pieces[].item are entirely inactive. |
| PlaceholderAPI | PAPI placeholders in text are no longer replaced and pass through unchanged. |
EmakiAccessory itself has no PlaceholderAPI expansion and exposes no %emakiaccessory_*% placeholders; it only consumes PlaceholderAPI optionally. The module also registers no actions into the CoreLib action registry.