Kzeroko KTM2

Skill-tree Data

Add unlock conditions to Puffish skill nodes and grant local learnable powers as rewards.

Updated Sep 19, 2026 6 min read

Skill requirements add a condition to an existing skill-tree node. A separate reward bridge grants an Origins power when Puffish Skills updates that definition’s unlock count; neither format creates the graph itself.

Where the files live

Requirements load from data/<namespace>/skill_requirement/*.json, including subdirectories. A file contains category IDs, each mapping node IDs to conditions. The file’s namespace does not choose the target category: the category key does.

The same resource ID is selected through normal data-pack priority. Different files can contribute to the catalogue, but do not define the same category/node pair in several files: the registry does not merge conditions or provide a stable winner.

Puffish Skills owns the graph format under data/<namespace>/puffish_skills/categories/<category>/. The bundled main tree is isekaiskills:main. This page documents the local requirement format and isekaiexpansion:learnable_power reward data; Puffish’s category, definition and connection formats belong to that dependency, checked here against version 0.18.2+1.20.

Minimal example

This is the first condition from the bundled main requirement file:

{
  "isekaiskills:main": {
    "aegis_t1_gate": {
      "condition_type": "level",
      "condition_value": 10
    }
  }
}

As an override of data/isekaiexpansion/skill_requirement/main.json, this replaces that entire selected file and therefore removes its other bundled conditions. Keep the remaining entries when changing just this gate. In a new category, use its real category ID and node ID; requirement keys identify nodes, not reusable definition IDs.

Fields

FieldTypeDefaultMeaning and limits
<category-id>objectEntries optional; empty root acceptedResource identifier of the Puffish category. The example uses isekaiskills:main. Invalid syntax stops that file.
<node-id>objectEntries optionalExact node key in that category’s skills data. The example uses aegis_t1_gate. No existence check is performed here.
condition_typestringRequiredExact lowercase name from the table below; unknown names fail.
condition_valueinteger / number / stringRequiredType depends on the condition. Numeric conversion does not impose gameplay ranges or a non-negative clamp.
identifierstringRequired for attribute and talent; otherwise absentAttribute or talent resource ID. If supplied for another condition it must still parse, but does not affect that condition.
condition_typecondition_valueidentifierCheck
levelInteger player levelUnusedCurrent IsekaiCore level is at least the threshold.
originOrigin identifier stringUnusedCurrent race-origin ID equals the value.
classClass identifier stringUnusedCurrent class ID equals the value.
professionProfession identifier stringUnusedCurrent profession ID equals the value.
xp_amountInteger experience amountUnusedStored vanilla total experience is at least the threshold.
xp_levelInteger experience levelUnusedCurrent vanilla experience level is at least the threshold.
destinyInteger destiny valueUnusedCurrent destiny is at least the threshold.
adventurer_rankInteger rank valueUnusedIsekaiCore’s rank check accepts the threshold.
attributeNumeric attribute thresholdRequired attribute IDCurrent attribute value is at least the threshold; an absent entity attribute fails.
talentInteger talent rank levelRequired talent IDCurrent talent rank level is at least the threshold.

A condition does not spend experience, destiny or attributes. It gates a new unlock, not continued possession of the node. Each entry contains a single condition; adding duplicate entries is not a supported way to express an AND or OR.

Learnable-power reward

Place this reward entry inside a Puffish skill definition’s rewards list. It is the same reward used by the bundled Appraisal definition:

{
  "type": "isekaiexpansion:learnable_power",
  "data": {
    "power": "isekaiskills:spassive_appraisal"
  }
}
FieldTypeDefaultMeaning and limits
typestringRequiredReward type isekaiexpansion:learnable_power.
dataobjectRequiredLocal reward payload; unused keys inside it are rejected.
powerstringRequiredSyntactically valid Origins power ID; existence is resolved when applying the reward.

Puffish Skills counts unlocked nodes sharing a definition and supplies that count to the reward. The local bridge grants the power through isekaiexpansion:learnables; upgradeable powers use the count as their level, bounded by their declared maximum. At a count of 0 it removes that source. A missing power type is ignored by the bridge, so a successfully parsed reward can still grant nothing.

The main tree’s active powers use meta.max_level, meta.cooldown and meta.energy, not legacy top-level equivalents. Skill-tree runtime covers their current authoring path; the current tree’s active effects are described in Wheel of Fate.

Validation

InputRequirement-loader behaviour
Missing required field, wrong object shape, unknown condition name, malformed identifierLogs an error for that resource and stops the rest of that file. Entries already registered from it remain. Other resources still load.
Unknown condition-object fieldIgnored; it does not create an extra condition.
Unknown category or nodeAccepted as a lookup key; it has no effect until something uses that exact category/node pair.
Syntactically valid but unregistered identity IDNot rejected at load; identity equality normally cannot match it.
Unknown attribute or talent IDNot checked at load. Use registered IDs; their later resolution belongs to the attribute/talent system and is not a loader validation guarantee.
Negative or excessive numeric thresholdNot range-checked here; the comparison uses the parsed value. Use integer JSON numbers for integer conditions.
Duplicate category/node across resourcesSeparate objects coexist; lookup takes an arbitrary first match from the set. No combined condition or deterministic override.
Empty root objectAccepted, contributes no conditions. Reload still discards the previous registry first.
Empty or malformed JSON textNo valid condition document; do not use it to disable an entry.

The reload is not transactional. A bad replacement can leave a partially populated catalogue, rather than retaining the old one. Reward data has different handling: its parser returns errors for missing power, invalid identifiers and unused payload keys to Puffish’s category-loading process.

Reloading

Server data reload rebuilds the requirement registry. The full local requirement catalogue is sent to a client on joining; there is no corresponding requirement broadcast on reload in the current wiring. Reconnect after editing requirements so client tooltips and eligibility agree with the server.

The server rechecks conditions during unlock, including forced dependency unlock requests. Graph reload and saved unlocks are managed by Puffish Skills; successful graph loading does not prove that the separate local requirement catalogue reached a connected client.

Wheel of Fate explains the bundled graph. Skill-tree runtime covers gates, synchronisation and the generator. Talents and Identity explain the values tested by talent and identity conditions.