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
# 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 Type | Description | Key Fields |
|---|---|---|
stat_contribution | Attribute contribution, provides numeric attributes to the product | stat, amount |
structured_presentation | Structured presentation, controls product name and Lore rendering | name_contributions, lore_sections |
capacity_bonus | Capacity bonus, increases forge capacity limit | amount |
quality_modify | Quality modifier, forces or sets minimum quality | modifier_type, tier |
attribute | EA attribute write, writes EmakiAttribute attributes to the product | attribute, value |
name_modify | Name modification, modifies product display name | format |
lore_action | Lore operation, appends/replaces product Lore lines | action, 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| Variable | Description |
|---|---|
stat | Attribute name (e.g., physical_damage) |
amount | Base attribute value provided by the material |
quality_multiplier | Quality 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_type | Description |
|---|---|
force | Forces quality to the specified tier, ignoring random results |
minimum | Sets a minimum quality tier; if the random result is lower, it is raised to this tier |
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:
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 Type | Description | Fields |
|---|---|---|
set_name | Set item display name | value |
set_lore | Set item Lore | lines |
set_custom_model_data | Set custom model data | value |
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:
| Variable | Description | Example Value |
|---|---|---|
{physical_damage} | Physical damage attribute value (after quality multiplier calculation) | 24.0 |
{quality} | Quality tier name | 传说 |
{multiplier} | Quality multiplier | 2.0 |
{player} | Player name | Steve |
{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:
| Field | Description |
|---|---|
recipe_id | Recipe ID used |
quality | Final quality tier |
quality_multiplier | Quality multiplier |
materials_used | List of consumed materials |
stat_values | Final attribute value mapping |
timestamp | Forging timestamp |
blueprint_id | Blueprint 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 displayNote
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.