Description
Ultimate Skills
A skill mod built around a node tree, and built for the people making modpacks. There is no hardcoded list of skills to work around: every node in the tree is a JSON file, so the tree that ships with the mod is just a starting point you are meant to replace.
The tree
Open it with K. It is a pan-and-zoom canvas: drag to move, scroll to zoom, left-click a node to learn it. Connections light up gold as you take them, so the path you have carved is visible at a glance.
421 nodes ship with the mod, laid out as twelve radial branches around a single starting node. Each branch is built on one attribute and runs ten nodes deep, with side branches of four splitting off every third node, a mastery at the end of every branch and every side branch, and a keystone further out still.
The twelve branches: Blade (melee damage), Fury (attack speed), Plating (armor), Temper (armor toughness), Vigor (max health), Swiftness (movement speed), Delving (mining speed), Fortune (luck), Anchor (knockback resistance), Mason (block reach), Hunter (reach against mobs) and Drift (safe fall distance).
Every node states exactly what it gives. Masteries and keystones also grant a permanent potion
effect — Strength, Haste, Resistance, Fire Resistance, Regeneration, Speed, Luck, Night Vision or
Slow Falling depending on the branch. Those effects refresh themselves, so they survive death,
dimension changes and /effect clear.
Points come from vanilla experience levels, and nodes are permanent once taken. /uskills reset
hands every point back if you want to start over.
Every node is a file
A node lives in data/<your_namespace>/skilltree/nodes/<id>.json:
{
"title": "Executioner",
"description": ["+3 melee damage and permanent Strength."],
"icon": "minecraft:netherite_sword",
"type": "notable",
"x": 420, "y": 0,
"cost": 2,
"player_level": 15,
"connections": ["ultimateskills:blade_9"],
"bonuses": [
{ "attribute": "minecraft:generic.attack_damage", "amount": 3.0 },
{ "attribute": "minecraft:generic.attack_speed", "amount": 0.15, "operation": "add_multiplied_base" }
],
"effects": [
{ "effect": "minecraft:strength" }
]
}
| Field | Default | What it does |
|---|---|---|
title |
— | Name shown in the tooltip |
lang |
— | Shared translation key, so many nodes can reuse one set of strings |
description |
empty | Tooltip lines |
icon |
minecraft:book |
Item drawn inside the node |
type |
minor |
start, minor, notable, keystone or gateway — sets size and colour |
x, y |
required | Position on the canvas |
cost |
1 | Points it costs |
player_level |
0 | Vanilla experience level demanded |
connections |
empty | Nodes it links to; links are made two-way automatically |
requires |
empty | Nodes that must already be learned |
bonuses |
empty | Attribute modifiers, any attribute including modded ones |
effects |
empty | Permanent potion effects |
A node can be taken when it is a start node or when something it connects to is already learned,
its requires are met, you have the points, and you are at the experience level it asks for.
Connections only need to be declared once: say A connects to B and the mod adds B to A on load. On every reload it also reports the shape of the tree in the log — node count, roots, how many are reachable, one-way links, broken links — and warns about any node no player could ever reach.
Recommended: OpenLoader — a normal
datapack lives inside one world, so you have to copy it into every new one. With OpenLoader the same
files go in config/openloader/data/ and load in every world.
Or write it in KubeJS
If KubeJS is installed the mod adds a global Skills binding. It goes in
kubejs/server_scripts/ — the tree loads with the datapack, so startup and client scripts are
thrown away when the world loads, and the mod warns you in the log.
Skills.node('mypack:brutal_strike')
.title('Brutal Strike')
.description('+4 melee damage and permanent Strength.')
.icon('minecraft:netherite_axe')
.type('notable')
.at(490, -70)
.cost(2)
.playerLevel(15)
.connect('ultimateskills:blade_10')
.bonus('minecraft:generic.attack_damage', 4)
.bonus('minecraft:generic.attack_speed', 0.2, 'add_multiplied_base')
.effect('minecraft:strength')
.register()
Nothing happens without .register() — that is the one thing people forget. raw({...}) takes
a whole object when a builder method does not cover what you need.
Commands
/uskills (or the shorter /ust):
/uskills info— your points, what you have spent, and every node you have learned./uskills points <players> <amount>— hand out or take away points./uskills learn <players> <node>— force a node, ignoring cost and connections./uskills reset <players>— wipe the learned nodes and give every point back./uskills nodes— how many nodes the tree currently has.
Configuration
config/ultimateskills-common.toml
| Option | Default | What it does |
|---|---|---|
enabled |
true | Master switch for the screen and every bonus |
starting_points |
1 | Points given on first join |
points_per_player_level |
1 | Points per vanilla experience level gained |
reset_on_death |
false | Wipes learned nodes on death, handing the points back |
max_points |
0 | Cap on points held at once; 0 removes the cap |
Languages
English and Spanish, with es_es, es_mx and es_ar all shipped, because Minecraft does not fall
back between Spanish variants. Node text goes through translation keys with the JSON string as a
fallback, so a pack that adds nodes without translating them still reads fine.
Requeriments:
· Minecraft 1.21.1
· NeoForge 21.1.240

