Java API
Everything on this page is for mods that build on PackEngine. Register things from your mod constructor. PackEngine reads packs only after every mod has been constructed, so load order doesn’t matter.
Custom action types
Register a namespaced action with UseActionRegistry:
UseActionRegistry.register(new ResourceLocation("my_mod", "stamina"), json -> {
float amount = json.get("amount").getAsFloat();
return (user, target, stack) -> MyStaminaApi.add(target, amount);
});
A pack can then write:
{ "type": "my_mod:stamina", "amount": 10 }
The event gets all the normal timing, animation filter and target fields. Your factory receives a copy of the whole event object, so changing it does nothing to PackEngine’s copy. Registering the same ID twice is an error.
Addon pack folders
PackEngine can scan a folder of your own as well as .minecraft/packengine/, so your addon’s
content and items can live in one place:
PackEnginePackLoader.registerPackDirectory(FMLPaths.GAMEDIR.get().resolve("my_addon"));
Every folder or zip in it with a pack.json loads exactly as it would from
.minecraft/packengine/. If a namespace has already been loaded from another folder, the second one
is skipped.
Addon-triggered animations
An item can have clips PackEngine never plays by itself. Your mod triggers them by name from whatever it controls: a reload key, an ability coming off cooldown, a block interaction. PackEngine plays the clip, its sound and its events. What the animation means in game is up to your mod.
"extra_animations": [
{
"name": "reload",
"animation": "reload",
"duration": 60,
"events": [ { "type": "my_mod:refill", "tick": 45 } ]
}
]
| Field | Default | Meaning |
|---|---|---|
name |
required | Name you trigger it by. Lowercase letters, digits and underscores. use, idle, equip and unequip are taken. |
animation |
name |
The clip to play. |
duration |
read from the clip | Length in ticks. |
events |
none | Same format as use_events, timing and filters included. |
To give it a sound, add its name as a key in the item’s sounds object.
Extra animations are one clip each. They don’t change with charges the way the built-in families do.
Triggering one
Call it on the server. PackEngine syncs it to every client tracking the player.
// server side, e.g. when handling your own reload-key packet
ItemStack held = player.getMainHandItem();
if (PackEngineApi.hasAnimation(held, "reload")) {
int ticks = PackEngineApi.playAnimation(player, InteractionHand.MAIN_HAND, "reload");
// ticks > 0: running
// -1: refused (not a PackEngine item, no such clip, or a use is running)
}
PackEngineApi also has isPackEngineItem, definitionOf, animationNames, isBusy,
playingAnimation and cancelAnimation.
While an extra animation plays, the item can’t be used. Switching hotbar slot or stack cancels it, along with its remaining events and sounds. Triggering one that’s already playing restarts it.
Put the gameplay result in your own action (see Custom action types) and
place it on the animation’s events at the tick it should happen. For a reload, that’s the tick the
charges come back.
Playing a third-person pose
If your mod shows an item that isn’t actually held (a first-person “phantom” hand, for example), start the body pose on the client yourself:
// client side, on every client that should see it
ThirdPersonAnimations.play(entityId, packEngineItem, "flip_down"); // extra animation name or clip name
ThirdPersonAnimations.stop(entityId); // fades it out early
A pose started this way wins over the held items’ paired clips until it ends.
Armor hooks
PackEngineArmorApi lets a mod extend pack armor. Register from your mod constructor, before packs
are read.
| Method | What it does |
|---|---|
registerExtension("mymod", reader) |
An armor file may have a "mymod": { ... } block. Your reader parses it, and you get it back with definition.extension("mymod", Type.class). Fields nobody reads are logged as warnings, so typos show up. |
registerSection("my_folder", reader) |
A pack may have extra folders next to items/ and armor/, and your reader gets every .json file in them. Sections are read before items and armor, so those can refer to data a section defines. Fracture Point’s plate tiers work this way. |
registerPackExtension("mymod", reader) |
A block of your own in pack.json, read after the pack’s items and armor. |
addBehavior(behavior) |
Gameplay for pack armor without owning the item class: right-click use, clicking items onto the piece, tooltip lines and tooltip images. |
PackEngineArmorClientApi adds client-side render hooks, extra worn stacks for accessory slots, and
skin layer rules.