For Developers/Cultivation API·匠

Cultivation API

Cultivation ships a public integration surface for other Hytale mods: plugin.siren.API.CultivationAPI plus fifty-one *Events classes in the same package. It is the intended stable shape of the mod - prefer it over reaching into CultivationManager, Cultivation or the ECS components directly, since those are free to change between versions.

There are four things you can do with it:

This page documents the API as of Cultivation 0.11.0, the current release. Where a method or event arrived after 0.5.0, the page that describes it says which version.

The sources are published. Every public API class, with its javadoc, lives at github.com/SirenHytale/Cultivation-API — alongside a generated reference for every event, a worked example add-on, and a brief written for AI coding assistants. The javadoc in those sources is the authoritative contract; this wiki is the guided tour.

Adding Cultivation to your project

Cultivation 0.11.0 is built for Hytale Update 7 (Server API 0.7.0-pre.5.1, ServerVersion: >=0.7.0-pre.0 <0.8.0) and Java 25, so an addon compiling against it needs the same. Cultivation is not on a public Maven repository: install the released jar into your local one first, then depend on it with provided scope and never shade it into your own jar. The server loads the real Cultivation jar, and two copies of plugin.siren.Cultivation on the classpath would each get their own static plugin instance - so every registry call would go into the copy nobody reads, silently.

mvn install:install-file -Dfile=Cultivation-0.11.0.jar -DgroupId=plugin.siren -DartifactId=Cultivation -Dversion=0.11.0 -Dpackaging=jar

Maven pom.xml:

<repositories>
    <repository>
        <id>hytale-release</id>
        <url>https://maven.hytale.com/release</url>
    </repository>
    <repository>
        <id>hytale-pre-release</id>
        <url>https://maven.hytale.com/pre-release</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.hypixel.hytale</groupId>
        <artifactId>Server</artifactId>
        <version>0.7.0-pre.5.1</version>
    </dependency>
    <dependency>
        <groupId>plugin.siren</groupId>
        <artifactId>Cultivation</artifactId>
        <version>0.11.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Then declare it in your Hytale manifest.json. Cultivation's own manifest publishes itself as group Siren, name Cultivation, so the dependency id is Siren:Cultivation. Every first-party add-on released with 0.11.0 declares a floor of 0.11.0:

"Dependencies": {
  "Siren:Cultivation": ">=0.11.0"
}

A manifest range accepts a full semver range rather than only a floor - ">=0.11.0 <0.12.0" makes the engine refuse to load your addon against any Cultivation outside that band, before a line of your code runs. If you would rather integrate only when Cultivation happens to be installed, put the same entry under "OptionalDependencies" instead, and keep every reference to a plugin.siren class behind a guard so the classes never load without it. See Compatibility for the published compatibility list that corrects a pairing after both jars have shipped.

The entry point

Everything is static. CultivationAPI has a private constructor and is never instantiated - you call it straight off the class:

import plugin.siren.API.CultivationAPI;
import plugin.siren.ECS.Realms.CultivationRealm;

CultivationRealm realm = CultivationAPI.getRealm(accessor, ref);
float qi = CultivationAPI.getQi(accessor, ref);

The read methods all take a ComponentAccessor<EntityStore> and a Ref<EntityStore> - the same pair every Hytale ECS system already has in hand. Anything that reads a component returns null (or 0, or Human) when the player does not have that component yet, so a fresh player never throws.

Listener and registry calls are safe from your own plugin's setup() in any load order relative to Cultivation's own setup(). The registries are plain static maps and the listener lists are CopyOnWriteArrayLists; nothing reads either until a player actually interacts with the mod, which is long after every plugin has finished loading.

Your first listener

The pattern is CultivationEvents.onPreX(...) to change or veto something before it happens, and CultivationEvents.onX(...) to be told once it is committed. Both take a java.util.function.Consumer of the event type, so a lambda is all you need:

import com.hypixel.hytale.server.core.universe.PlayerRef;
import plugin.siren.API.CultivationEvents;
import plugin.siren.ECS.Realms.CultivationRealm;

public final class MyCultivationHooks {

    public static void register(){
        // Make the jump into Golden Core Formation cost twice as much banked Qi.
        CultivationEvents.onPreBreakthrough(event -> {
            if(event.toRealm() == CultivationRealm.GOLDEN_CORE_FORMATION){
                event.setQiCost(event.qiCost() * 2.0F);
            }
        });

        // Refuse the very last realm outright.
        CultivationEvents.onPreBreakthrough(event -> {
            if(event.toRealm() == CultivationRealm.VOID_REFINEMENT){
                event.setCancelled(true);
            }
        });

        // React once it has actually happened - the component already shows the new realm.
        CultivationEvents.onBreakthrough(event -> {
            if(event.player() != null){
                recordAscension(event.player(), event.newRealm());
            }
        });
    }

    private static void recordAscension(PlayerRef player, CultivationRealm realm){
        // your own bookkeeping here
    }
}

Call MyCultivationHooks.register() from your plugin's setup(). There is deliberately no unregister - a listener's lifetime is the server's lifetime, matching how plugins load once and stay.

Pages

PageCovers
API EventsAll 370 events in the 51 *Events classes, grouped by subsystem: when each fires, whether it can be cancelled, what it exposes, and the locking and threading rules that apply.
API RegistriesAll 30 register* methods - races, techniques and their gates, menu pages, Codex entries, update, build and compat checks, palettes, auras, titles, banners, standing modifiers, store benefits, the caps - and the public types they use.
API ReferenceEvery one of the 261 CultivationAPI methods by family, and the 50 CultivationConfigs accessors.
API AddonsProgressionProvider (every method you implement, with a complete example), CultivationTheme and AdminConfigSection - replacing the ladder, the wording, and adding your own admin settings.

Player-facing documentation for the systems these hooks sit on top of lives on the main wiki: Cultivation Realms, Qi Gathering, The Dao, Techniques, Sects, Sect Wars, Formations, Cave Abodes, Duels and Spirit Beasts. Every number an event lets you re-tune also has a server-owner-facing equivalent on the Config page, and most of them mirror something on the Commands page.