Skip to content

Recipe System

Recipes are the core data structure of EmakiForge, defining the blueprints, materials, quality rules, and output results required for forging. Each recipe corresponds to a YAML file in the recipes/ directory.

Full Recipe Format

yaml
# Recipe unique identifier
id: example_sword

# Display name (supports MiniMessage format)
display_name: "<gold>铁剑锻造"

# Forge capacity — limits the total capacity of materials that can be invested
forge_capacity: 100

# ===== Blueprint Requirements =====
# A matching blueprint must be placed in the blueprint slot before forging
blueprint_requirements:
  - iron_sword_blueprint

# ===== Material List =====
materials:
  # Required material
  - item: "minecraft:iron_ingot"
    amount: 5
    optional: false
    capacity_cost: 10
    effects:
      - type: stat_contribution
        stat: physical_damage
        amount: 12.0

      - type: quality_modify
        modifier_type: minimum    # minimum | force
        tier: "精良"

  # Optional material
  - item: "neigeitems:magic_crystal"
    amount: 1
    optional: true
    capacity_cost: 20
    effects:
      - type: attribute
        attribute: "攻击力"
        value: 5.0

      - type: capacity_bonus
        amount: 15

      - type: name_modify
        format: "<light_purple>魔力{name}"

      - type: lore_action
        action: append
        section: enchant_info
        lines:
          - "<gray>附魔:<aqua>魔力注入"

      - type: structured_presentation
        name_contributions:
          magic_prefix:
            order: 1
            format: "<light_purple>魔力 "
        lore_sections:
          magic_info:
            order: 50
            lines:
              - "<gray>魔力注入:<aqua>+5"

# Optional material count limit
optional_material_limit: 3

# ===== Condition System =====
# Condition type: all_match (all must be met) | any_match (any one met)
condition_type: all_match
conditions:
  - type: permission
    value: "emakiforge.recipe.example_sword"
  - type: level
    operator: ">="
    value: 10
  - type: placeholder
    placeholder: "%player_exp%"
    operator: ">="
    value: "500"

# ===== Quality Configuration =====
quality:
  # Custom quality pool (uses global tiers from config.yml if not set)
  custom_pool:
    - "普通-40-1.0"
    - "精良-35-1.3"
    - "史诗-20-1.6"
    - "传说-5-2.0"

  # Quality actions — trigger different actions based on quality tier
  actions:
    传说:
      - "broadcast message=<gold>{player} <yellow>锻造出了传说品质的 {item}!"
      - "playsound sound=ui.toast.challenge_complete volume=1.0 pitch=1.0"
    史诗:
      - "playsound sound=entity.player.levelup volume=1.0 pitch=1.2"

# ===== Result Definition =====
result:
  # Output item (item source ID)
  output_item: "minecraft:iron_sword"

  # Meta actions — modification operations performed on the output item
  meta_actions:
    - type: set_name
      value: "{quality} 铁剑"
    - type: set_lore
      lines:
        - "<gray>物理伤害:<white>{physical_damage}"
        - "<gray>品质:<white>{quality}"
        - "<gray>品质倍率:<white>{multiplier}"
    - type: set_custom_model_data
      value: 10001

  # Action phases
  action:
    # Execute before forging
    pre:
      - "playsound sound=block.anvil.use volume=1.0 pitch=0.8"
      - "sendmessage message=<gray>开始锻造..."

    # Execute after successful forging
    success:
      - "playsound sound=block.anvil.land volume=1.0 pitch=1.2"
      - "sendmessage message=<green>锻造成功!品质:{quality}"
      - "giveexp amount=100"

    # Execute after failed forging (forging always succeeds in current version, this phase is reserved)
    failure:
      - "playsound sound=block.anvil.destroy volume=1.0 pitch=0.5"
      - "sendmessage message=<red>锻造失败了..."

# Permission node (optional, overrides global permission check)
permission: "emakiforge.recipe.example_sword"

Material Effect Types

The effects list of materials supports the following effect types:

Effect TypeDescriptionKey Fields
stat_contributionAttribute contribution, provides numeric attributes to the productstat, amount
structured_presentationStructured presentation, controls product name and Lore renderingname_contributions, lore_sections
capacity_bonusCapacity bonus, increases forge capacity limitamount
quality_modifyQuality modifier, forces or sets minimum qualitymodifier_type, tier
attributeEA attribute write, writes EmakiAttribute attributes to the productattribute, value
name_modifyName modification, modifies product display nameformat
lore_actionLore operation, appends/replaces product Lore linesaction, section, lines

stat_contribution Details

Attribute contribution is the most commonly used material effect. The calculation formula is:

final_attribute_value = stat × amount × quality_multiplier
VariableDescription
statAttribute name (e.g., physical_damage)
amountBase attribute value provided by the material
quality_multiplierQuality multiplier (determined by quality tier, e.g., Legendary = 2.0)

Example: A material provides physical_damage = 12.0, quality is "Legendary" (multiplier 2.0), so the final physical damage = 12.0 × 2.0 = 24.0.

quality_modify Details

Quality modifiers support two modes:

modifier_typeDescription
forceForces quality to the specified tier, ignoring random results
minimumSets a minimum quality tier; if the random result is lower, it is raised to this tier
yaml
effects:
  - type: quality_modify
    modifier_type: minimum
    tier: "精良"

structured_presentation Details

The structured presentation effect allows materials to inject name prefixes/suffixes and Lore sections into the product:

yaml
effects:
  - type: structured_presentation
    name_contributions:
      magic_prefix:
        order: 1          # Sort weight, lower values appear first
        format: "<light_purple>魔力 "
    lore_sections:
      magic_info:
        order: 50         # Lore section sort weight
        lines:
          - "<gray>魔力注入:<aqua>+5"

Result meta_actions

meta_actions are used to perform modification operations on the output item after forging is complete:

Action TypeDescriptionFields
set_nameSet item display namevalue
set_loreSet item Lorelines
set_custom_model_dataSet custom model datavalue

The value and lines in meta_actions support variable injection.

Variable Injection

The following variables can be used in recipe meta_actions, action phases, and quality actions:

VariableDescriptionExample Value
{physical_damage}Physical damage attribute value (after quality multiplier calculation)24.0
{quality}Quality tier name传说
{multiplier}Quality multiplier2.0
{player}Player nameSteve
{item}Output item name铁剑

Tip

All stat names declared in stat_contribution are automatically registered as available variables. For example, if stat: spell_power is declared, {spell_power} can be used in templates.

Audit Data

After each forging is complete, the system records the following audit data to the player data file:

FieldDescription
recipe_idRecipe ID used
qualityFinal quality tier
quality_multiplierQuality multiplier
materials_usedList of consumed materials
stat_valuesFinal attribute value mapping
timestampForging timestamp
blueprint_idBlueprint ID used

ForgeLayerSnapshotBuilder Pipeline

ForgeLayerSnapshotBuilder is responsible for building the forging result into a layer snapshot and writing it to the product:

Collect material contributions

Calculate quality tier (weighted random / pity / material modifiers)

Apply quality multiplier to all stat_contributions

Merge structured_presentation (name contributions + Lore sections)

Merge attribute write list

Build ForgeLayerSnapshot

Write to item PDC via AssemblyService

Trigger StructuredPresentationRenderer to rebuild item display

Note

In the current version's recipe DSL, invalid condition_type values are rejected at load time. Declaring a target_item node in a recipe will also be rejected by the loader.

Released under the GPL-3.0 License