Construct an empty modifier owned by parent — shorthand for
new ValueModifier({}, { parent }).
The owning sohl.core.logic.SohlLogic.
Construct a modifier from initial state and apply it.
Data to construct the modifier.
Options to construct the modifier (carrying parent).
OptionalbaseThe base value before deltas (undefined until set; treated as 0 by base).
OptionalcustomHandler invoked by a CUSTOM delta to compute a value, when one is used.
The list of ValueDelta modifiers applied on top of the base.
Reason the value is disabled as an i18n key; empty string means enabled. Localize for display via disabledLabel. See disabled.
The base value (0 when unset).
Setter form of setBase.
Render the deltas as an HTML breakdown (name + adjustment per row) for chat cards and tooltips; when disabled, renders the localized disabled reason instead.
A compact, human-readable summary of how the value is derived: the base
contribution followed by each applied delta (e.g. Base +30, SSMod +25),
or the disabled marker (Dsbl) when disabled. An unmodified value
still summarizes as Base +N, so the summary is never empty for an
enabled value.
Named deltaLabel — not shortcode — because a ValueModifier's
derivation summary is unrelated to the document system.shortcode
identity key used across the rest of the system.
The disabled reason as stored — an i18n key (or "" when enabled).
A non-empty value forces effective to 0. This is the serialized
form; use disabledLabel for localized display (#948).
Disable with a reason string, or toggle via a boolean (passing true
applies a default reason; false clears it). A string reason must be an
i18n key (see disabled); it is localized for display by
disabledLabel.
The disabled reason localized for display, or "" when enabled.
disabledReason always stores an i18n key (never localized prose), so callers that surface the reason to a human must localize it here rather than emitting the raw key (#948). Idempotent on already-plain text.
The computed effective value — the base with all deltas applied (always 0 when disabled). Recomputed lazily on access.
Whether no deltas have been applied.
Whether a base value has been explicitly set.
A coarse index derived from the base value (base / 10, truncated).
The serialization discriminator for this instance — the concrete class's static Kind. Written into the JSON by toJSON under the kind key and read back by sohl.utils.defaultFromJSON to select the constructor. Derived from the class, never stored per-instance.
The deltas' net contribution to the value — effective − base.
Add an additive (+value) delta. A new delta replaces any existing one
with the same abbrev.
this, for chaining.
Two forms: (abbrev, value) resolves the display name from the
VALUE_DELTA_INFO registry (and throws on an unknown abbrev);
(name, abbrev, value) supplies both explicitly for ad-hoc deltas.
Fold another modifier into this one, preserving the full auditable
derivation: every labeled delta from other (its name, abbrev,
operator, and value) is replayed onto this modifier, so the merged result
keeps each source justification in its tooltip and this modifier can then
layer its own deltas on top.
Deltas are additive — other's are appended to whatever this modifier
already carries (each replayed through the internal _oper, so
same-abbrev replacement and OVERRIDE semantics apply, and the clones
are re-parented to this modifier). The base is not additive — a
modifier has exactly
one base — so other's base is adopted only when includeBase is set,
and it replaces any existing base rather than adding to it. Omit
includeBase to take other's modifiers while keeping this modifier's
own base.
The modifier to merge from.
Merge options.
OptionalincludeBase?: booleanWhen set, replace this modifier's base with
other's base.
this, for chaining.
Add a DOWNGRADE (ceiling / maximum) delta: the effective value cannot
exceed value. Same argument forms as add.
this, for chaining.
Deep-copy this entity, re-parenting the copy under parent with no other
changes. Shorthand for clone({}, { parent }).
The Logic to own the cloned entity.
The cloned entity.
Deep-copy this entity, optionally overriding fields and clone options.
Field overrides applied to the clone.
Clone options (e.g. a new parent).
The cloned entity.
Add an UPGRADE (floor / minimum) delta: the effective value cannot drop
below value. Same argument forms as add.
this, for chaining.
Find the delta with the given abbrev.
The delta abbrev to look up.
The matching ValueDelta, or undefined.
Add a multiplicative (×value) delta. Same argument forms as
add.
this, for chaining.
Add an OVERRIDE delta that replaces the value, ignoring all other
modifiers. Same argument forms as add.
this, for chaining.
Chainable form of the disabled setter.
A reason string, or a boolean (true applies a default
reason; false clears it).
this, for chaining.
A tracked numeric value composed of a base plus zero or more deltas (modifiers), producing a fully auditable effective value.
Effective value calculation
effective = base + deltas, computed lazily when accessed:base(from setBase, or 0 if unset).modifierreturnseffective - base, i.e., just the delta contribution.Disabled state
A ValueModifier can be disabled by setting a reason string. When disabled,
effectiveis always 0 regardless of base or deltas. This distinguishes "value is zero because of modifiers" from "value is inapplicable" (e.g., a skill the character cannot use).Lifecycle
ValueModifiers are created during sohl.core.logic.SohlLogic.initialize with a base from persisted data. Deltas are added during
evaluate/finalizeby active effects, cross-item dependencies, or other logic. The entire object is rebuilt on the next preparation cycle — deltas are never persisted.Auditability
Each delta has a
nameandabbrevidentifying its source, so the full breakdown of "why is this value X?" is always available via the deltas array. Use get, has, and delete to inspect or remove specific deltas by abbrev.