Repository navigation
Combo Innate Skills
Combo Innate Skills are designed for advanced combat abilities that require multiple possible animation paths.
Unlike Sequential Innate Skills, which always progress through a fixed list, Combo Innate Skills use a node-based system to create branching combinations.
The system can be understood as a small animation state tree:
- Entry points act as the roots of the tree.
- Nodes represent individual steps of a combo.
- Next nodes determine what can happen after the current node.
- Conditions determine whether a transition can be followed.
- Global entry points can interrupt the current route and start another one.
This allows complex combinations to be described entirely through JSON without creating a separate skill for every possible combination.
Depending on whether you want users to be able to modify the skills locally or bundle them inside your mod, choose one of the following paths:
Use this path if you want the setup to be easily accessible and editable by servers or pack developers.
-
Path:
.minecraft/config/epicfight_edp/innate_skill_builder/combo_innate_skill/*.json ⚠️ Rule: You MUST explicitly declare themodidfield inside the JSON when using this folder.
Use this path to ship skills natively pre-configured inside your mod jar or data-driven setup.
-
Path:
data_driven/<your_modid>/innate_skill_builder/combo_innate_skill/*.json - 💡 Rule: The
modidfield can be safely omitted inside the JSON because the directory's namespace acts as the fallback namespace automatically.
A Combo Innate Skill consists of two main structures:
Entry Points
│
▼
Nodes
│
▼
Next Nodes
│
▼
Next Nodes
│
...
The easiest way to visualize the system is as a tree or graph.
For example:
BASIC_1
│
▼
BASIC_2
│
▼
BASIC_3
/ \
▼ ▼
HOLD BASIC_1
When BASIC_1 is executed, the next valid node can be BASIC_2.
After BASIC_2, the next node is BASIC_3.
From BASIC_3, the combination can branch into different paths depending on the current condition.
Entry points are the roots of the combo system.
They define where a combination can begin.
"entry_points": [
{
"node": "BASIC_1",
"physical_condition": "normal"
},
{
"node": "AIR_1",
"physical_condition": "in_air",
"global": true
},
{
"node": "DASH",
"physical_condition": "sprinting",
"global": true
}
]Each entry point references a node by its ID.
Entry Point
│
▼
BASIC_1
The entry point itself does not contain the animation. Instead, it tells the system which node should be used as the starting point when its condition is satisfied.
| Field | Type | Description |
|---|---|---|
node |
String | ID of the node used as the entry point. |
physical_condition |
Condition | Physical state required to activate this entry point. |
global |
Boolean | Determines whether this entry point can interrupt another active combo route. |
Nodes are identified using strings.
"nodes": {
"BASIC_1": {
...
},
"BASIC_2": {
...
}
}The name itself has no special meaning.
You can use any identifier that makes sense for your combo:
AA1
AA2
AA3
BASIC_1
BASIC_2
BASIC_3
DASH
AIR_FINISHER
HEAVY_ATTACK
HEAVY_FINISHER
These strings effectively act as the IDs of the nodes.
For example:
{
"node": "BASIC_1"
}references:
"nodes": {
"BASIC_1": {
...
}
}A node represents an individual step in the combo.
At minimum, a node defines an animation:
"BASIC_1": {
"animation": "epicfight:biped/skill/rushing_tempo1"
}A node can optionally define one or more possible next nodes:
"BASIC_1": {
"animation": "epicfight:biped/skill/rushing_tempo1",
"next": [
{
"node": "BASIC_2"
}
]
}The next list defines the possible transitions from the current node.
| Field | Type | Description |
|---|---|---|
animation |
Resource Location | Animation executed by this node. |
next |
Array | Optional list of nodes that can follow the current node. |
A node can have multiple possible transitions.
For example:
"BASIC_3": {
"animation": "epicfight:biped/skill/rushing_tempo3",
"next": [
{
"node": "HOLD",
"physical_condition": "use_item"
},
{
"node": "BASIC_1"
}
]
}This creates two possible routes:
BASIC_3
/ \
/ \
use_item default
│ │
▼ ▼
HOLD BASIC_1
The transition containing physical_condition requires that condition to be satisfied.
| Field | Type | Description |
|---|---|---|
node |
String | ID of the node to transition to. |
physical_condition |
Condition | Optional condition required for this transition. |
A transition without a physical_condition can be used as the default route.
The main advantage of Combo Innate Skills is that a node does not have to lead to only one node.
For example:
"COMBO_3": {
"animation": "example:combo3",
"next": [
{
"node": "AIR_FINISHER",
"physical_condition": "in_air"
},
{
"node": "GROUND_FINISHER"
}
]
}The resulting structure is:
COMBO_3
/ \
/ \
In Air Default
│ │
▼ ▼
AIR_FINISHER GROUND_FINISHER
This allows the same combination to branch into different attacks depending on the player's state.
The global property changes how an entry point interacts with an already active combination.
{
"node": "AIR_1",
"physical_condition": "in_air",
"global": true
}A global entry point can be evaluated even when another combo route is currently active.
This means that a condition can effectively cancel the current route and start the global entry point's route.
For example:
BASIC_1
│
▼
BASIC_2
│
│ Player jumps
│
▼
AIR_1
│
▼
AIR_2
Without a global entry point, the currently active basic route could continue normally.
With:
{
"node": "AIR_1",
"physical_condition": "in_air",
"global": true
}the airborne condition can take priority and redirect the combo into the aerial route.
The distinction can be summarized as:
Normal Entry Point
│
└── Starts a route when the combo is available.
Global Entry Point
│
└── Can interrupt an already active route.
For example:
"entry_points": [
{
"node": "BASIC_1",
"physical_condition": "normal"
},
{
"node": "AIR_1",
"physical_condition": "in_air",
"global": true
}
]The basic route can begin normally:
BASIC_1 → BASIC_2 → BASIC_3
But if the player becomes airborne while the combo is active:
BASIC_1 → BASIC_2
│
│ jump
▼
AIR_1 → AIR_2
The global AIR_1 entry point can take over the combination.
Entry points and transitions can use physical conditions to determine whether a route is available.
The available conditions are:
| Condition | Description |
|---|---|
normal |
Default condition; player is alive. |
in_air |
Player is not on the ground. |
sprinting |
Player is sprinting. |
use_item |
Player is currently using an item. |
kneeling |
Player is holding the sneak key. |
These conditions allow the combo graph to react to the player's current state.
For example:
{
"node": "AIR_1",
"physical_condition": "in_air"
}requires the player to be airborne.
A complete Combo Innate Skill has the following general structure:
{
"modid": "epicfight",
"name": "combo_test",
"alwaysAllow": true,
"entry_points": [
{
"node": "BASIC_1",
"physical_condition": "normal"
}
],
"nodes": {
"BASIC_1": {
"animation": "example:attack1",
"next": [
{
"node": "BASIC_2"
}
]
},
"BASIC_2": {
"animation": "example:attack2"
}
}
}| Field | Type | Description |
|---|---|---|
modid |
String | The target mod namespace used to register the skill. |
name |
String | Unique internal identifier for the custom innate skill. |
alwaysAllow |
Boolean | Controls whether the skill is allowed independently of the normal skill activation restrictions (energy). |
tooltip |
Array | Optional list of custom tooltip components. |
entry_points |
Array | Defines the roots of the combo graph. |
nodes |
Object | Collection of all nodes referenced by the combo graph. |
Consider the following configuration:
{
"modid": "epicfight",
"name": "combo_test",
"alwaysAllow": true,
"entry_points": [
{ "node": "BASIC_1", "physical_condition": "normal" },
{ "node": "AIR_1", "physical_condition": "in_air", "global": true },
{ "node": "DASH", "physical_condition": "sprinting", "global": true}
],
"nodes": {
"BASIC_1": {
"animation": "epicfight:biped/skill/rushing_tempo1",
"next": [ { "node": "BASIC_2" } ]
},
"BASIC_2": {
"animation": "epicfight:biped/skill/rushing_tempo2",
"next": [ { "node": "BASIC_3" } ]
},
"BASIC_3": {
"animation": "epicfight:biped/skill/rushing_tempo3",
"next": [
{ "node": "HOLD", "physical_condition": "use_item" },
{ "node": "BASIC_1" }
]
},
"AIR_1": {
"animation": "epicfight:biped/combat/axe_airslash",
"next": [ { "node": "AIR_2", "physical_condition": "in_air" } ]
},
"AIR_2": {
"animation": "epicfight:biped/skill/heartpiercer"
},
"DASH": {
"animation": "epicfight:biped/skill/battojutsu_dash"
},
"HOLD": {
"animation": "epicfight:biped/skill/battojutsu"
}
}
}This creates a graph similar to:
┌──────────────┐
│ BASIC_1 │
└──────┬───────┘
│
▼
┌──────────────┐
│ BASIC_2 │
└──────┬───────┘
│
▼
┌──────────────┐
│ BASIC_3 │
└──────┬───────┘
/ \
use_item / \ default
▼ ▼
┌────────┐ ┌─────────┐
│ HOLD │ │ BASIC_1 │
└────────┘ └─────────┘
Global Entry Point
│
in_air
▼
┌──────────┐
│ AIR_1 │
└────┬─────┘
│
in_air
▼
┌──────────┐
│ AIR_2 │
└──────────┘
Global Entry Point
│
sprinting
▼
┌──────────┐
│ DASH │
└──────────┘
The important concept is that the nodes themselves form the combination, while the entry points determine where the combination can begin or, when global, where it can be redirected.
Suppose the player begins the skill normally.
The system starts at:
BASIC_1
The next activation advances to:
BASIC_2
Then:
BASIC_3
At BASIC_3, the player has two possible transitions:
BASIC_3
│
├── use_item → HOLD
│
└── default → BASIC_1
If the player is using an item, the combination becomes:
BASIC_1 → BASIC_2 → BASIC_3 → HOLD
Otherwise:
BASIC_1 → BASIC_2 → BASIC_3 → BASIC_1
Now consider the player jumping while the basic combination is active.
Because AIR_1 is a global entry point:
BASIC_1 → BASIC_2
│
│ player enters air
▼
AIR_1 → AIR_2
The current basic route is abandoned in favor of the aerial route.
A Combo Innate Skill is not simply a list of animations.
It is a collection of relationships between nodes.
Sequential Skill:
A → B → C → D
Combo Skill:
┌── B ──┐
│ │
A D
│ │
└── C ──┘
\
└── E
The sequential system describes what comes next.
The combo system describes what can come next depending on the current route and conditions.
This distinction is what makes Combo Innate Skills suitable for more complex combat systems.
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