Repository navigation
api health
Audience: developers of Coffee Pub modules that colour, sort, or branch on how hurt a creature is.
Scope: reading hit points and classifying them into severity tiers, so every module in the suite draws the same line between injured and bloodied.
Mechanism and design rationale live in architecture/architecture-tool-windows.md.
A module that shows health in colour needs boundaries, and every module that invents its own gets different ones. The result a GM sees is a portrait ring, a bar, and a token indicator disagreeing about whether a creature is bloodied.
These functions are that single definition. The boundaries are world settings, so a GM configures them once and every consumer follows.
const blacksmith = game.modules.get('coffee-pub-blacksmith')?.api;
blacksmith.getActorHP(actor); // { value, max } or null when unreadable
blacksmith.getHealthPercent(actor); // 0-100, or null when unreadable
blacksmith.getHealthPercentForHP(hp); // same, from a raw { value, max }getActorHP resolves the shapes Blacksmith supports (system.attributes.hp, system.vitals.hp,
system.hp) and returns null rather than zero when an actor has no readable hit points -- an actor with
no HP is not an actor at 0 HP, and the two must not be conflated.
getHealthPercentForHP is the same answer for callers holding the HP object rather than the Actor -- a
Handlebars helper, most often. It clamps to 0-100 and returns null when there is no usable max or no
usable value: an actor with a max and no readable value is missing data, not a corpse, and answering 0
would classify it as dead.
Use one of these rather than dividing by hand. The arithmetic is exactly trivial enough that every module
writes it slightly differently and nobody checks -- guarding max > 0 in one place, clamping in another,
and rendering NaN% everywhere else.
blacksmith.getHealthSeverity(percent); // from a 0-100 percentage
blacksmith.getHealthSeverityForHP({value, max}); // from a raw pairBoth return one of:
| Value | Meaning |
|---|---|
healthy |
Undamaged. |
hurt |
Damaged, but above the Injured threshold. |
injured |
At or below the Injured threshold. |
bloodied |
At or below the Bloodied threshold. |
critical |
At or below the Critical threshold. |
dead |
At or below 0. |
null |
No readable hit points. |
Boundaries are inclusive: a creature at exactly the Bloodied threshold is bloodied.
hurt has no threshold of its own. It distinguishes a scratch from an untouched creature, which some
consumers care about and others do not; a consumer that does not should treat it as healthy.
const { injured, bloodied, critical } = blacksmith.getHealthThresholds();The configured percentages, defaulting to 75 / 50 / 25. Reads settings directly, so it needs no window open and no manager instance -- a tray handle that rebuilds on every render can call it safely.
Blacksmith does not know your CSS. Map the returned string yourself:
const SEVERITY_CLASS = {
healthy: 'my-healthbar-healthy',
hurt: 'my-healthbar-healthy',
injured: 'my-healthbar-injured',
bloodied: 'my-healthbar-bloodied',
critical: 'my-healthbar-critical',
dead: 'my-healthbar-dead'
};
const cls = SEVERITY_CLASS[blacksmith.getHealthSeverityForHP(hp) ?? 'healthy'];blacksmith.getPartyHealthSummary(); // { current, max, percent, currentDisplay, maxDisplay }
blacksmith.getPartyActorHp(actor); // { current, max }Aggregates across the configured party roster. getPartyActorHp returns zeroes rather than null for an
unreadable actor, because it is a summing helper; use getActorHP when the difference matters.
- Ai assistance
- Applicationv2 traps
- CSS traps
- dnd5e conditions
- Documentation standard
- Token actor identity
- Campaign
- Canvas
- Chatcards
- Compendiums
- Contextmenu
- Core
- Create journal entry
- Dialog
- Active Effects
- Entity list
- Equiplocations
- Geography
- GM request
- Gmnotes
- Health
- Hookmanager
- Importer
- Inventory
- Menubar
- Notes
- Party
- Pins
- Quantity split
- Requestroll
- Rolls
- Scene config
- Sockets
- Stats
- Tags
- Toast
- Tokens
- Toolbar
- Window
- Worldclock