Skip to content

Combatant

One participant in a combat, and the mutable state that belongs to this fight.

A Combatant is not a creature — it points at one via reference and reads its statistics from there. What lives on the combatant is what changes during the fight: current hit points and other ranges in data, active effects and modifiers, and its place in the turn order via initiative.

That split is what lets six goblins share one monster entry while each tracks its own damage. The reverse case is a shared combatant — a player character, whose entity is unique — where the Entity/combatant link means state persists between sessions instead of being deleted with the combat.

A combatant may also be tied to a map Token, in which case label, name, role and visibility are kept in sync between the two.

  • SeeAlso: Game, Initiative, Entity, Token

View JSON Schema

Property Type Required Description
id string Yes The unique identifier for this combatant. A UUID string automatically generated when the combatant is created. This serves as the primary key in the Realm database.
label string No A short label distinguishing this combatant from identical ones. Assigned by Game/addCombatant(_:) and mirrored onto the map token. Friendly combatants get a bare letter, others a letter and number.
Examples: "A" — a friendly combatant; "G1", "G2" — the first and second goblin SeeAlso: CombatantLabel, uniqueName
name string No The display name of the combatant. Copied from the referenced entity or token when the combatant is created, and editable afterwards so a creature can be renamed for this fight only.
Examples: "Goblin"; "Thorin Ironforge"
role Role No Which side the combatant is on. Drives colouring on the map, experience totals and automatic initiative rolling. A nil value is treated as hostile. SeeAlso: Role, isHostile, isFriendlyOrNeutral
hidden boolean No Whether the combatant is concealed from the players. Hidden combatants are omitted from the player display and the web client’s initiative list. Kept in sync with the map token’s visibility.
notes string No Game-master notes for this combatant. Free-form annotations scoped to this fight — tactics, reminders, what the creature is carrying.
initiative Array<Initiative> Yes This combatant’s places in the turn order. Usually one entry, but a combatant can act several times per round, so systems with multiple actions or legendary turns produce more than one. SeeAlso: Initiative, rollInitiative(), activeInitiative
data Object No Per-combat state overriding the referenced entity’s values. Holds whatever changes during the fight — most importantly the ranges configured by the system, such as current and maximum hit points. Values here take precedence over the entity’s own data when the combatant’s view context is built.
Usage Examples: "hp.current", "hp.maximum", "hp.temporary" Note: The structure of this data varies by game system.; SeeAlso: configureRangesFromEntity(_:), rangeFor(_:title:)
attributes Object Yes Dynamic attribute storage supporting various data types. A flexible key-value store for attributes and properties that need to be queryable or frequently accessed. Supports multiple data types through RealmAny.
reference string No A soft link to the Entity this combatant represents. Stored as an app URL rather than a Realm relationship, so a combatant survives the entity being unavailable and can be serialized on its own. Resolved through CacheManager by entity and entityId.
Examples: "/monster/goblin"; "/character/thorin-ironforge" SeeAlso: referenceURL, entity
modifiers Array<Modifier> Yes Adjustments applied directly to this combatant. Applied on top of the combatant’s context when its view context is computed, alongside the modifiers carried by effects.
Examples: Equipment bonuses (+2 to AC from armor); Temporary penalties (-2 to attacks) SeeAlso: Modifier, activeModifiers
effects Array<StatusEffect> Yes Conditions currently affecting this combatant. Each effect may carry its own modifiers, which are applied together with modifiers.
Examples: Conditions: "poisoned", "stunned", "paralyzed"; Buffs: "blessed", "hasted", "invisible" SeeAlso: StatusEffect
bloodied any Yes
defeated any Yes
player any Yes
image any Yes
entityId string No The identifier of the referenced entity, without loading the entity itself.
entityType any No The kind of content this combatant references, derived from reference. Determines which system configuration applies — ranges, defeated conditions, role defaults.
tokenId any Yes

One slot a Combatant occupies in the turn order.

Turn order is modelled as entries rather than a single number on the combatant, because a combatant can act more than once per round — legendary actions, multiple initiative counts, or a system that hands out several turns. Each entry carries its own rolled value and, once Game/sortInitiative() has run, its order within the round.

An entry with no order exists but is not yet in the turn order.

  • SeeAlso: Combatant, Game

View JSON Schema

Property Type Required Description
id string Yes The unique identifier for this initiative entry. A UUID string generated when the entry is created. Embedded objects have no primary key, so this is what Game/initiativeId points at to mark the acting entry.
name string No An optional label for this entry. Distinguishes a combatant’s several entries from one another where the system gives them distinct meanings.
Examples: "Legendary Action"; "Lair Action"
value AnyRealmValue Yes The rolled or assigned initiative value. Held as AnyRealmValue because systems score initiative differently — a number in most, a drawn card or suit in others. .none means the entry has not been rolled yet and it is excluded from sorting.
Examples: .int(17); .string("Ace of Spades") SeeAlso: roll(), Game/rollInitiative(for:)
order integer No This entry’s position in the round, counting from 1. Assigned by Game/sortInitiative(). nil while the entry is not part of the turn order — which is exactly what isActive reports.