dune-tools/character-builder/data/skills-swordmaster.json
Vantz Stockwell f142725dd8 Skill tree: subtrees, loadout slots, label fix
Skill trees now render the way the source does: each class has three named
subtrees (e.g. Swordmaster: The Blade / The Will / The Way), each with its
own 3-col or 5-col grid, sized in 72px cells. Extractor parses subtrees
separately so the per-tree row/col coordinates are correct (previously all
22 nodes were stacked on one combined grid and overlapped). Connector
edges are mapped per-subtree too.

Loadout: new global 3-ability + 3-technique slot row at the bottom of the
Skill Trees panel. The cap is global across all 5 classes (matches the
source HTML which has `id=active-Ability-N` / `id=active-Technique-N`
without per-tree scope). Click a slot to pick from any allocated Ability
or Spice (for Ability slots) or any allocated Perk (for Technique slots);
right-click clears. Slot backgrounds use the local ability.png /
technique.png artwork copied into /icons.

Label overlap fix: constrained the name label under each node to the node
width (72px) and bumped the vertical gap from 44 to 60px so 2-3 line names
have room without bleeding into the row below.

Existing saved builds migrate cleanly — loadout normalizes to length-3
slot arrays if absent or malformed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 08:21:09 -04:00

384 lines
No EOL
11 KiB
JSON

{
"id": "swordmaster",
"name": "Swordmaster",
"subtrees": [
{
"name": "The Blade",
"cols": 3,
"nodes": [
{
"tag": "Skills.Spice.ParryBoost",
"id": "ParryBoost",
"name": "Precise Parry",
"kind": "Spice",
"row": 1,
"col": 2,
"maxPoints": 3,
"icon": "t_ui_iconskilltreepreciseparry_d.webp",
"url": "https://dune.gaming.tools/skills/skills-spice-parryboost"
},
{
"tag": "Skills.Ability.Whirlwind",
"id": "Whirlwind",
"name": "Eye of the Storm",
"kind": "Ability",
"row": 2,
"col": 1,
"maxPoints": 3,
"icon": "t_ui_iconabilitywhirlwind_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-whirlwind"
},
{
"tag": "Skills.Ability.RiposteBreak",
"id": "RiposteBreak",
"name": "Foil",
"kind": "Ability",
"row": 2,
"col": 3,
"maxPoints": 1,
"icon": "t_ui_iconabilitybreakingreposte_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-ripostebreak"
},
{
"tag": "Skills.Attribute.Blade2",
"id": "Blade2",
"name": "Long Blade Damage",
"kind": "Attribute",
"row": 3,
"col": 2,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeskillbrawler_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-blade2"
},
{
"tag": "Skills.Perk.MeleeChain",
"id": "MeleeChain",
"name": "Dance of Blades",
"kind": "Perk",
"row": 4,
"col": 1,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeperkbladechaining_d.webp",
"url": "https://dune.gaming.tools/skills/skills-perk-meleechain"
},
{
"tag": "Skills.Ability.RiposteInjure",
"id": "RiposteInjure",
"name": "Retaliate",
"kind": "Ability",
"row": 4,
"col": 3,
"maxPoints": 1,
"icon": "t_ui_iconabilityinjuringreposte_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-riposteinjure"
},
{
"tag": "Skills.Attribute.Blade1",
"id": "Blade1",
"name": "Blade Damage",
"kind": "Attribute",
"row": 5,
"col": 2,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeskillbrawler_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-blade1"
}
],
"edges": [
{
"from": "Skills.Ability.Whirlwind",
"to": "Skills.Spice.ParryBoost"
},
{
"from": "Skills.Ability.RiposteBreak",
"to": "Skills.Spice.ParryBoost"
},
{
"from": "Skills.Ability.Whirlwind",
"to": "Skills.Attribute.Blade2"
},
{
"from": "Skills.Ability.Whirlwind",
"to": "Skills.Perk.MeleeChain"
},
{
"from": "Skills.Ability.RiposteBreak",
"to": "Skills.Attribute.Blade2"
},
{
"from": "Skills.Ability.RiposteBreak",
"to": "Skills.Ability.RiposteInjure"
},
{
"from": "Skills.Attribute.Blade2",
"to": "Skills.Perk.MeleeChain"
},
{
"from": "Skills.Ability.RiposteInjure",
"to": "Skills.Attribute.Blade2"
},
{
"from": "Skills.Attribute.Blade1",
"to": "Skills.Perk.MeleeChain"
},
{
"from": "Skills.Ability.RiposteInjure",
"to": "Skills.Attribute.Blade1"
}
]
},
{
"name": "The Will",
"cols": 3,
"nodes": [
{
"tag": "Skills.Perk.ThriveOnDanger",
"id": "ThriveOnDanger",
"name": "Thrive on Danger",
"kind": "Perk",
"row": 1,
"col": 2,
"maxPoints": 1,
"icon": "t_ui_iconskilltreethriveondanger_d.webp",
"url": "https://dune.gaming.tools/skills/skills-perk-thriveondanger"
},
{
"tag": "Skills.Attribute.Resolve2",
"id": "Resolve2",
"name": "Solid Stance",
"kind": "Attribute",
"row": 2,
"col": 1,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeattributepoisedefense_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-resolve2"
},
{
"tag": "Skills.Attribute.UnstoppableAttacks",
"id": "UnstoppableAttacks",
"name": "Confidence",
"kind": "Attribute",
"row": 2,
"col": 3,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeattributedamagemitigation_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-unstoppableattacks"
},
{
"tag": "Skills.Attribute.Resolve1",
"id": "Resolve1",
"name": "Bleed Tolerance",
"kind": "Attribute",
"row": 4,
"col": 1,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeskillmaxhealth_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-resolve1"
},
{
"tag": "Skills.Perk.ToughLunge",
"id": "ToughLunge",
"name": "Reckless Lunge",
"kind": "Perk",
"row": 4,
"col": 3,
"maxPoints": 3,
"icon": "t_ui_iconskilltreetoughlunge_d.webp",
"url": "https://dune.gaming.tools/skills/skills-perk-toughlunge"
},
{
"tag": "Skills.Ability.DeflectionSlow",
"id": "DeflectionSlow",
"name": "Deflection",
"kind": "Ability",
"row": 5,
"col": 2,
"maxPoints": 1,
"icon": "t_ui_iconabilitydeflection_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-deflectionslow"
}
],
"edges": [
{
"from": "Skills.Attribute.Resolve2",
"to": "Skills.Perk.ThriveOnDanger"
},
{
"from": "Skills.Attribute.UnstoppableAttacks",
"to": "Skills.Perk.ThriveOnDanger"
},
{
"from": "Skills.Attribute.Resolve1",
"to": "Skills.Attribute.Resolve2"
},
{
"from": "Skills.Attribute.UnstoppableAttacks",
"to": "Skills.Perk.ToughLunge"
},
{
"from": "Skills.Ability.DeflectionSlow",
"to": "Skills.Attribute.Resolve1"
},
{
"from": "Skills.Ability.DeflectionSlow",
"to": "Skills.Perk.ToughLunge"
}
]
},
{
"name": "The Way",
"cols": 5,
"nodes": [
{
"tag": "Skills.Spice.ShadowStrike",
"id": "ShadowStrike",
"name": "Prescient Strike",
"kind": "Spice",
"row": 1,
"col": 3,
"maxPoints": 1,
"icon": "t_ui_iconskilltreeprescientstrike_d.webp",
"url": "https://dune.gaming.tools/skills/skills-spice-shadowstrike"
},
{
"tag": "Skills.Attribute.Aggression3",
"id": "Aggression3",
"name": "General Conditioning",
"kind": "Attribute",
"row": 2,
"col": 2,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeattributestamina_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-aggression3"
},
{
"tag": "Skills.Attribute.Aggression4",
"id": "Aggression4",
"name": "Desert Conditioning",
"kind": "Attribute",
"row": 2,
"col": 4,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeattributewatherdefense_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-aggression4"
},
{
"tag": "Skills.Ability.CripplingStrike",
"id": "CripplingStrike",
"name": "Crippling Strike",
"kind": "Ability",
"row": 3,
"col": 1,
"maxPoints": 1,
"icon": "t_ui_iconabilitycripplingstrike_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-cripplingstrike"
},
{
"tag": "Skills.Perk.SprintStamina",
"id": "SprintStamina",
"name": "Disciplined Breathing",
"kind": "Perk",
"row": 3,
"col": 3,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeperkrunner_d.webp",
"url": "https://dune.gaming.tools/skills/skills-perk-sprintstamina"
},
{
"tag": "Skills.Ability.BattleCry",
"id": "BattleCry",
"name": "Inspiration",
"kind": "Ability",
"row": 3,
"col": 5,
"maxPoints": 3,
"icon": "t_ui_iconabilitybattlecry_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-battlecry"
},
{
"tag": "Skills.Attribute.Aggression1",
"id": "Aggression1",
"name": "Field Medicine",
"kind": "Attribute",
"row": 4,
"col": 2,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeskillhealingmultiplier_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-aggression1"
},
{
"tag": "Skills.Attribute.Aggression2",
"id": "Aggression2",
"name": "Optimized Hydration",
"kind": "Attribute",
"row": 4,
"col": 4,
"maxPoints": 3,
"icon": "t_ui_iconskilltreeattributewatherbonus_d.webp",
"url": "https://dune.gaming.tools/skills/skills-attribute-aggression2"
},
{
"tag": "Skills.Ability.KneeCharge",
"id": "KneeCharge",
"name": "Knee Charge",
"kind": "Ability",
"row": 5,
"col": 3,
"maxPoints": 3,
"icon": "t_ui_iconabilitykneecharge_d.webp",
"url": "https://dune.gaming.tools/skills/skills-ability-kneecharge"
}
],
"edges": [
{
"from": "Skills.Attribute.Aggression3",
"to": "Skills.Spice.ShadowStrike"
},
{
"from": "Skills.Attribute.Aggression4",
"to": "Skills.Spice.ShadowStrike"
},
{
"from": "Skills.Ability.CripplingStrike",
"to": "Skills.Attribute.Aggression3"
},
{
"from": "Skills.Attribute.Aggression3",
"to": "Skills.Perk.SprintStamina"
},
{
"from": "Skills.Attribute.Aggression4",
"to": "Skills.Perk.SprintStamina"
},
{
"from": "Skills.Ability.BattleCry",
"to": "Skills.Attribute.Aggression4"
},
{
"from": "Skills.Ability.CripplingStrike",
"to": "Skills.Attribute.Aggression1"
},
{
"from": "Skills.Attribute.Aggression1",
"to": "Skills.Perk.SprintStamina"
},
{
"from": "Skills.Attribute.Aggression2",
"to": "Skills.Perk.SprintStamina"
},
{
"from": "Skills.Ability.BattleCry",
"to": "Skills.Attribute.Aggression2"
},
{
"from": "Skills.Ability.KneeCharge",
"to": "Skills.Attribute.Aggression1"
},
{
"from": "Skills.Ability.KneeCharge",
"to": "Skills.Attribute.Aggression2"
}
]
}
]
}