Tutorial 2 — Adding Your First Mob Affix
A mob affix is a modifier applied to living entities that changes their behaviour or stats. This tutorial adds a simple affix that gives mobs bonus armor, then registers it so it can be applied to entities.
Prerequisites: Complete Tutorial 1 first.
1. Create a key holder for affixes
An ExileKeyHolder is a typed container for a group of related registry entries. Create one for
your mod's affixes:
public class MyAffixHolder extends ExileKeyHolder<ExileMobAffix> {
public MyAffixHolder(String modid) {
super(modid, LibDatabase.MOB_AFFIX);
}
// Declare all your affixes here as public fields.
public ExileKey<ExileMobAffix, KeyInfo> IRON_HIDE = ExileKey.ofId(
this,
"my_mod:iron_hide", // unique GUID — modid:name format is strongly recommended
x -> {
var data = AttributeMobAffix.Data.of(
Attributes.ARMOR,
UUID.fromString("a1b2c3d4-e5f6-7890-abcd-ef1234567890"), // stable UUID
AttributeModifier.Operation.ADDITION,
new AffixNumberRange(5, 20) // min 5 armor at 0%, max 20 at 100%
);
return new AttributeMobAffix(
ExileMobAffix.Affects.MOB,
x.GUID(),
1000, // weight — higher = more common
data,
AffixTranslation.ofAttribute(Ref.MODID)
);
}
);
}
Notes on the UUID: Every AttributeMobAffix needs a stable, unique UUID. Generate one
offline and hardcode it. Two affixes with the same UUID will conflict on the same entity.
2. Register the key holder
Add your holder to MyModConstructor.getAllKeyHolders():
public static final MyAffixHolder AFFIXES = new MyAffixHolder("my_mod");
@Override
public List<ExileKeyHolder> getAllKeyHolders() {
return List.of(AFFIXES);
}
OrderedModConstructor.register calls holder.init() on each holder, which schedules the
factory to run when the EXILE_REGISTRY_GATHER event fires for MOB_AFFIX.
3. Apply the affix to entities
Affixes are pulled from ExileEvents.GRAB_MOB_AFFIXES each tick. Register a listener in your
mod constructor (or CommonInit):
ExileEvents.GRAB_MOB_AFFIXES.register(new EventConsumer<GrabMobAffixesEvent>() {
@Override
public void accept(GrabMobAffixesEvent e) {
// Only apply to Zombies, at 75% power.
if (e.en instanceof Zombie) {
e.add(new ExileAffixData(MyModConstructor.AFFIXES.IRON_HIDE.GUID(), 75));
}
}
});
A good place to register this listener is inside registerDatabaseEntries() in your
OrderedModConstructor, or in a static initializer that runs at mod load.
4. Test in-game
Run the client, spawn a Zombie, and inspect its attributes with:
/attribute @e[type=minecraft:zombie,limit=1] minecraft:generic.armor get
The value should be 5–20 above the base armor value, depending on how other mods set the power percentage.
What you learned
- How to declare a named affix with
ExileKey.ofIdinside anExileKeyHolder. - How to use
AttributeMobAffixwith a fixed UUID and a numeric range. - How to hook
GRAB_MOB_AFFIXESto apply affixes conditionally.
Next steps
- Tutorial 3: Adding Your First Relic
- How-to: Add Mob Affixes — covers potion affixes and JSON-driven affixes.