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 behavioursData pack
A new power type with custom logicPowerType subclass
A new action or conditionEntityAction, EntityCondition, … factories
A new data type usable from JSONA Codec + registration
Compat with another modA 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:

  1. depends on Apoli at build and runtime,
  2. registers its power types, actions and conditions during mod init,
  3. 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 mavenLocal and rebuild with --refresh-dependencies.

Next

Reference map

TopicPage
Power typesRegistering power types
Actions & conditionsActions & conditions
ContextsContexts
Legacy JSONAliasing
Custom value typesCustom data types
Where powers liveThe power container
Saved stateAux & persistence
Client syncNetworking
Math fieldsExpressions
Hot-path rulesPerformance
Other-mod supportCompatibility
Loader/version gapsLoaders & versions