Hytale Server API - Plugin System

PluginBase

Location: com/hypixel/hytale/server/core/plugin/PluginBase.java

Fields:

FieldTypeDescription
loggerHytaleLoggerPlugin logger
identifierPluginIdentifierUnique identifier (group:name)
manifestPluginManifestPlugin manifest
dataDirectoryPathData directory path
configsList<Config>Configuration files
statePluginStateCurrent lifecycle state
shutdownTasksCopyOnWriteArrayListShutdown callbacks
basePermissionStringBase permission node

Registries:

FieldTypeDescription
clientFeatureRegistryClientFeatureRegistryClient features
commandRegistryCommandRegistryCommands
eventRegistryEventRegistryEvent listeners
blockStateRegistryBlockStateRegistryBlock states
entityRegistryEntityRegistryEntity types
taskRegistryTaskRegistryScheduled tasks
entityStoreRegistryComponentRegistryProxyEntity components
chunkStoreRegistryComponentRegistryProxyChunk components
assetRegistryAssetRegistryAsset stores
codecMapRegistriesMap<Codec, IRegistry>Codec registries

Lifecycle Methods:

protected void setup();      // Override for setup logic
protected void start();      // Override for start logic
protected void shutdown();   // Override for cleanup

Configuration Methods:

<T> Config<T> withConfig(BuilderCodec<T> configCodec)
<T> Config<T> withConfig(String name, BuilderCodec<T> configCodec)
CompletableFuture<Void> preLoad()

Getter Methods:

HytaleLogger getLogger()
PluginIdentifier getIdentifier()
PluginManifest getManifest()
Path getDataDirectory()
PluginState getState()
boolean isEnabled()
boolean isDisabled()

JavaPlugin

Location: com/hypixel/hytale/server/core/plugin/JavaPlugin.java

Extends PluginBase for JAR-based plugins.

Fields:

FieldTypeDescription
filePathJAR file path
classLoaderPluginClassLoaderPlugin class loader

Methods:

Path getFile()
PluginClassLoader getClassLoader()
PluginType getType()  // Returns PluginType.PLUGIN

PluginState

Location: com/hypixel/hytale/server/core/plugin/PluginState.java

StateDescription
NONEInitial state
SETUPSetup phase executing
STARTStart phase executing
ENABLEDFully operational
SHUTDOWNShutdown phase executing
DISABLEDStopped/disabled

Lifecycle Flow:

NONE → SETUP → START → ENABLED → SHUTDOWN → DISABLED

PluginManifest

Location: com/hypixel/hytale/common/plugin/PluginManifest.java

Fields:

FieldTypeDescription
groupStringPlugin group/namespace
nameStringPlugin name
versionSemverSemantic version
descriptionStringPlugin description
authorsListAuthor information
websiteStringPlugin website URL
mainStringMain class (fully qualified)
serverVersionSemverRangeRequired server version
dependenciesMap<PluginIdentifier, SemverRange>Required dependencies
optionalDependenciesMap<PluginIdentifier, SemverRange>Optional dependencies
loadBeforeMap<PluginIdentifier, SemverRange>Load ordering
subPluginsListSub-plugin definitions
disabledByDefaultbooleanDisabled by default
includesAssetPackbooleanContains asset pack

Constants:

  • CORE_GROUP = "Hytale"
  • CORE_VERSION - Server version

JSON Format:

{
    "Group": "namespace",
    "Name": "pluginname",
    "Version": "1.0.0",
    "Description": "Plugin description",
    "Authors": [{ "Name": "Author", "Email": "email", "Url": "website" }],
    "Website": "https://example.com",
    "Main": "com.example.plugin.MainClass",
    "ServerVersion": "*",
    "Dependencies": { "group:plugin": "1.0.0" },
    "OptionalDependencies": { "group:optional": "*" },
    "LoadBefore": { "group:other": "*" },
    "SubPlugins": [],
    "DisabledByDefault": false,
    "IncludesAssetPack": true
}

AuthorInfo

Location: com/hypixel/hytale/common/plugin/AuthorInfo.java

Fields:

FieldType
nameString
emailString
urlString

PluginIdentifier

Location: com/hypixel/hytale/common/plugin/PluginIdentifier.java

Fields:

FieldType
groupString
nameString

Methods:

String toString()  // Returns "group:name"
static PluginIdentifier fromString(String str)  // Parse "group:name"

PluginManager

Location: com/hypixel/hytale/server/core/plugin/PluginManager.java

Fields:

FieldTypeDescription
MODS_PATHPathMods directory path
instancePluginManagerSingleton instance
loadOrderListPlugin load order
loadingMap<PluginIdentifier, PluginBase>Plugins loading
corePluginClassLoaderPluginClassLoaderCore class loader
corePluginsListCore plugins
bridgeClassLoaderPluginBridgeClassLoaderBridge class loader
lockReentrantReadWriteLockThread-safe access
pluginsMap<PluginIdentifier, PluginBase>Loaded plugins
classLoadersMap<Path, PluginClassLoader>Class loaders
loadExternalPluginsbooleanLoad external plugins
statePluginStateManager state
availablePluginsMap<PluginIdentifier, PluginManifest>Available plugins

Core Methods:

static PluginManager get()
void registerCorePlugin(PluginManifest builder)
void setup() throws URISyntaxException, IOException
void start()
void shutdown()

Plugin Access:

List<PluginBase> getPlugins()
PluginBase getPlugin(PluginIdentifier identifier)
boolean hasPlugin(PluginIdentifier identifier, SemverRange range)
Map<PluginIdentifier, PluginManifest> getAvailablePlugins()

Plugin Loading:

boolean load(PluginIdentifier identifier)
boolean load(PendingLoadPlugin pendingLoadPlugin)
boolean findAndLoadPlugin(PluginIdentifier identifier)
static PluginManifest loadManifest(Path file)

Plugin Control:

boolean reload(PluginIdentifier identifier)
boolean unload(PluginIdentifier identifier)
void unloadJavaPlugin(JavaPlugin plugin)

Dependency Validation:

void validatePluginDeps(PendingLoadPlugin plugin, Map<PluginIdentifier, PendingLoadPlugin> pending)
boolean dependenciesMatchState(PluginBase plugin, PluginState requiredState, PluginState stage)

PluginClassLoader

Location: com/hypixel/hytale/server/core/plugin/PluginClassLoader.java

Extends URLClassLoader.

Fields:

FieldTypeDescription
THIRD_PARTY_LOADER_NAMEString“ThirdPartyPlugin”
pluginManagerPluginManagerManager reference
inServerClassPathbooleanIs builtin plugin
pluginJavaPluginAssociated plugin

Methods:

boolean isInServerClassPath()
void setPlugin(JavaPlugin plugin)
Class<?> loadClass(String name, boolean resolve)
Class<?> loadClass0(String name, boolean useBridge)
Class<?> loadLocalClass(String name)
URL getResource(String name)
Enumeration<URL> getResources(String name)
static boolean isFromThirdPartyPlugin(Throwable throwable)

Class Resolution Order:

  1. Server classpath
  2. Plugin’s own JAR
  3. Bridge classloader (dependencies)

PluginBridgeClassLoader

Inner class of PluginManager.

Extends ClassLoader to enable inter-plugin class access with dependency respect.

Methods:

Class<?> loadClass0(String name, PluginClassLoader pluginClassLoader)
Class<?> loadClass0(String name, PluginClassLoader pluginClassLoader, PluginManifest manifest)
URL getResource0(String name, PluginClassLoader pluginClassLoader)
Enumeration<URL> getResources0(String name, PluginClassLoader pluginClassLoader)

PluginInit

Location: com/hypixel/hytale/server/core/plugin/PluginInit.java

Fields:

FieldType
pluginManifestPluginManifest
dataDirectoryPath

Methods:

PluginManifest getPluginManifest()
Path getDataDirectory()
boolean isInServerClassPath()  // Returns true

JavaPluginInit

Location: com/hypixel/hytale/server/core/plugin/JavaPluginInit.java

Extends PluginInit.

Fields:

FieldType
filePath
classLoaderPluginClassLoader

Methods:

Path getFile()
PluginClassLoader getClassLoader()
boolean isInServerClassPath()  // Delegates to classLoader

EventRegistry

Location: com/hypixel/hytale/event/EventRegistry.java

Extends Registry<EventRegistration<?, ?>> and implements IEventRegistry.

Registration Methods:

// Simple registration
<EventType extends IBaseEvent<Void>> EventRegistration<Void, EventType> register(
    Class<? super EventType> eventClass,
    Consumer<EventType> consumer
)

// With priority
<EventType extends IBaseEvent<Void>> EventRegistration<Void, EventType> register(
    EventPriority priority,
    Class<? super EventType> eventClass,
    Consumer<EventType> consumer
)

// With key
<KeyType, EventType extends IBaseEvent<KeyType>> EventRegistration<KeyType, EventType> register(
    Class<? super EventType> eventClass,
    KeyType key,
    Consumer<EventType> consumer
)

// Global (all events of type)
<KeyType, EventType extends IBaseEvent<KeyType>> EventRegistration<KeyType, EventType> registerGlobal(...)

// Async variants
<EventType extends IAsyncEvent<Void>> EventRegistration<Void, EventType> registerAsync(...)
<KeyType, EventType extends IAsyncEvent<KeyType>> EventRegistration<KeyType, EventType> registerAsyncGlobal(...)

// Unhandled (fallback)
<KeyType, EventType extends IBaseEvent<KeyType>> EventRegistration<KeyType, EventType> registerUnhandled(...)

EventPriority

Location: com/hypixel/hytale/event/EventPriority.java

PriorityValueDescription
FIRST-21844Highest priority
EARLY-10922Early
NORMAL0Default
LATE10922Late
LAST21844Lowest priority

CommandRegistry

Location: com/hypixel/hytale/server/core/command/system/CommandRegistry.java

Extends Registry<CommandRegistration>.

Methods:

CommandRegistration registerCommand(AbstractCommand command)

TaskRegistry

Location: com/hypixel/hytale/server/core/task/TaskRegistry.java

Extends Registry<TaskRegistration>.

Methods:

TaskRegistration registerTask(CompletableFuture<Void> task)
TaskRegistration registerTask(ScheduledFuture<Void> task)

Scheduled Task Example (using HytaleServer.SCHEDULED_EXECUTOR):

import com.hypixel.hytale.server.core.HytaleServer;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

private ScheduledFuture<?> tickTask;

@Override
protected void start() {
    // Schedule a recurring task every 500ms
    tickTask = HytaleServer.SCHEDULED_EXECUTOR.scheduleAtFixedRate(
        this::onTick,
        1000,  // initial delay
        500,   // period
        TimeUnit.MILLISECONDS
    );
}

@Override
protected void shutdown() {
    if (tickTask != null) {
        tickTask.cancel(false);
    }
}

private void onTick() {
    // Task logic here
}

EntityRegistry

Location: com/hypixel/hytale/server/core/modules/entity/EntityRegistry.java

Extends Registry<EntityRegistration>.

Methods:

<T extends Entity> EntityRegistration registerEntity(
    String key,
    Class<T> clazz,
    Function<World, T> constructor,
    DirectDecodeCodec<T> codec
)

AssetRegistry

Location: com/hypixel/hytale/server/core/plugin/registry/AssetRegistry.java

Methods:

<K, T extends JsonAssetWithMap<K, M>, M extends AssetMap<K, T>, S extends AssetStore<K, T, M>>
AssetRegistry register(S assetStore)

CodecMapRegistry

Location: com/hypixel/hytale/server/core/plugin/registry/CodecMapRegistry.java

Implements IRegistry.

Methods:

CodecMapRegistry<T, C> register(String id, Class<? extends T> aClass, C codec)
CodecMapRegistry<T, C> register(Priority priority, String id, Class<? extends T> aClass, C codec)

Inner Class Assets:

Assets<T, C> register(String id, Class<? extends T> aClass, BuilderCodec<? extends T> codec)
Assets<T, C> register(Priority priority, String id, Class<? extends T> aClass, BuilderCodec<? extends T> codec)

PendingLoadPlugin

Location: com/hypixel/hytale/server/core/plugin/pending/PendingLoadPlugin.java

Fields:

FieldType
identifierPluginIdentifier
manifestPluginManifest
pathPath

Abstract Methods:

PendingLoadPlugin createSubPendingLoadPlugin(PluginManifest pluginManifest)
PluginBase load()
boolean isInServerClassPath()

Static Methods:

static List<PendingLoadPlugin> calculateLoadOrder(Map<PluginIdentifier, PendingLoadPlugin> pending)

PendingLoadJavaPlugin

Location: com/hypixel/hytale/server/core/plugin/pending/PendingLoadJavaPlugin.java

Extends PendingLoadPlugin.

Fields:

FieldType
urlClassLoaderPluginClassLoader

Methods:

JavaPlugin load()  // Instantiates main class with JavaPluginInit

Plugin Events

PluginEvent

Location: com/hypixel/hytale/server/core/plugin/event/PluginEvent.java

Implements IEvent<Class<? extends PluginBase>>.

Fields:

FieldType
pluginPluginBase

PluginSetupEvent

Location: com/hypixel/hytale/server/core/plugin/event/PluginSetupEvent.java

Extends PluginEvent. Fired during plugin setup phase.


PluginType

Location: com/hypixel/hytale/server/core/plugin/PluginType.java

ValueDisplay Name
PLUGIN“Plugin”

Complete Example

manifest.json:

{
    "Group": "momo",
    "Name": "voidstorage",
    "Version": "1.0.0",
    "Description": "Void storage mod",
    "Main": "net.momo.voidstorage.VoidStoragePlugin",
    "ServerVersion": "*",
    "IncludesAssetPack": true
}

Plugin Class:

import java.util.logging.Level;

public class VoidStoragePlugin extends JavaPlugin {
    private static VoidStoragePlugin instance;

    public VoidStoragePlugin(JavaPluginInit init) {
        super(init);
        instance = this;
    }

    @Override
    protected void setup() {
        // Register global event listener (receives all events of this type)
        getEventRegistry().registerGlobal(
            PlayerConnectEvent.class,
            event -> getLogger().at(Level.INFO).log("Player connected: %s", event.getPlayerRef().getUsername())
        );

        // Register command
        getCommandRegistry().registerCommand(new VoidStatusCommand());
    }

    @Override
    protected void start() {
        getLogger().at(Level.INFO).log("Plugin started");
    }

    @Override
    protected void shutdown() {
        getLogger().at(Level.INFO).log("Plugin shutting down");
    }

    public static VoidStoragePlugin getInstance() {
        return instance;
    }
}