Skip to content

V0.8.9

Latest

Choose a tag to compare

@trevlar trevlar released this 07 Aug 05:40

Version 0.8.9

Compatible with Foundry VTT v13. Manifest: https://github.com/Nimble-Co/FoundryVTT-Nimble/releases/download/0.8.9/system.json

Back up your world before updating. This release runs migrations 027 through 041, which rewrite embedded copies of Berserker, Commander, Hunter, ancestry and Rage content on your existing actors.

Actions became something rules can talk about. Three new rule types (actionCost, actionDelta, grantActivation) cover features worded "for free", "costs 1 less", "gain 1 action on your next turn" and "an ally may immediately attack", and zero-cost activations are finally representable, so a Free action no longer quietly debits an action. The Commander is the first class built on all of it.

Damage resolution was rebuilt around the attack rather than the damage packet. Resistances, vulnerabilities and immunities now apply to heroes and monsters alike, damage reduction gained a half mode, and a card's damage applies in one pass so a reduction larger than the first packet carries into the next instead of being wasted. Alongside it, the Berserker's Fury Dice, the Oathsworn's Judgment Dice and Hunter's Mark all became mechanical, built on generic rules (toggleEffect, markTarget, conditionalBonus, modifyToggle, modifyConsumer) that any homebrewer can now use.

Twelve new rule types, fifteen migrations and a complete user documentation site. Several changes alter how existing worlds behave, including how Apply Damage works and which rules honour their predicates. Read the Behaviour changes section before updating a live game.

Additions / Changes

Action economy

  • [#876] Activations can cost zero actions. The schema, the cost resolver and the combatant deduction all floored at 1, so every feature worded "for free" debited an action. @Fronix
  • [#876] A cost type of none resolves to 0 actions instead of 1. @Fronix
  • [#876] Activation cost labels are rendered by one shared formatter across all six surfaces that show them, so a zero-cost activation reads "Free" everywhere including the PDF export. @Fronix
  • [#876] Reactions read as "Reaction", "Reaction (2 Actions)" or "Free Reaction". Four sheets previously rendered the literal string "undefined" for any item authored against the legacy reaction cost shape. @Fronix
  • [#876] The spells tab shows a reaction's trigger tooltip for both the current and the legacy authoring shape. @Fronix
  • [#877] New actionCost rule changes what an activation costs: delta or set mode with a formula value, scopable by item type and identifier. @Fronix
  • [#878] actionCost scopes to heroic reactions too, so a free Defend is usable at 0 actions while a Defend already spent this round stays blocked. Cost and use limit are separate axes. @Fronix
  • [#878] Activating an item that costs more actions than you have left asks for confirmation with a force override, instead of silently going negative. @Fronix
  • [#879] New actionDelta rule grants or docks actions on item use: formula value, timing now or nextTurn, target self, targeted or allAllies, plus a borrow mode that adds now and debits your next turn in one atomic write. @Fronix
  • [#879] Character combatants carry a pending action adjustment that folds in at every refill site, and the action tracker renders overflow pips and a pending next-turn badge. @Fronix
  • [#880] New grantActivation rule offers an immediate weapon attack to targeted allies from the granting feature's chat card. Only the target actor's owners and GMs see the button, so a GM can act for an offline player. @Fronix
  • [#896] Pending action grants also fold at the start of the recipient's turn, so a grant written after their turn ended arrives on their next turn instead of a full turn late. @Fronix
  • [#896] The combat tracker shows pending action adjustments, so a player with their sheet closed is no longer told nothing. @Fronix
  • [#896] Activation cards report the action adjustments they made, one line per recipient. The lines record what was requested, since clamping happens when the combatant is written. @Fronix

Damage

  • [#851] New damageReduction rule: flat or formula-based, with optional damage-type and predicate filtering. Matching reductions stack and apply after armor but before temporary hit points. @Fronix
  • [#851] Manual dice consumers can bank one-shot damage reduction as a visible Active Effect. "That all you got?!" spends Fury Dice into a pending reduction that the next damage application consumes. @Fronix
  • [#855] Damage reduction gained a half mode: instead of subtracting a value it halves the damage, which is resistance per the Core Rules glossary. Halving rounds up, matching the heavy-armor convention. @Fronix
  • [#855] Monster damageResistances and damageImmunities were inert schema fields. They are now honoured by the damage pipeline and editable from the NPC meta config dialog. @Fronix
  • [#855] Banked one-shot reductions expire at combat end, and are no longer consumed when immunity or armor already zeroed the hit. @Fronix
  • [#871] [#785] Vulnerability is wired into the pipeline: vulnerable damage ignores the target's armor, and an unarmored target takes double instead. Immunity still outranks vulnerability. @Fronix
  • [#871] [#785] Characters gained resistance, vulnerability and immunity arrays of their own, sharing one damage-defenses editor with monsters. Previously a hero's resistance could only be faked through a half-mode reduction rule. @Fronix
  • [#871] [#785] Damage defenses have their own section on the character sheet's Core tab, so a player can read them without the meta dialog's edit-mode pencil. @Fronix
  • [#871] [#785] Chat card target rows carry short IMM, VUL, RES and DR badges explaining why a number is lower than the roll, each with the full rule text on hover. @Fronix
  • [#890] A card's damage applies in one pass. Armor, immunity and resistance stay per packet, because each is a property of a damage type, while flat and banked reductions become per attack, which is how the rulebooks word every one of them. A reduction larger than the first packet now carries into the next. @Fronix
  • [#890] Flat reductions are named only on the packet that actually spent them, so a target immune to the card's only damage type no longer shows reductions that subtracted nothing. @Fronix
  • [#890] A type-scoped reduction only spends against packets of a type it is scoped to. A fire ward could previously soak slashing damage. @Fronix

Dice pools and card-side spends

  • [#887] A diceConsumer can set cardOffer to hit or criticalHit and be spent from the attack card it modifies instead of the sheet's pool panel. The result folds into that card's primary damage roll, which is what keeps armor and reductions from resolving twice against one attack. @Fronix
  • [#887] The card's Reactions section is now called Options, because it carries attacker-side spends that cost nothing alongside reactions that cost an action. @Fronix
  • [#888] Card offers honour bonusOnAttackDelivery, so a consumer that only fires on melee attacks stops appearing on ranged ones. An activation with no attack type counts as neither, and any restriction hides the consumer there. @Fronix
  • [#889] The dice-consumer card offer gained a damageType field. An empty value keeps the existing fold into the attack's roll; a set type lands as its own damage packet beside it. @Fronix
  • [#861] [#683] modifyPool gained addRefills, so a granting feature can contribute refill entries to a pool declared on another item. @Fronix
  • [#861] [#683] Refill entries accept a predicate, evaluated against the actor's live domain when the trigger fires. @Fronix
  • [#861] [#683] New turn-start and turn-end dice pool refill triggers, plus an onCritReceived trigger fired from the damage pipeline. @Fronix
  • [#861] [#683] modifyPool gained minFace, a floor for rolled pool dice. The highest floor among contributing modifiers wins, and chat notes when a roll was raised. @Fronix
  • [#861] [#683] New modifyConsumer rule appends formulas to another item's dice-spend consumer, in rule priority order. @Fronix
  • [#861] [#683] New poolGainMessage rule posts a chat reminder when a targeted pool gains dice. @Fronix
  • [#861] [#683] New maximizeDie pool action raises the lowest N faces of a pool to the die maximum, wired through activation, the effect tree and the chat card. @Fronix
  • [#861] [#683] diceConsumer gained selectionOutcome, so a feature whose text lets you choose which die to change opens the spend panel and you pick, rather than the system applying a silent automatic change. @Fronix
  • [#904] [#613, #619] modifyPool can contribute charge pool recoveries, not just dice refills, so a feature can give an existing charge pool a new way to come back. @Fronix
  • [#896] Charge pools emit domain tags for count, empty and full state, matching what dice pools already published, so a rule can ask whether a charge remains. @Fronix
  • [#896] A charge pool can declare itself hidden. It is still tracked, recovered and spent, but it stays out of the badge row, so a feature with two rate-limit gates beside one real budget no longer looks like three budgets that add up. @Fronix
  • [#896] Charge badges resolve their own pools when a caller does not supply them, so adding charges to a surface is one line. @Fronix
  • [#896] Charges show on the actions tab, on all four panels that list your own items, and clicking a badge opens the adjust dialog in place. @Fronix

Toggles, marks and conditional bonuses

  • [#805] [#577] New toggleEffect foundation rule: an Active Effect backed switch that pushes domain tags into the actor while it is on, so one toggle on Rage lights up every "while raging" feature that predicates on the tag. @tristin-albers
  • [#805] [#577] Three new dispatcher events: onItemActivated for every activation with or without damage, onEncounterEnd, and a dying trigger. @tristin-albers
  • [#805] [#577] An on/off switch on attack-feature rows in the Actions panel, with an optional confirmation before ending and pool clearing on end, so Rage is a state you switch rather than a card you re-post. @tristin-albers
  • [#805] [#577] New modifyToggle rule lets one item modify a sibling toggle, first capability being suppression of named turn-off triggers. @Fronix
  • [#805] [#577] endAfterInactiveRounds ends a toggle at turn end after a round with no attack or owning-item activation. @Fronix
  • [#805] [#577] Toggle-backed effects appear in Temporary Effects on the sheet and as icons in the canvas conditions panel, where a right click ends them through the rule's own lifecycle rather than a raw delete. @Fronix
  • [#830] [#483] New markTarget rule tracks a per-attacker mark with an optional visible condition, with capacity derived across sibling rules so Nemesis raises it to unlimited. Two hunters marking the same creature get independent markers. @trevlar
  • [#830] [#483] New conditionalBonus rule offers a per-attack choice of advantage or bonus damage gated by a target condition, surfaced in the activation dialog for the player to pick. @trevlar
  • [#830] [#483] New marked condition as the visible quarry marker. @trevlar
  • [#861] [#683] modifyToggle gained turnOn, so a granting feature can switch a toggle on from a turn start, a dying state or a received crit. @Fronix
  • [#861] [#683] New onAttackReceived rule hook dispatched to the target actor's rules from the damage pipeline. @Fronix

Rules engine

  • [#859] [#583] New modifyIncomingAttack rule: rules on an actor that modify attacks aimed at them. Disadvantage and auto-miss apply automatically pre-roll; force-reroll and redirect-to-self are interactive offers on the attack card. Scope limits: first target only, AoE and minion group attack cards exempt, and token movement on a redirect stays manual. @Fronix
  • [#859] [#583] Force-reroll options cover mandatory rerolls with no button, a trigger of always, hit or criticalHit, and rerolling at disadvantage. @Fronix
  • [#859] [#583] Baseline heroic Interpose: every living allied character within 2 spaces is offered the redirect without needing a rule, paying through the combat tracker. Rule-granted redirects leave the cost to the granting feature. @Fronix
  • [#859] [#583] New alliesAdjacent domain tags mirroring enemiesAdjacent, with a spaces-based geometry helper. @Fronix
  • [#857] New skillRollMode rule sets or adjusts advantage on one or more skill checks, gated by a predicate. @Fronix
  • [#856] suppressActivationCard is now an editable tri-state on every rule (auto, always, never) in the rule card's advanced section. Cards carrying rolls or effect nodes are still never suppressed. @Fronix
  • [#895] [#613] New subclass: domain tag, so a rule living on an item shared with the whole class can finally be gated on which subclass the character took. @Fronix
  • [#902] The Rules Builder says why a rule is not running. A rule dropped for a bad field previously rendered a normal-looking card, indistinguishable from one that works, with only a console warning. @Fronix
  • [#858] The Rules Builder warns when an early-phase rule predicates on a tag that is only populated later, instead of showing a false "matches" preview. @Fronix
  • [#886] New automation settings group: eight per-family toggles (rule effects, derived conditions, resource recovery, resource spending, action tracking, health-state sync, combat convenience, chat notifications) in a GM-only Configure Automation dialog. Saving applies immediately with no reload. @Fronix
  • [#886] Core plumbing is exempt from the rule-effects toggle, so dice consumer spend prompts and toggle activation still work with rule automation off. @Fronix

Character creation and level up

  • [#800] [#708] New levelUpOptions for choosing between alternative level-up rewards, covering selection groups, fixed grants and charge pool maximum bonuses. @trevlar
  • [#800] [#708] Full level 1 to 20 progression tests for every class, driven by the real compendium data. @trevlar
  • [#854] The same class feature available from two copies, a world item and a compendium version, now resolves as a comparison list you choose from instead of silently granting every copy. @trevlar
  • [#854] Each row says where the copy lives, where it came from, and what actually differs: "identical to Nimble Core" or "differs: duration, healing", with the differing words highlighted inline so you need not open a copy to learn it is byte-identical. @trevlar
  • [#854] An owned copy stays in the cluster so a new copy can be compared against the one already on your sheet, and is never re-granted. @trevlar
  • [#833] Ancestry bonus traits are separate, swappable ancestryBonus items. The ancestry references a default that a player can exchange for any other during creation, with both added to the character and the bonus nested under the ancestry in the Features tab. @trevlar
  • [#833] New nimble-ancestry-bonuses compendium holding every core trait, named for the trait rather than the ancestry (dwarf becomes stout, birdfolk becomes hollow-bones). @trevlar
  • [#833] Languages stay on the ancestry rather than the swappable bonus, read from the GM-owned language configuration so a world defining a different set previews correctly. @trevlar
  • [#899] The ancestry sheet's Config tab gained a size options control, so a custom ancestry no longer needs JSON or the console to set which sizes it offers. Sizes list smallest to largest, selections show as removable badges, and an "All sizes" row selects every size at once. @trevlar
  • [#899] The player-facing size step is a radio list that picks exactly one size with nothing pre-selected, replacing a tag row that looked multi-select. Each size carries a short description and a note on how size affects grappling. @trevlar
  • [#899] A fixed size is stated rather than asked, so the step tells you your size instead of rendering nothing. @trevlar

Spells

  • [#864] [#845] New increaseDieSize upcast scaling operation steps an existing die up the chain instead of appending a new term, with a configurable cap. Spells whose upcast rule reads d6 to d8 to d10 could not be authored at all before. @Fronix
  • [#864] [#845] The Settings UI exposes Steps and Max Die controls, and the upcast dialog previews the upgraded die. @Fronix

Sheet and UI

  • [#875] Wounds moved to a segmented track directly under the hit point bar. The pips were hidden over the portrait until hover, so a healthy character gave no sign the mechanic existed. Hovering segment N previews the resulting total in both directions. @Fronix
  • [#901] New per-item "Skip roll dialog" toggle on the activation config tab. Holding Alt inverts the item's default rather than the flag being absolute, so a flagged upcastable spell stays reachable. @Fronix

Documentation

  • [#848] A full user documentation section written for GMs and players in plain language: getting started, playing the game, running the game, homebrewing, and the Rules Builder. @Fronix
  • [#848] Reference pages for every rule type, setting and condition are generated from the source schemas and regenerated on every docs build, so new rule types appear automatically. @Fronix
  • [#861] [#683] Worked examples for the dice pool rule types and a player-facing section on the pool tracker and its spend panel. @Fronix

Fixes

Rules engine

  • [#902] Data-prep rules stopped stacking twice per prepare cycle. Two call sites re-prepared every character with a bare prepareData(), which reuses the already-derived data, so every read-modify-write rule applied its bonus twice. A +2 Skill Bonus read +2 while the world ran and +4 after a reload, and the same held for ability, save, wound, speed, hit dice and healing potion bonuses. @Fronix
  • [#902] A Skill Bonus of @strength resolved to 0. Ability, save and skill modifiers are derived and were computed after the rule sweep, so every stat reference in a rule saw the source value. The double prepare hid it: the bonus appeared to work after a reload and never while playing. @Fronix
  • [#902] Open sheets refresh when an Active Effect changes. Applying or clearing a condition re-runs data preparation without touching the actor or any item, so a condition-gated bonus updated in the data while the sheet kept rendering the old value until reopened. @Fronix
  • [#902] Ability and skill modifiers are no longer clamped to 12. The ability cap had no basis in the rules at all, and a silent clamp is the wrong way to hold the skill cap. @Fronix
  • [#858] initiativeRollMode and skillBonus mutated actor data without testing their predicate, so an authored predicate was silently ignored. @Fronix
  • [#858] The same predicate gap is closed on abilityBonus, healingPotionBonus, maxHitDice, maxWounds and savingThrowBonus. Live-verified on maxWounds, where an impossible predicate still raised the maximum from 6 to 8. @Fronix
  • [#858] self:fullHp is now an early domain tag, so predicates on it match for data-prep rules. It was populated after the early hook, so Leave No Trace's condition silently never matched. @Fronix
  • [#858] Fixed a stale read where the bloodied threshold used the previous cycle's maximum hit points. @Fronix
  • [#805] [#577] findDiceConsumerRule matched on type and pool identifier only, ignoring the rule's predicate, so a consumer gated on self:raging auto-added Fury Dice on every melee attack whether or not the toggle was on. @tristin-albers
  • [#805] [#577] Activating the source item only ever turns a toggle on. It previously toggled off when already on, making a re-use mid-effect a silent off switch for a feature like Rage that you re-use every turn. @tristin-albers
  • [#805] [#577] Toggle turn-off is gated to the active GM. The hooks fire on every connected client, so an automatic end produced a duplicate "ended" message and a redundant delete per client. @Fronix
  • [#805] [#577] Renamed the dying trigger away from "unconscious". Nimble has no unconscious-at-0-HP state; that name imported the D&D 5e model. @Fronix
  • [#859] [#583] Rejected spoofed-GM reaction requests. The socket's user id is client-supplied, and validation skipped the ownership check whenever the claimed user resolved to a GM, so a player could borrow the primary GM's id to trigger any pending redirect or reroll. @Fronix
  • [#859] [#583] Fixed predicate min and max operations being vacuously true when no matching tag exists. @Fronix
  • [#855] Rule accumulator arrays duplicated their entries whenever Foundry called prepareData() directly, since the same data object is reused across such calls. Rules now register their accumulator paths and the actor resets them each cycle. @Fronix
  • [#904] [#613, #619] A contributed recovery's own predicate was discarded on the charge path, so a charge pool modifier gated on a condition recovered unconditionally while the identical rule on a dice pool did not. @Fronix
  • [#904] [#613, #619] A contributed entry naming a mode charge pools do not have was coerced to add rather than dropped, so clear on a charge pool added a charge instead of emptying it. @Fronix
  • [#861] [#683] Refill entry predicates read from initialized rule data were wrapped objects, and treating that shape as the raw predicate made every predicated refill fail. Found by live v13 verification. @Fronix
  • [#861] [#683] modifyConsumer matched consumers on pool identifier alone while enumeration also matches on scope, so an actor-scoped and an item-scoped pool sharing an identifier could cross-contaminate. @Fronix

Combat

  • [#896] An actionDelta rule targeting all allies included the granter. A feature worded "every ally gains 1 action" also handed one to the character using it, every time. Found by live testing a level 20 Commander quietly gaining an extra action on every use of their capstone order. @Fronix
  • [#853] Players can roll initiative from their character sheet again. Rolling still carried Foundry core's initiative-based turn reconciliation, and the flag write that adds makes it a disallowed update for a non-GM, so a player hit a permission error. In Nimble initiative sets your starting actions and never reorders the turn list, so the reconciliation is gone entirely. @trevlar
  • [#861] [#683] Backstopped the turn-start hook when Foundry skips the turn interval. Under the expanded solo-monster turn order its cached history can desync, silently dropping every turn-start pool refill and charge recovery for that turn. @Fronix

Chat cards

  • [#900] A card's condition button applied to whatever tokens you had selected on the canvas. With several selected it conditioned all of them, and with the wrong one selected it conditioned the wrong creature. It now applies to the card's own targets. @Fronix
  • [#900] Conditions record where they came from, so the readout names the responsible feature instead of "Source: None". @Fronix
  • [#900] Condition application was written twice in two places that had drifted apart: one skipped the immunity hook entirely, so a click could stick a condition on a creature immune to it. @Fronix
  • [#900] Each target's condition applies independently. A sequential await meant the first target that failed skipped every remaining one. @Fronix
  • [#900] The condition tooltip no longer promises a click action that does not exist. @Fronix
  • [#894] Cosmetic hit point feedback no longer aborts the update dispatch. The scrolling text and ring flash run inside the update handler, and a third-party wrapper that throws killed the update hook: hit points persisted but the sheet froze until reopened, the token bar kept its old value, no death overlay appeared, and the remaining targets of a multi-target damage application were dropped. @Fronix
  • [#890] Save-gated damage keeps a per-packet Apply Damage control. Moving the control to the card's damage group left saving-throw cards with none at all, affecting every shipped save card including Pyroclasm, Gangrenous Burst and Unspeakable Word. @Fronix
  • [#889] Typed conditional-bonus damage was invisible on every hit card it was rolled for, because a root damage node with no outcome children is only collected under conditions the hit path did not meet. @Fronix
  • [#888] A card offer stranded by a later forced reroll is dropped. The reroll rewrites the card's crit and miss state afterwards, so a crit-only spend survived on a card that no longer crits and folded its bonus into a non-crit attack. @Fronix
  • [#887] A card-side spend can no longer be confirmed twice. For a player the request returns as soon as the socket is emitted, well before the GM writes it as used, so a second confirmation inside that window read the same unspent pool: the dice came out once and the damage went on twice. @Fronix
  • [#887] A folded card-side spend survives a reroll. The reroll rebuilds the damage roll from the original formula, which never carried the folded bonus, so a spend confirmed before the reroll vanished from the total while the dice stayed spent. @Fronix
  • [#887] Reaction writes are serialized per card. Two resolvers overlapping on one card each wrote their own stale copy of the entry array, and whichever landed second dropped the other's used flag. @Fronix
  • [#887] A spending player is told why the GM refused their spend. Every refusal warned on the GM's screen while the player watched their button sit disabled and come back unexplained. @Fronix
  • [#847] Banked dice-pool bonuses apply through monster armor. Fury Dice and Judgment Dice ship as flavored numeric terms, so the armor calculation treated them as ignorable modifiers and dropped them against armored targets. Per the rules they are dice: they survive medium armor and are halved by heavy. @Fronix
  • [#847] Each target row shows a damage preview computed through the same armor-aware path as Apply Damage, so the number always matches what will be applied. @Fronix
  • [#847] A missed attack shows no damage preview instead of a zero on every target. @Fronix
  • [#896] A granted action's card names only the recipient as the one taking it. With the recipient and a real target both selected, the notice claimed the goblin was taking the action too. @Fronix
  • [#896] A granted offer aimed at a friendly target is no longer dimmed. The 0.45 opacity drop read as disabled on a button that stayed fully usable, and who to aim at is the table's call. @Fronix
  • [#896] An activation card's action economy is written in one update. Two handlers on the same hook each fired their own un-awaited update against the same message in the same tick, and pack data that both adjusts actions and grants activations is already shipping. @Fronix

Charges and pools

  • [#850] Charges are no longer auto-consumed when an item has no chargeConsumer rule. An implicit cost-1 consumer was synthesized from the item's pool state, so any item with only a chargePool rule silently spent one charge from every pool on each activation, forcing a cost-0 consumer as a workaround. @Fronix
  • [#896] A charge consumer honours its own predicate. Consumers were collected on type and disabled state alone, so a predicate was parsed and then ignored, and a consumer with no charges left aborted the whole activation. @Fronix
  • [#896] A charge pool honours its own predicate, so a pool belonging to a feature gained partway up a progression no longer shows a permanently full badge from level one. @Fronix
  • [#896] Hidden charge pools stay adjustable from the dialog, so a GM can correct a spent gate by hand. @Fronix
  • [#861] [#683] Pool effect nodes are applied after the use gate, not during activation data assembly. A use blocked by a charge gate still mutated the pool. @Fronix
  • [#861] [#683] maximizeDie reports what actually happened instead of a generic "no change", and its results land on the nodes the card serializes rather than on discarded clones. @Fronix
  • [#861] [#683] A pool node whose parent is neither a damage nor a saving-throw node is no longer dropped before it can be applied. @Fronix

Sheet and UI

  • [#905] The features tab stopped warning about level data it cannot expect. It sorted every card through a helper that warned whenever an item had neither level field, but most cards it sorts cannot have either, so a character with a class and a subclass produced two warnings per re-render. @Fronix
  • [#896] The combat tracker's pending action marker sits inside the action box. It rendered as a sibling and added its own width to a row tuned to exactly fill the portrait card, so the card clipped it: a player saw a green sliver and could not read the number. The same overflow was clipping the minus button. @Fronix
  • [#875] The wound track meets 3:1 contrast in both themes. Filled against empty measured 1.24:1 in dark mode, so the only signal was hue. @Fronix
  • [#805] [#577] Wound pips beyond six were clipped by an overlay sized for exactly six, hiding the extra pips granted by max-wound features. @Fronix
  • [#887] The attack panel's feature list is no longer capped by a max height when the sheet is expanded. @Fronix
  • [#871] [#785] The chat card's armor icon is pinned to its grid column. Injected without one, it auto-flowed into the first free cell and drifted left once the badges column was added. @Fronix
  • [#871] [#785] Damage badges use theme tokens instead of literal hex fills, which had rendered near-black text on muted backgrounds. Every pair now clears WCAG AA. @Fronix
  • [#871] [#785] Target rows are keyed by token uuid. The unkeyed list reused DOM as targets were added one at a time, printing a row's name more than once. @Fronix

Rules Builder

  • [#862] [#806] The modifyPool pool picker resolves from poolType. It hardcoded the dice picker, so with a charge pool selected the actor's charge pools never appeared and a stored identifier rendered as "not found". @Fronix
  • [#862] [#806] Pool identifiers can be typed on an unowned item. Both pickers resolve options from the parent actor, so on a compendium or world item the control was a permanently disabled empty dropdown and pack authors could not set an identifier at all. @Fronix
  • [#862] [#806] The empty-state message distinguishes "this item is not on an actor" from "this actor has no pools of that kind". @Fronix
  • [#888] bonusOnAttackDelivery renders with a real label and hint instead of its raw key, and the hint states the trap: an activation with no attack type counts as neither melee nor ranged. @Fronix
  • [#896] All twelve charge recovery triggers are labelled. The tooltip covered six and printed the raw key for the rest, so a pool recovering on an initiative roll showed "onInitiativeRolled" to the player. @Fronix
  • [#856] An explicit "always" suppression works regardless of the automation setting. The item-level gate applied to every rule, so a rule set to Always still posted its card with rule automation off. @Fronix
  • [#866] Reworded the banked reduction note. @Fronix

Packaging and CI

  • [#870] Babele resolves from the official package listing. The hardcoded manifest URL is dead, so Foundry's dependency check failed on install and claimed the optional dependency had to be installed by hand. @Fronix
  • [#865] The FoundryVTT registry publish is skipped for pre-releases. They still build and attach their artifacts to the GitHub release. @Fronix
  • [#867] Attaching build artifacts no longer clears a release's pre-release flag, which had been letting GitHub promote pre-releases to latest, and no longer clobbers post-publish edits to the name and body. @Fronix
  • [#872] The rolling dev release tag moved off latest-dev, which had been set immutable. @Fronix
  • [#860] Tags are escaped during the docs build. @Fronix
  • [#859] [#583] The docs site installs as a self-contained project instead of resolving up to the repo workspace root and leaving its dependencies empty. @Fronix

System Data

  • [#805] [#577] Rage ships as a toggle: it pushes self:raging while on, ends on death, encounter end or rest, clears the Fury pool when it ends, and prompts before ending if dice would be lost. @tristin-albers
  • [#805] [#577] Deep Rage suppresses Rage's turn-off triggers through the new modifyToggle rule. @Fronix
  • [#861] [#683] Berserker tier-1 automation: Bloodlust and Death Blow as manual Fury consumers, Onslaught's speed while Raging, Savage Awareness' Perception advantage, and One with the Ancients' per-Safe-Rest gate. @Fronix
  • [#861] [#683] Whirlwind, You're Next!, Unstoppable Brutality and Thunderous Steps carry reminder notes on the activation card for their manual portions. @Fronix
  • [#861] [#683] Intensifying Fury rolls a free Fury Die at turn start while Raging, and MORE BLOOD! gains one when crit. @Fronix
  • [#861] [#683] Stone's Resilience adds the spent die values to Fury Dice damage-reduction spends, and Boundless Rage sets a Fury Dice floor of 6 at level 20. @Fronix
  • [#861] [#683] Enduring Rage auto-Rages at turn start while Dying, and Titan's Fury restores Rage when crit. @Fronix
  • [#861] [#683] Blood Frenzy and Deathless Rage gained 1/turn gates, Unbreakable a 1/encounter gate, and Swift Fury a reminder that you may move for free when gaining Fury Dice. @Fronix
  • [#887] Death Blow offers its Fury spend on the crit that triggers it. It could previously only be spent through the sheet panel, which posted a standalone roll with no target and no Apply Damage button. @Fronix
  • [#895] [#613] Coordinated Strike is a zero-cost activation, matching its "Free action" wording, and gained INT-per-Safe-Rest and once-per-round use pools. @Fronix
  • [#895] [#613] Coordinated Strike grants the ally's weapon attack through grantActivation, with two actionDelta rules paying for both attacks. The "or cast a cantrip" branch stays a manual choice. @Fronix
  • [#895] [#615] Master Commander raises the Coordinated Strike maximum at levels 9, 13 and 17 through level-predicated pool modifiers. @Fronix
  • [#895] [#619] Experienced Commander adds a Coordinated Strike use and Survey the Battlefield adds a Combat Die maximum. @Fronix
  • [#895] [#615, #619] As One!, Unparalleled Tactics and Captain of Legions grant allies an action off the back of Coordinated Strike, gated by subclass and level band. The all-allies target reaches every allied combatant rather than a range, which needs a token adjacency primitive we do not have yet. @Fronix
  • [#895] [#617] Hold the Line! and I Can Do This ALL DAY! gained the 1/encounter gates their text calls for. Their effects stay manual: one sets an ally's hit points and the other spends Hit Dice, neither of which any rule type can do. @Fronix
  • [#895] [#618] Taunting Strike tracks its 1/turn use and offers the Taunt as a click-to-apply condition on the card, rather than auto-applying to every creature the Commander hits. @Fronix
  • [#895] [#616, #617] Five Combat Tactics, Field Medic, Hold the Line! and I Can Do This ALL DAY! carried a placeholder acid damage node of 0 that existed only to hang a reminder off. Since damage applies in one pass those emitted a real zero-damage packet on every card, so each note is now a proper note node. @Fronix
  • [#895] [#617] Move it! Move it! no longer deals thunder damage. It carried a thunder node used as a device to roll and display an initiative value, which landed as a real damage packet on whoever was targeted, and the roll was a meaningless second d20 anyway. @Fronix
  • [#895] [#617] Removed a malformed maxHitDice rule left over from the Rules Builder on I Can Do This ALL DAY!. It was wrong in both directions: the rule adds to the Hit Dice maximum while the feature spends Hit Dice. @Fronix
  • [#895] Master Commander's description no longer lists level 5 among the levels granting an extra use, which implied a fourth use the rules do not grant. @Fronix
  • [#904] [#613, #619] Master Commander and Survey the Battlefield regain a spent Coordinated Strike use at encounter start. Not modelled: Master Commander's "lost if not spent during that encounter", so a recovered use persists until the next Safe Rest. @Fronix
  • [#896] [#613] The Coordinated Strike capstones are gated to once per encounter. Live testing confirmed they fired on every use. @Fronix
  • [#896] [#613] Coordinated Strike shows one charge badge instead of three. The two rate-limit gates are hidden and relabelled; they still refuse the activation when spent and still report on the card. @Fronix
  • [#830] [#483] Hunter's Mark and Nemesis are wired to the new marking rules. @trevlar
  • [#864] [#845] Lifebinding Spirit is upcastable, capped at d12. The "+1 healing use" half of its upcast rule is a companion concern left for a follow-up. @Fronix
  • [#857] Leave No Trace ships as the first skillRollMode consumer, granting Stealth advantage at full hit points. @Fronix
  • [#859] [#583] Aura of Refuge, Pocket Sand and Mountain's Endurance are implemented with modifyIncomingAttack. @Fronix
  • [#901] Lay on Hands activates without the roll dialog. @Fronix
  • [#833] Every core ancestry's trait is extracted into the new ancestry bonuses compendium, with stable rule ids pinned so references survive reimport. @trevlar
  • [#801] Selection-group parent progression icons updated so each group reads at a glance and does not collide with its child abilities. @trevlar
  • [#800] [#708] Class and subclass progressions updated, including Commander, Storm Shifter and Songweaver fixes, audited against the Nimble Vault. @trevlar
  • [#824] French system translation updated. @Eilirmwd

Behaviour changes

  • Apply Damage is one control per card, not one per damage node. A card with two damage packets previously charged the target's per-attack defenses twice. The tradeoff is deliberate: a GM can no longer apply one packet and not another. Save-gated damage keeps its per-packet controls. [#890]
  • The chat card's condition button is GM-only and applies to the card's targets. It previously applied to your canvas selection, and it bypassed condition immunity entirely. Both were bugs, but a world that leaned on the old behaviour will notice. [#900]
  • Predicates on data-prep rules are now honoured. abilityBonus, skillBonus, initiativeRollMode, healingPotionBonus, maxHitDice, maxWounds and savingThrowBonus silently ignored them before. No shipped content carries predicates on these types, but homebrew that added one and relied on it being ignored will change. [#858]
  • Data-prep rule bonuses no longer double after a reload. If you tuned homebrew numbers against the doubled value, they will now read half of what you saw. [#902]
  • Ability and skill modifier caps are gone. Both were clamped to 12. The system reports state; the table decides. [#902]
  • An item with charge pools and no chargeConsumer rule no longer spends charges. If you added a cost-0 consumer as a workaround, it is now redundant rather than harmful. [#850]
  • A cost type of none resolves to 0 actions, not 1. Minion attack paths still treat a missing or none cost as 1; only an explicit zero is free. [#876]
  • turn is gone from the activation cost dropdown. "1/turn" is a usage limit rather than a cost. Nothing in the packs authored it and it rendered no label. [#876]
  • Activating a toggle's source item only turns it on. It used to toggle off when already on, which made re-using Rage to roll Fury Dice a silent off switch. Turn it off from the effects panel, the actions-panel switch, or a turn-off trigger. [#805]
  • An actionDelta targeting all allies excludes the granter. A feature meant to cover both needs a paired self rule. [#896]
  • Charge pool and consumer predicates now apply. A pool whose predicate goes false loses its definition and its stored charges and returns at its initial value, so predicate the consumer rather than the pool for anything reversible. [#896]
  • Migrations rewrite embedded Commander, Berserker, Hunter, Rage and ancestry content. Every write is guarded on the exact value the pack shipped before, so a hand-edited copy keeps your edit and is skipped. [#895, #861, #830, #833]

Migrations

Migration What it repairs
027 Rage and Deep Rage embedded copies: the toggle rule, the raging-gated Fury auto-bonus, chat suppression on pool nodes
028 Removes orphaned max-combat-die grants and updates Fit for Any Battlefield to the pool-bonus mechanism
029 "That all you got?!" reconciled with the damage reduction flow
030 Hunter's Mark and Nemesis: the mark, conditional bonus and note rules, and the raised quarry cap
031 modifyIncomingAttack rules for Aura of Refuge, Pocket Sand and Mountain's Endurance
032 Lifebinding Spirit's die-size upcast scaling, capped at d12
033 Berserker automation across 19 features
034 Death Blow's card-offer field, and its description where still untouched
035 Splits each actor's ancestry trait into a separate ancestry bonus item, keeping languages on the ancestry
036 Commander Coordinated Strike automation on four class features
037 Commander pack repair across ten features: placeholder damage nodes, the thunder node, new pools, the malformed rule
038 Coordinated Strike ally-action riders for As One!, Unparalleled Tactics and Captain of Legions
039 The once-per-encounter gate on the Coordinated Strike capstones
040 Hides and relabels the Coordinated Strike rate-limit pools
041 The encounter-start Coordinated Strike regain on Master Commander and Survey the Battlefield

Schema version 26 to 41. Rule types 32 to 44.

Contributors

@Fronix, @trevlar, @tristin-albers, @Eilirmwd

If you would like to support continued development, you can do so on Patreon or Ko-fi.