Skip to content

KubeJS Atlas Builder

hp-1e edited this page Oct 25, 2026 · 1 revision

English | 中文

Atlas Builder

Use the builder inside SkillAtlasEvents.definitions. Scripts work on a staged copy of the base atlas (config/skill_atlas/atlas.json). The result is fully validated before it becomes the effective atlas.

SkillAtlasEvents.definitions(event => {
  event.createNode('pack_harvest_health')
    .name('Farmer Constitution')
    .category('farming')
    .icon('minecraft:golden_carrot')
    .position(0, 0)
    .level(1, rank => {
      rank.cost({ type: 'skill_points', amount: 1 })
      rank.attributeReward('minecraft:generic.max_health', 2, 'add')
    })
})

Event methods

Method Purpose
createNode(id) / createCategory(id) / createPool(id) Create and return a builder
modifyNode(id, callback) / modifyCategory(id, callback) / modifyPool(id, callback) Edit an existing object
removeNode(id) / removeCategory(id) / removePool(id) Remove an object
hasNode(id) / getNodeIds() / getSnapshot() Inspect the staged atlas

Builders close when the event callback ends. Writing through a builder you kept for later throws an error.

Node builder

Method Meaning
category(id) Category of the node
name(text) / description(text) Name and tooltip text
icon(itemIdOrIconObject) 'minecraft:diamond' or e.g. {type:'texture', id:'minecraft:textures/item/diamond.png'}
position(x, y) Canvas position
hidden(boolean) Hide until the prerequisites are met
requireAll(boolean) true: all prerequisites; false: any prerequisite
requires(id) Requires at least level 1 of id
requiresLevelGreaterThan(id, level) Requires a level strictly greater than level
clearPrerequisites() Remove all prerequisites
choiceGroup(groupId) Put the node into a choice group; '' removes it
condition(typeId, data) / clearConditions() Custom conditions for every learnable level
level(n, callback) Create or edit level n (starting at 1)
clearLevels() Remove all levels, including their custom declarations
json(patch) Merge raw node JSON fields

requiresLevelGreaterThan('haste', 2) means at least level 3.

Levels start at 1 and must be contiguous. Each level's rewards apply only while that level is the current one. They do not stack with lower levels, so if level 2 should give +2 in total, write amount = 2 on level 2.

Choice groups

Nodes that share the same choice group ID are mutually exclusive. Once a player learns any node in the group, the other nodes in that group are locked with the state Excluded. They become learnable again when the learned node is reset to level 0.

SkillAtlasEvents.definitions(event => {
  event.createNode('warrior_path').category('combat').choiceGroup('class').level(1, r => r.cost({ type: 'skill_points', amount: 1 }))
  event.createNode('mage_path').category('combat').choiceGroup('class').level(1, r => r.cost({ type: 'skill_points', amount: 1 }))
})
  • Group IDs follow the node ID rule: lowercase, no colon, at most 64 characters.
  • Groups are atlas-wide. Nodes in different categories can share a group.
  • A node that is already learned is never locked by its group. If two nodes were learned before the group was added, both stay learned and can still be upgraded.
  • The check runs on the server. Blocked attempts fail with code choice_excluded.
  • Map editors can set the same field in the in-game node editor (Choice group) or in JSON as "choice_group".

Level builder

Method Meaning
cost({type, amount}) type is 'skill_points' or 'experience' (actual experience points)
item(itemId, count[, nbtOrComponents]) Required delivery item
clearItems() Remove delivery items
attributeReward(attribute, amount, operation) Attribute modifier reward
effectReward(...) / immunityReward(...) / commandReward(...) Native reward types
reward(json) Any native reward JSON, or {type:'pack:type', data:{...}} for a custom reward
clearRewards() Remove native rewards only
condition(typeId, data) / clearConditions() Custom conditions for this level
customReward(typeId, data) / clearCustomRewards() Custom rewards for this level
json(patch) Merge raw level JSON fields

The field holding delivery item data is still called nbt. On 1.20.1 it is a full item NBT condition. On 1.21.1 and 26.1.2 it is Skill Atlas's component patch format. Old NBT strings cannot be reused unchanged on newer versions.

Category builder

Method Meaning
name(text) / icon(...) Display
pool(poolId) Point pool; '' means no pool, so costs fall back to actual experience
background(textureId, tiled) Canvas background
json(patch) Raw JSON fields

Pool builder

Method Meaning
name(text) / description(text) / color(rgb) / initial(points) Display and initial points
acquisition(method, count, points, limit) Native rule: kill, mine, harvest, craft, smelt, fish, movement, advancement, playtime
targets(array) Targets of a native rule, e.g. ['#minecraft:crops']
customAcquisition(typeId, data, count, points, limit) Bind to a registered acquisition type
json(patch) Raw JSON fields

Custom pools do not accept native targets. Switching back to a native acquisition, or setting method through json, removes the custom binding.

json(patch)

json merges top-level fields and replaces arrays as a whole. It cannot change the object's ID. The result still goes through the full native parser, so every native field works: shape, size, aliases, prerequisite lines, background images and so on. Ranges and totals are the same as for the base atlas. Nothing is relaxed for scripts.

Clone this wiki locally