Tutorial 3 — Adding Your First Relic
A relic is a special equippable item with procedurally rolled stat modifiers. A complete relic
system requires four pieces: a RelicItem, a RelicType, at least one RelicStat, and at least
one RelicAffix. This tutorial builds all four.
Prerequisites: Complete Tutorial 1.
1. Register a RelicItem
A RelicItem is a plain Item subclass. Register it with Forge's DeferredRegister:
// In MyModConstructor:
public static final DeferredRegister<Item> ITEMS =
DeferredRegister.create(ForgeRegistries.ITEMS, "my_mod");
public static final RegistryObject<Item> AMULET_ITEM =
ITEMS.register("amulet", RelicItem::new);
Wire the DeferredRegister in registerDeferredContainers:
@Override
public void registerDeferredContainers(IEventBus bus) {
ITEMS.register(bus);
}
2. Define a RelicType via JSON
A RelicType entry tells the library which Item is used for this relic and how many can be
equipped simultaneously.
Create the file:
src/main/resources/data/my_mod/library_of_exile_relic_type/amulet.json
{
"id": "my_mod:amulet",
"item_id": "my_mod:amulet",
"weight": 1000,
"max_equipped": 1
}
item_idmust match theResourceLocationof theRegistryObjectyou registered above.max_equippedlimits how many relics of this type a player can wear at once.
3. Define a RelicStat via JSON
A RelicStat is a named numeric quantity. Create:
src/main/resources/data/my_mod/library_of_exile_relic_stat/life_regen.json
{
"id": "my_mod:life_regen",
"serializer": "manual_stat",
"is_percent": false,
"min": 0,
"max": 500,
"base": 0
}
manual_stat is the generic stat type. If you need a stat that influences map content spawning
weights, use "content_weight" instead (see the Relics reference).
4. Define a RelicAffix via JSON
A RelicAffix bundles one or more stat rolls onto a specific relic type. Create:
src/main/resources/data/my_mod/library_of_exile_relic_affix/amulet_life_regen.json
{
"id": "my_mod:amulet_life_regen",
"weight": 800,
"relic_type": "my_mod:amulet",
"mods": [
{
"stat": "my_mod:life_regen",
"min": 10.0,
"max": 50.0
}
]
}
relic_typemust match theidof yourRelicTypeJSON.modsis a list ofRelicModentries, each pairing a stat with a value range.
5. Read stat values at runtime
When the library rolls a relic, it produces a list of ExactRelicStat objects. You read the
aggregated total using RelicStatsContainer:
List<ExactRelicStat> mods = // ... from the relic's capability data
RelicStatsContainer stats = RelicStatsContainer.calculate(mods);
// Look up by GUID string:
float regenValue = stats.get(Database.get(LibDatabase.RELIC_STAT, "my_mod:life_regen"));
// Or look up by ExileKey reference:
float regenValue = stats.get(MY_RELIC_STAT_KEY);
6. Test in-game
After running the client with /reload, your relic type, stat, and affix should be registered.
You can give yourself a relic item with /give @s my_mod:amulet and inspect its rolled affixes
through whatever display system your dependent mods provide.
What you learned
- How to register a
RelicItemwith Forge'sDeferredRegister. - How to link it to a
RelicTypeJSON entry. - How to define
RelicStatandRelicAffixentries via JSON datapacks. - How to read rolled stat values with
RelicStatsContainer.
Next steps
- How-to: Add Relics and Relic Affixes — advanced stat types, rarities.
- Reference: Relics — complete field listings.