Repository navigation
API Animation Groups
The Animation Group system allows existing animations to be parameterized according to their animation inheritance without creating a "new animation object".
Animation groups describe how a JSON definition should be interpreted based on the type of animation it targets.
Unlike [Animation Accessors], groups do not construct animations. Instead, they operate on existing animations and treat them according to their inheritance hierarchy.
For example, an animation belonging to an attack group can accept properties applicable to attack animations, as well as properties inherited from its parent animation types.
ExtendedDatapacksRegistry
│
▼
IAnimationGroupType
│
├──────────────────────┐
▼ ▼
Virtualization Definition Config Definition
│ │
▼ ▼
IAnimationVirtualization IAnimationConfig
│ │
▼ ▼
Existing Animation Existing Animation
An animation group provides two independent definitions:
- A configuration definition, used to modify an existing animation.
- A virtualization definition, used to create a virtual representation of an existing animation.
Both definitions are associated with the same animation group type.
Animation groups are based on the inheritance hierarchy of Epic Fight animations.
Conceptually:
StaticAnimation
│
└── ActionAnimation
│
└── AttackAnimation
A group represents one point in this hierarchy.
For example:
STATIC_GROUP
│
▼
StaticAnimation
ATTACK_GROUP
│
▼
ActionAnimation
│
▼
AttackAnimation
Therefore, an animation belonging to an attack group can accept properties applicable to:
- Static animations.
- Action animations.
- Attack animations.
A static animation, on the other hand, only accepts properties applicable to the static level of the hierarchy.
This allows animation JSON to remain generic while still respecting the capabilities of the underlying animation type.
Animation groups implement:
IAnimationGroupTypeA group type defines:
- Its unique identifier.
- Its virtualization definition codec.
- Its configuration definition codec.
public enum EpicFightAnimationGroups
implements IAnimationGroupType {
STATIC_GROUP(
"epicfight_edp:static_group",
new AnimationVirtualizationDefinitionCodec<>(
VirtualStaticAnimationGroup.CODEC,
StaticAnimationProperties.CODEC
),
new AnimationConfigDefinitionCodec<>(
ConfigStaticAnimationGroup.CODEC,
StaticAnimationProperties.CODEC
)
),
ATTACK_GROUP(
"epicfight_edp:attack_group",
new AnimationVirtualizationDefinitionCodec<>(
VirtualActionAnimationGroup.CODEC,
ActionAnimationProperties.CODEC
),
new AnimationConfigDefinitionCodec<>(
ConfigActionAnimationGroup.CODEC,
ActionAnimationProperties.CODEC
)
),
ACTION_GROUP(
"epicfight_edp:action_group",
new AnimationVirtualizationDefinitionCodec<>(
VirtualAttackAnimationGroup.CODEC,
AttackAnimationProperties.CODEC
),
new AnimationConfigDefinitionCodec<>(
ConfigAttackAnimationGroup.CODEC,
AttackAnimationProperties.CODEC
)
);
private final String id;
private final AnimationVirtualizationDefinitionCodec<?> virtualDefinitionCodec;
private final AnimationConfigDefinitionCodec<?> configDefinitionCodec;
EpicFightAnimationGroups(
String id,
AnimationVirtualizationDefinitionCodec<?> virtualDefinitionCodec,
AnimationConfigDefinitionCodec<?> configDefinitionCodec) {
this.id = id;
this.virtualDefinitionCodec = virtualDefinitionCodec;
this.configDefinitionCodec = configDefinitionCodec;
}
@Override
public String id() {
return id;
}
@Override
public AnimationVirtualizationDefinitionCodec<?> virtualDefinitionCodec() {
return virtualDefinitionCodec;
}
@Override
public AnimationConfigDefinitionCodec<?> configDefinitionCodec() {
return configDefinitionCodec;
}
}The group identifier is explicitly defined through:
String id()For example:
epicfight_edp:static_group
epicfight_edp:attack_group
epicfight_edp:action_group
Configuration definitions implement:
IAnimationConfig<T>They operate on an existing animation.
They do not create a new animation instance.
public record ConfigStaticAnimationGroup(
ResourceLocation animation
) implements IAnimationConfig<StaticAnimation> {
public static final MapCodec<ConfigStaticAnimationGroup> CODEC =
RecordCodecBuilder.mapCodec(instance ->
instance.group(
ResourceLocation.CODEC
.fieldOf("animation")
.forGetter(ConfigStaticAnimationGroup::animation)
).apply(instance, ConfigStaticAnimationGroup::new)
);
@Override
public IAnimationGroupType groupType() {
return EpicFightAnimationGroups.STATIC_GROUP;
}
@Override
public void applyConfig(
IAnimationProperties<StaticAnimation> property) {
if (this.isInvalidAccessor()) return;
var animation = getAccessor().get();
property.applyTo(animation);
this.isSuccessful();
}
}The configuration definition identifies an existing animation:
{
"animation": "..."
}and then applies the decoded properties to that animation.
The important distinction is that the animation already exists.
Virtualization definitions implement:
IAnimationVirtualization<T>They also operate on existing animations, but instead of modifying the original animation directly, they describe a virtual animation based on an existing one.
public record VirtualStaticAnimationGroup(
ResourceLocation realAnimation,
ResourceLocation virtualAnimation
) implements IAnimationVirtualization<StaticAnimation> {
public static final MapCodec<VirtualStaticAnimationGroup> CODEC =
RecordCodecBuilder.mapCodec(instance ->
instance.group(
ResourceLocation.CODEC
.fieldOf("real_animation")
.forGetter(VirtualStaticAnimationGroup::realAnimation),
ResourceLocation.CODEC
.fieldOf("virtual_animation")
.forGetter(VirtualStaticAnimationGroup::virtualAnimation)
).apply(instance, VirtualStaticAnimationGroup::new)
);
@Override
public IAnimationGroupType groupType() {
return EpicFightAnimationGroups.STATIC_GROUP;
}
}A virtualization definition therefore establishes a relationship between:
real animation
│
▼
virtual animation
The virtual animation can then receive additional configuration while retaining the behavior and inheritance characteristics of the underlying animation.
Animation groups are registered through the centralized:
ExtendedDatapacksRegistryusing:
ANIMATION_GROUPExtendedDatapacksRegistry.ANIMATION_GROUP.register(
MOD_ID,
EpicFightAnimationGroups.class
);Multiple enum classes can be registered in a single call:
ExtendedDatapacksRegistry.ANIMATION_GROUP.register(
MOD_ID,
EpicFightAnimationGroups.class,
CustomAnimationGroups.class
);The registry automatically verifies that every supplied enum implements:
IAnimationGroupTypeInvalid classes are rejected and a warning is emitted to the log.
A configuration definition uses an existing animation as its target.
For example:
{
"type": "attack_group",
"animation": "epicfight:biped/skill/battojutsu_dash",
"in_time_events": [
{
"type": "epicfight_edp:thunder",
"side": "server",
"start": 1.0
}
]
}Here:
"type": "attack_group"selects the animation group.
The:
"animation": "epicfight:biped/skill/battojutsu_dash"field identifies the existing animation that will receive the configuration.
The remaining fields are interpreted according to the properties supported by that animation group.
Virtualization definitions use two animation identifiers:
{
"type": "attack_group",
"real_animation": "epicfight:biped/skill/battojutsu",
"virtual_animation": "new_epicfight:biped/skill/battojutsu",
"in_time_events": [
{
"type": "teleport",
"side": "server",
"start": 0.15,
"params": {
"offset": [0, 0, 0],
"mode": "target_front"
}
}
]
}The:
"real_animation"identifies the existing animation.
The:
"virtual_animation"defines the new identifier under which the virtualized animation can be referenced.
The virtualized animation can then receive additional properties and events without requiring the creation of a new concrete DynamicAnimation implementation.
The two group operations serve different purposes.
Existing Animation
│
▼
Apply Properties
│
▼
Modified Existing Animation
A configuration definition references an animation and applies properties to it.
Existing Animation
│
▼
Virtual Definition
│
├── real_animation
│
└── virtual_animation
│
▼
Virtual Animation Reference
A virtualization definition creates an additional virtual representation of an existing animation.
The most important distinction between Animation Accessors and Animation Groups is how they interact with animations.
Accessors create an animation:
JSON
│
▼
Accessor
│
▼
new DynamicAnimation(...)
│
▼
Registered Animation
An accessor therefore defines how an animation object is constructed.
Groups do not create the underlying animation:
JSON
│
▼
Group
│
▼
Existing Animation
│
▼
Treat according to its inheritance
They operate on an existing animation and determine which property definitions are valid according to its inheritance level.
This distinction allows a single group definition to work with the capabilities inherited by the target animation.
Suppose the animation hierarchy is:
StaticAnimation
│
└── ActionAnimation
│
└── AttackAnimation
A group associated with AttackAnimation can expose properties from the complete applicable hierarchy:
Attack Group
│
├── Static properties
├── Action properties
└── Attack properties
While a static group only exposes:
Static Group
│
└── Static properties
This is why the group definition associates a group with a specific property codec:
new AnimationConfigDefinitionCodec<>(
ConfigActionAnimationGroup.CODEC,
ActionAnimationProperties.CODEC
)or:
new AnimationConfigDefinitionCodec<>(
ConfigAttackAnimationGroup.CODEC,
AttackAnimationProperties.CODEC
)The same principle applies to virtualization definitions.
Animation groups must be registered before Extended Datapacks initializes and consumes its animation registries.
Attempting to register an animation group after the registry has been consumed will throw:
RegistryObjectException
Registration should therefore occur during mod initialization:
private static void registerAnimationGroups() {
ExtendedDatapacksRegistry.ANIMATION_GROUP.register(
MOD_ID,
EpicFightAnimationGroups.class
);
}A third-party mod can define its own animation group by providing:
- A group enum implementing
IAnimationGroupType. - A configuration definition implementing
IAnimationConfig<T>. - A virtualization definition implementing
IAnimationVirtualization<T>. - The corresponding codecs.
- Registration through
ExtendedDatapacksRegistry.ANIMATION_GROUP.
Conceptually:
IAnimationGroupType
│
┌──────────────┴──────────────┐
▼ ▼
Config Definition Virtualization Definition
│ │
▼ ▼
IAnimationConfig<T> IAnimationVirtualization<T>
│ │
└──────────────┬──────────────┘
▼
Existing Animation
- Animation groups implement
IAnimationGroupType. - Groups operate on existing animations rather than constructing new animation objects.
- Configuration definitions implement
IAnimationConfig<T>. - Virtualization definitions implement
IAnimationVirtualization<T>. - Every group provides both a configuration definition codec and a virtualization definition codec.
- Group identifiers are explicitly defined through
IAnimationGroupType.id(). - Register group enum classes through
ExtendedDatapacksRegistry.ANIMATION_GROUP. - Multiple group enum classes can be registered in a single call.
- The applicable property set is determined by the animation group's position in the animation inheritance hierarchy.
- A more specialized animation group can expose properties belonging to its inherited animation types.
- Configuration definitions modify an existing animation.
- Virtualization definitions establish a virtual representation of an existing animation.
EF: Extended Datapacks
📦 Data
🧰 Core
👁️ Visuals
- Zoom Types
- Weapon Models per Style
- Advanced Swing Trails
- Weapons Passive Particles
- Shader Effects I
- Shader Effects II
- Shader Effects III
⚔️ Combat
🗝️ Skill Builder
🛠️ Innate Builder
- Simple Innate Skills
- Holdable Innate Skills
- Conditional Innate Skills
- Conditional Data Innate Skills
- Conditional Holdable Innate Skills
- Sequential Innate Skills
- Per Combo Innate Skills
- Combo Innate Skills
🗡️ Animation Operations
- Animation Operations
- Animation Properties
⚙️ Third-Party