Skip to content

Branch Tree System ​

The branch tree covers how an item forks into different strengthen routes after certain stars, and what each route grants. The routes are described as a nested structure, so the same item gains 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 ​

You configure branches in a strengthen recipe's branch_tree, and that branch_tree is itself 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 ​

A branch node can carry these fields:

FieldTypeRequiredDefaultRangeDescription
branch_idstringNoThe node's key (root for the root node)—Branch identifier
display_namestringNoempty—Branch display name (used by the GUI selection screen)
fork_after_starintegerNo-1-1 or a positive integerEnter child branches after this star completes. -1 means no further fork; with children present, -1 cannot fork
starsmapNoemptykeys are positive target starsStar stage definitions inside this branch, identical in format to a linear recipe's stars
childrenmapNoemptykeys are child branch idsChild branch nodes

NOTE

A node whose stars and children are both empty is ignored

Effect on the item ​

Attributes, skills, and presentation accumulate along the branch path: walk down the selected path from the root node, collect every star stage at or below the current star, and sum its effects

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 ship 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 they are for players to understand; one or two forks are easier to maintain

Current implementation scope ​

The branch tree data model, path resolution, stage collection, and persistence are all implemented. You set a branch path with the /estrengthen branch [id] command: without id it lists the currently selectable branch IDs, and with id it writes the choice into the item's branch_path. There is currently no in-GUI graphical branch picker, and no matching CoreLib action stage. So:

  • Without running the branch command, an item's branch_path stays empty, which is equivalent to growing along the root route only
  • After the star given by fork_after_star, if later stars are only defined under children, you must run the branch command to choose a branch, or the item cannot be strengthened further (preview returns strengthen.branch.selection_required)
  • 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

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

Strengthen transfer ​

The runtime ships a strengthen transfer service that migrates star levels from one item to another. Current rules:

  • 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; you can cancel it or rewrite the transferred star count, and 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

NOTE

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