Skip to content

Branch Tree System

The branch tree describes, as a nested structure, the strengthen routes an item can take across star ranges, so the same item can gain different attributes, skills, and presentation per route.

Concepts

  • Branch node: A node in the branch tree with its own star stage definitions.
  • Fork point: A node's fork_after_star, meaning child branches become available after that star completes.
  • Branch path: The route an item has selected, a /-separated sequence of branch ids stored as branch_path in the strengthen layer.
text
root (★1-4) → fork_after_star: 4
  ├── sharp (Sharp route ★5-7) → fork_after_star: 7
  │     ├── lethal (Lethal route ★8-10)
  │     └── swift (Swift route ★8-10)
  └── heavy (Heavy route ★5-10)

Configuration

Branches are configured in strengthen recipes through branch_tree. branch_tree itself is the root node:

yaml
id: "weapon_refine_branch"

branch_tree:
  branch_id: "root"
  display_name: "<white>Basic Refinement</white>"
  fork_after_star: 4
  stars:
    1:
      effects:
        - type: "variables"
          variables:
            physical_attack: 5
      materials:
        - item_sources:
            - "minecraft-copper_ingot"
          amount: 2
  children:
    sharp:
      branch_id: "sharp"
      display_name: "<red>Sharp Route</red>"
      fork_after_star: 7
      stars:
        5:
          effects:
            - type: "variables"
              variables:
                physical_crit_rate: 3
          materials:
            - item_sources:
                - "minecraft-copper_ingot"
              amount: 3
      children:
        lethal:
          branch_id: "lethal"
          display_name: "<dark_red>Lethal Route</dark_red>"
          fork_after_star: -1
          stars:
            8:
              effects:
                - type: "variables"
                  variables:
                    physical_crit_damage: 10
    heavy:
      branch_id: "heavy"
      display_name: "<gold>Heavy Route</gold>"
      fork_after_star: -1
      stars:
        5:
          effects:
            - type: "variables"
              variables:
                physical_attack: 9

Fields

Every branch node supports the following fields:

FieldTypeDefaultDescription
branch_idstringThe node's key (root for the root node)Branch identifier.
display_namestringemptyBranch display name.
fork_after_starinteger-1Enter child branches after this star completes. -1 means no further fork.
starsmapemptyStar stage definitions inside this branch, identical in format to a linear recipe's stars.
childrenmapemptyChild branch nodes keyed by child branch id.

A node whose stars and children are both empty is ignored.

Effect on the item

Attributes, skills, and presentation accumulate along the branch path: starting from the root node and walking down the selected path, all star stages at or below the current star are collected and their effects summed.

Concretely:

  • Variable accumulation: Sum of variables effects across the stages on the path.
  • Attribute accumulation: Sum of ea_attribute effects across the stages on the path, written to the PDC attribute layer.
  • Skill binding: The set of skill ids collected from es_skill effects on the path.
  • Name and lore: The accumulated name_action / lore_action chains from the stages on the path.

The branch path is stored alongside star and temper in the branch_path field of the strengthen layer audit data.

Branch recipe file

The default resources include recipes/example_branch_recipe.yml as a reference for branch strengthen recipes. Branch recipes suit designs such as:

  • Weapons choosing an output route (attack speed, critical, penetration) at mid-to-high stars.
  • Armor choosing defense, health, tenacity, or resistance routes at a specific star.
  • Accessories choosing resource, skill, or utility attributes based on class role.

Keep linear and branch strengthening in separate recipes so one file does not carry too many rules. The more branch nodes there are, the harder it is for players to understand; one or two forks are usually easier to maintain.

Current implementation scope

The branch tree data model, path resolution, stage collection, and persistence are all implemented, but the current version does not provide a way for players to select a branch in the GUI, nor a command or action that sets the branch path. Therefore:

  • An item's branch_path stays empty throughout the normal strengthen flow, which is equivalent to growing along the root route only.
  • After the star given by the root node's fork_after_star, if later stars are only defined under children, the item cannot be strengthened further.
  • When designing a branch recipe that must remain usable linearly, make sure the root node's stars cover every star players should be able to reach.

Milestone flags

The item state records the set of stars reached for the first time, used to:

  • Prevent repeated broadcasts; see Broadcast.
  • Record the item's growth history.

Administrators can inspect the main-hand item's star, temper, recipe, and first-reach flags with /estrengthen inspect.

Strengthen transfer

The runtime includes a strengthen transfer service that migrates star levels from one item to another. Rules implemented today:

  • The source item must already be strengthened, and the target item must be eligible with a resolvable recipe.
  • Transferred stars = floor(source star × decay rate), where the decay rate is clamped to 0~1.
  • The transferred star count is clamped to the target recipe's limits.max_star.
  • StrengthenTransferEvent fires, allowing external code to cancel or rewrite the transferred star count; a rewritten value is clamped again.
  • Transfer aborts when the transferred star count is 0 or below.
  • Transfer is rejected when the target recipe has a branch tree that requires a branch selection at that star.
  • Transfer resets the target item's temper to 0.

The current version does not ship a built-in command or GUI entry point that triggers a transfer; the service targets the API and future feature work.