# Seams

Everything else a plugin declares **adds**. A seam **replaces**.

Exactly one plugin owns a seam, or nobody does. That exclusivity is the point: two plugins
both rewriting the damage formula would have no defined result, so the engine does not
allow it.

## The seams

| Seam | Replaces |
|---|---|
| `variance` | every damage spread in the game |
| `armor` | what a target subtracts |
| `damageFormula` | turning the parts of a blow into a number |
| `damageTaken` | what a blow costs the one taking it, after armour and guarding |
| `weaponAttack` | the whole swing |
| `levelUpAward` | what a level grants |
| `enemyXpValue` | what a kill is worth |
| `simulateNpc` | which NPCs the world bothers to think about while nobody is watching |

## They nest

Replacing `damageFormula` leaves `variance` and `armor` available — your formula can call
them or ignore them. You are replacing one layer, not the whole stack.

That is why `weaponAttack` exists separately: a game whose attacks are not a roll against a
defence *at all* replaces the whole swing rather than trying to express itself through a
formula that assumes one.

## Not every seam is about combat

`simulateNpc` is the one to look at if your world is large. Every NPC the background pass
considers costs something, and the engine's own answer is "all of them" — which is right for a
village and wrong for a continent. Narrow it and the rest of the world simply holds still until
the party is nearer:

```js
$.stat('hopsFromParty') <= 2
```

It reads how far each NPC is from the party **on the map as it stands this turn**, so a
drawbridge your plugin opens changes what counts as near. `-1` means there is no route at all,
which fails every `<=` test on purpose.

The trap is writing a rule that is true forever. An NPC nobody ever simulates never finishes
anything, so put a floor under it:

```js
$.stat('hopsFromParty') <= 2 || $.stat('turnsSinceSimulated') > 10
```

You can also read your own plugin's fields with `$.field(...)`, which is how a faction plugin
keeps its own people alive while everyone else idles.

## When to use one

Reach for a seam when the engine's calculation is **wrong for your game**, not when it
needs tuning. A game that wants tougher characters edits the
[`maxHp` dial](/docs/formulas). A game where damage is decided by suit-matching cards
replaces `weaponAttack`.

If a [dial](/docs/formulas) can express it, use the dial. Seams are the heavier tool and
they take ownership away from everyone else.

## Next

[Cooperation](/docs/plugin-cooperation) — for everything that adds rather than replaces.
