Materials and Quality
This page provides detailed documentation on EmakiForge's material definition format, quality calculation pipeline, pity mechanism, blueprint format, and item refresh service.
Quality System
Quality Tier Format
Quality tiers are defined using a compact three-segment format:
"name-weight-multiplier"| Segment | Type | Description | Example |
|---|---|---|---|
| Name | String | Display name of the quality | 传说 |
| Weight | Integer | Weight for weighted randomization | 2 |
| Multiplier | Double | Multiplier for material contributions | 2.0 |
Example quality pool:
tiers:
- "粗糙-40-0.6" # 40% weight, 0.6 multiplier
- "普通-30-1.0" # 30% weight, 1.0 multiplier
- "精良-20-1.3" # 20% weight, 1.3 multiplier
- "史诗-8-1.6" # 8% weight, 1.6 multiplier
- "传说-2-2.0" # 2% weight, 2.0 multiplierQuality Calculation Pipeline
The final quality is determined through the following pipeline:
1. Determine quality pool
├── Recipe declares custom_pool? → Use recipe's custom quality pool
└── Not declared? → Use global tiers from config.yml
2. Apply material quality modifiers
├── Has force modifier? → Directly use force-specified quality, skip to step 4
└── Has minimum modifier? → Record minimum quality tier
3. Check pity counter
├── Counter ≥ guarantee.count? → Force guarantee.tier, reset counter
└── Not reached? → Continue
4. Execute weighted random
└── Randomly select a quality tier from the pool by weight
5. Apply minimum modifier
├── Random result below minimum? → Raise to minimum tier
└── Random result ≥ minimum? → Keep random result
6. Update pity counter
├── Final quality ≥ guarantee.tier? → Reset counter to 0
└── Final quality < guarantee.tier? → Counter +1Pity Counter Mechanism
The pity system prevents players from being unable to obtain high-quality products for extended periods:
guarantee:
enabled: true
count: 50 # 50 consecutive misses of target quality
tier: "史诗" # Force Epic quality on the 51st attemptHow it works:
- After each forging, if the final quality is below
guarantee.tier, the counter increments by 1 - If the final quality meets or exceeds
guarantee.tier, the counter resets to 0 - When the counter reaches the
countthreshold, the next forging forcesguarantee.tierquality - The pity counter is tracked per player and stored in player data
Material Quality Modifiers
Materials can influence quality results through the quality_modify effect:
| modifier_type | Behavior | Priority |
|---|---|---|
force | Forces quality to the specified tier, skipping randomization | Highest — direct override |
minimum | Sets a quality floor; raises the result if random outcome is below this tier | Applied after randomization |
# Force quality example
effects:
- type: quality_modify
modifier_type: force
tier: "传说"
# Minimum quality example
effects:
- type: quality_modify
modifier_type: minimum
tier: "精良"Note
When multiple materials declare force modifiers simultaneously, the last one to take effect wins. It is recommended to have at most one force modifier material per forging.
Quality structured_presentation Example
Quality tiers can be displayed on item names via item_meta.structured_presentation:
quality:
item_meta:
structured_presentation:
name_contributions:
quality_prefix:
order: 0
format: "{quality} "
lore_sections:
quality_info:
order: 0
lines:
- "<gray>品质:<white>{quality}"
- "<gray>倍率:<white>×{multiplier}"Quality Action Examples
Trigger different actions based on quality tier (e.g., server-wide broadcast):
quality:
actions:
传说:
- "broadcast message=<gold>✦ {player} <yellow>锻造出了 <gold>传说 <yellow>品质的 {item}!"
- "playsound sound=ui.toast.challenge_complete volume=1.0 pitch=1.0"
- "firework location=player colors=GOLD,YELLOW"
史诗:
- "playsound sound=entity.player.levelup volume=1.0 pitch=1.2"
- "sendmessage message=<light_purple>锻造出了史诗品质!"Blueprint Format
Blueprints define the base template for forging and are stored in the blueprints/ directory:
# Blueprint unique identifier
id: iron_sword_blueprint
# Display name
displayName: "<white>铁剑图纸"
# Item source (used to match the blueprint item placed by the player)
source: "minecraft:paper"
# Tags (used for blueprint_requirements matching in recipes)
tags:
- sword
- iron
- melee
# Forge capacity (base capacity provided by the blueprint, stacks with recipe's forge_capacity)
forgeCapacity: 50| Field | Type | Required | Description |
|---|---|---|---|
id | String | Yes | Blueprint unique identifier |
displayName | String | Yes | Display name, supports MiniMessage |
source | String | Yes | Item source ID, used for matching |
tags | List | No | Tag list, used for recipe matching |
forgeCapacity | Integer | No | Base forge capacity provided by the blueprint |
Material Format
Materials define the input items required for forging and their effects. They are stored in the materials/ directory or inlined directly in recipes:
# Item source ID
item: "minecraft:iron_ingot"
# Required amount
amount: 5
# Whether this is an optional material
optional: false
# Capacity cost (forge capacity points consumed)
capacity_cost: 10
# Material effect list
effects:
- type: stat_contribution
stat: physical_damage
amount: 12.0
- type: attribute
attributes:
physical_attack: 10.0
physical_crit_rate: 5.0
- type: skill
skills:
- "fireball"
- type: quality_modify
modifier_type: minimum
tier: "精良"| Field | Type | Required | Default | Description |
|---|---|---|---|---|
item | String | Yes | — | Item source ID |
amount | Integer | Yes | — | Required amount |
optional | Boolean | No | false | Whether this is an optional material |
capacity_cost | Integer | No | 0 | Capacity cost |
effects | List | No | [] | Material effect list |
ForgeItemRefreshService
The item refresh service automatically refreshes an item's display state when the forge layer data signature changes.
Trigger Conditions
- When a player opens their inventory
- When a player switches held items
- When an admin executes the refresh command
- After recipe/material resource reload
Refresh Pipeline
Check if item contains forge layer data
↓
Read forge layer snapshot from item PDC
↓
Calculate current snapshot signature (based on recipe version, material definitions, etc.)
↓
Compare with old signature stored on the item
├── Signatures match → Skip refresh
└── Signatures differ → Execute refresh
↓
Rebuild structured_presentation based on latest recipe and material definitions
↓
Update item name, Lore, and PDC data
↓
Write new signatureSignature Comparison
The signature is calculated based on the following data:
- Recipe ID and version
- Hash of material definitions
- Quality tier and multiplier
- Hash of structured_presentation templates
When a server admin modifies recipe or material definitions and reloads, the signatures of already-forged items will no longer match the new definitions, triggering automatic refresh to ensure all existing items' displays stay consistent with the latest configuration.
Tip
The refresh service only updates the item's display layer (name, Lore) and does not change the item's actual attribute values. Attribute values are determined at forging time and written to PDC, unaffected by subsequent configuration changes.