English
Forge History
Forge stores one forging record per player to count recipe usage, drive the quality pity counter, and back the forge placeholders
Configuration
History lives under the history node of config.yml. Shipped defaults:
yaml
history:
enabled: true
auto_save: true
# autosave interval, 6000 ticks = 5 minutes
save_interval: 6000| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
history.enabled | boolean | No | true | true / false | Together with auto_save, decides whether the periodic save task is scheduled. It does not change how craft counts and pity counters accumulate: counting always happens; only periodic saving is turned off |
history.auto_save | boolean | No | true | true / false | Whether player data is saved periodically |
history.save_interval | integer | No | 6000 | A tick count, >= 0 (falls back to 6000 when unparsable) | Period and initial delay of the periodic save, in ticks (20 ticks = 1 second). 6000 ticks is about 5 minutes |
NOTE
When either enabled or auto_save is false, the periodic autosave task is not scheduled. Disabling autosave is not the same as never writing: player quit, reload, and shutdown still persist data
yaml
history:
enabled: true
auto_save: true
# 10 minutes
save_interval: 12000Storage location
Player data is stored one file per player at plugins/EmakiForge/data/<player-uuid>.yml. Writes go through an async path, and the file also carries _meta version information so concurrent sessions can decide which snapshot is newer
File structure
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
uuid | string | Yes | — | Player UUID | Owner of the data |
recipes | map | No | empty | Key is a recipe id | History grouped by recipe. Only recipes that were forged appear |
recipes.<recipe_id>.craft_count | integer | No | 0 | >= 0 | Successful forge count for that recipe |
recipes.<recipe_id>.first_crafted_at | string | No | blank | ISO-8601 timestamp | First forge time |
recipes.<recipe_id>.last_crafted_at | string | No | blank | ISO-8601 timestamp | Most recent forge time; backs %emakiforge_last_crafted% |
guarantee | map | No | empty | Key is a recipe id, value is an integer | Consecutive-failure count for quality pity. Only recipes that changed appear |
_meta.epoch | integer | Yes | 0 | >= 0 | Session epoch, used to order concurrent writes |
_meta.revision | integer | Yes | 0 | >= 0 | Revision within the same epoch |
_meta.tombstone | boolean | Yes | false | true / false | When true the file is a deletion marker and loads as empty data |
yaml
uuid: "3f1c1f2a-0000-0000-0000-000000000000"
recipes:
flame_sword:
craft_count: 3
first_crafted_at: "2026-01-01T10:00:00Z"
last_crafted_at: "2026-01-02T12:30:00Z"
guarantee:
flame_sword: 2
_meta:
epoch: 12
revision: 0
tombstone: falseRelationship with quality pity
The pity counter is stored in the guarantee node of the player data file, so the two are directly related:
- Each forge whose result ranks below the pity minimum tier increases the pity counter by 1
- Once the counter reaches the threshold, pity triggers and the counter resets
- Pity conditions and threshold are documented in Quality
Operational guidance
- On a production server keep
enabledandauto_saveon - On a high-concurrency server raise
save_intervalto reduce write frequency - Seasonal or event servers can archive the
data/folder afterwards to analyse recipe output
Troubleshooting
- Data not saved: first check
enabled,auto_save, anddata/directory permissions - When player data fails to load, that player's session stays read-only to protect the existing file and a warning is printed to console
- Odd pity behaviour: first confirm the current counter with
%emakiforge_guarantee_<recipe_id>%, then re-check the recipe-level and global pity config - Odd data after a reload: first check the autosave interval, and if needed stop the server during maintenance and let data flush before inspecting files