Overview
What the Apoli API is, and when you need Java instead of JSON.
Most powers can be built in a data pack — no code required. You only need the Java API when JSON runs out of road: a genuinely new kind of power, a new action or condition, or a hook into game internals that no existing type exposes.
This side of the docs is for mod authors writing an Apoli addon. Origins is the canonical example: it’s a mod that depends on Apoli and registers its own types on top.
When to reach for Java
| You want to… | Use |
|---|---|
| Combine existing behaviours | Data pack |
| A new power type with custom logic | PowerType subclass |
| A new action or condition | EntityAction, EntityCondition, … factories |
| A new data type usable from JSON | A Codec + registration |
| Compat with another mod | A gated compat module |
If your idea is a rearrangement of things Apoli already does, stay in JSON — it’s faster and needs no build.
How an addon is shaped
An Apoli addon is an ordinary Fabric/NeoForge mod that:
- depends on Apoli at build and runtime,
- registers its power types, actions and conditions during mod init,
- optionally ships a data pack of its own powers.
Package layout follows Apoli’s own convention — everything under dev.<you>.<modid>:
dev/example/mymod/
├── MyMod.java // entrypoint: registers everything
├── power/ // PowerType subclasses
├── action/ // action factories
└── condition/ // condition factories Depending on Apoli
Apoli is published per loader and Minecraft version, so the coordinate is qualified. Add the dependency in build.gradle:
repositories {
mavenLocal() // if you build Apoli yourself
}
dependencies {
// fabric, 1.21.1 — match your loader and MC version
modImplementation "dev.overgrown:apoli-fabric-1.21.1:${apoli_version}"
} Then declare it in fabric.mod.json (or the NeoForge equivalent) so the game enforces it:
{
"depends": {
"apoli": ">=1.5.0"
}
} Building against a stale local copy is the single most common addon bug. If Apoli changes and your addon can’t see it, republish Apoli to
mavenLocaland rebuild with--refresh-dependencies.
Next
- Getting started — set up a project and register your first type.
- Registering power types — the core of an addon.
- Contexts — how you reach the entity, level and target.
- Performance — the rules for code on a live server.
Reference map
| Topic | Page |
|---|---|
| Power types | Registering power types |
| Actions & conditions | Actions & conditions |
| Contexts | Contexts |
| Legacy JSON | Aliasing |
| Custom value types | Custom data types |
| Where powers live | The power container |
| Saved state | Aux & persistence |
| Client sync | Networking |
| Math fields | Expressions |
| Hot-path rules | Performance |
| Other-mod support | Compatibility |
| Loader/version gaps | Loaders & versions |