DND Engine Registry

skill_node

Registers under Skill Nodes · source: modules/skill_node/v1

A node wanting two effects is two sibling nodes under one parent, not one node with a multi-effect payload (see combat-engine-readme.md → Skill Tree Schema) — this module enforces exactly one effect kind per node by construction (a single `effect_kind`/`effect_payload` pair, not a list). A branch="class" node can be authored directly here, referencing an EXISTING class's `class_id` by string — it doesn't have to go through character_class/v1's own `skill_tree=[...]` bundling param (that param stays Python-only, see that module's own COMMUNITY_SCHEMA comment); this is how a community author adds a node to someone else's class without touching its Python file at all. `skill_tree_tier` is the node's depth/prerequisite rank in the tree — used alongside `parent_id` to reconstruct and render the full tree, no separate layout/position data needed (see combat-engine-readme.md → Class → Skill Tree Schema). `skill_tree_cost` is the SkillPoints required to unlock this node — cost should scale with the node's power (a minor node costs little, a strong unlock costs significantly more). `ability_id` and `new_cost` are the actionCostRetag payload's flat fields (see gamemaster/engine/skill_tree.py's own `action_cost_retags`). `ability_id` is an EXISTING Class Action's own id. `new_cost` is the action-cost category (`action` or `bonusAction`) that ability gets retagged to once this node is unlocked. `class_action_id` is classActionUnlock's own flat field (2026-10-17, DND-29) — an EXISTING Class Action's own id, same "references an existing id" shape as `ability_id` above, just a different effect kind entirely: this one makes that ability USABLE at all once the node is unlocked (see gamemaster/engine/skill_tree.py's class_action_unlocks), `ability_id`/`new_cost` only ever retag an ALREADY-usable ability's action-cost category. Deliberately a separate field from `ability_id` rather than reusing it, so a node can never accidentally mean both at once.

Example Usage

resource "general_quickdraw" {
  source: modules/skill_node/v1
  id: "general_quickdraw"
  branch: "general"
  parent_id: "general_root_blessing"
  skill_tree_tier: 1
  skill_tree_cost: 2
  effect_kind: "bonusActionGrant"
  amount: 1
  description: "An extra Bonus Action per round."
}

Arguments Reference

The following arguments are supported:

  • id - (Required) The unique id this record is registered and referenced under — what a `.resource` file's own filename-independent identity is, and what any other content's foreign-key-style field (a dungeon node's `next`, a skill node's `parent_id`, and so on) points at. community
  • branch - (Required) Valid options are class, general and guild. community
  • skill_tree_tier - (Required) `skill_tree_tier` is the node's depth/prerequisite rank in the tree — used alongside `parent_id` to reconstruct and render the full tree, no separate layout/position data needed (see combat-engine-readme.md → Class → Skill Tree Schema). community
  • skill_tree_cost - (Required) `skill_tree_cost` is the SkillPoints required to unlock this node — cost should scale with the node's power (a minor node costs little, a strong unlock costs significantly more). community
  • effect_kind - (Required) Valid options are actionCostRetag, bonusActionGrant, classActionUnlock, essenceCapacityGrant, essenceRegenGrant, expBonus, hitdieUpgrade, statBonus, weaponTierUnlock and worldBossUnlock. community
  • effect_payload - (Optional) Defaults to None. developer
  • parent_id - (Optional) Defaults to None. community
  • class_id - (Optional) Currently registered: ranger, skylancer, warrior and wizard. Defaults to None. community
  • description - (Optional) Flavor text shown to players — pure display data with no effect on game mechanics. community
  • stat_id - (Optional) Currently registered: strength, agility, evasiveness, luck, vitality, wisdom and charisma. community
  • bonus_percent - (Optional) Defaults to 0.0. community
  • pools - (Optional) Defaults to None. community
  • amount - (Optional) Defaults to 0. community
  • ability_id - (Optional) `ability_id` and `new_cost` are the actionCostRetag payload's flat fields (see gamemaster/engine/skill_tree.py's own `action_cost_retags`). `ability_id` is an EXISTING Class Action's own id. Currently registered: arcane_barrier, battle_cry, dive_bomb and hobbling_shot. community
  • new_cost - (Optional) `new_cost` is the action-cost category (`action` or `bonusAction`) that ability gets retagged to once this node is unlocked. Valid options are action and bonusAction. community
  • tier - (Optional) Defaults to 0. community
  • essence_type_id - (Optional) Currently registered: ammo, mana and stamina. community
  • amount_per_round - (Optional) Defaults to 0.0. community
  • weapon_id - (Optional) Currently registered: apprentice_wand, beastslayer, dragon_wand, heavenly_spear, practice_bow and rusty_sword. community
  • dice_count_increase - (Optional) Defaults to 0. community
  • class_action_id - (Optional) `class_action_id` is classActionUnlock's own flat field (2026-10-17, DND-29) — an EXISTING Class Action's own id, same "references an existing id" shape as `ability_id` above, just a different effect kind entirely: this one makes that ability USABLE at all once the node is unlocked (see gamemaster/engine/skill_tree.py's class_action_unlocks), `ability_id`/`new_cost` only ever retag an ALREADY-usable ability's action-cost category. community