Note: This document focuses on architecture and API structure. For practical code examples and complete manifest.json reference, see Plugin API Reference.
PluginBase (abstract, implements CommandOwner)
└── JavaPlugin (abstract)
└── YourPlugin (concrete)
Package: com.hypixel.hytale.server.core.plugin
public abstract class JavaPlugin extends PluginBase {
public JavaPlugin(@Nonnull JavaPluginInit init);
@Nonnull public Path getFile(); // Path to plugin JAR
@Nonnull public PluginClassLoader getClassLoader();
@Nonnull public final PluginType getType(); // Always PluginType.PLUGIN
}Provides all registries and lifecycle hooks.
protected void setup(); // Called first — register configs, initialize
protected void start(); // Called after setup — register commands, events, start logic
protected void shutdown(); // Called on disable — cleanup resourcesNONE → SETUP → START → ENABLED → SHUTDOWN → DISABLED
If setup/start throws, state moves to DISABLED.
@Nonnull public EventRegistry getEventRegistry();
@Nonnull public CommandRegistry getCommandRegistry();
@Nonnull public TaskRegistry getTaskRegistry();
@Nonnull public EntityRegistry getEntityRegistry();
@Nonnull public BlockStateRegistry getBlockStateRegistry();
@Nonnull public AssetRegistry getAssetRegistry();
@Nonnull public ClientFeatureRegistry getClientFeatureRegistry();
@Nonnull public ComponentRegistryProxy<EntityStore> getEntityStoreRegistry();
@Nonnull public ComponentRegistryProxy<ChunkStore> getChunkStoreRegistry();
@Nonnull public <T, C extends Codec<? extends T>> CodecMapRegistry<T, C> getCodecRegistry(StringCodecMapCodec<T, C> mapCodec);@Nonnull public HytaleLogger getLogger();
@Nonnull public PluginManifest getManifest();
@Nonnull public PluginIdentifier getIdentifier();
@Nonnull public Path getDataDirectory();
@Nonnull public PluginState getState();
@Nonnull public final String getBasePermission(); // "{group}.{name}" lowercase
public boolean isEnabled();
public boolean isDisabled();// Call in constructor (before setup):
@Nonnull protected final <T> Config<T> withConfig(@Nonnull BuilderCodec<T> configCodec);
@Nonnull protected final <T> Config<T> withConfig(@Nonnull String name, @Nonnull BuilderCodec<T> configCodec);public class JavaPluginInit extends PluginInit {
public JavaPluginInit(@Nonnull PluginManifest manifest, @Nonnull Path dataDirectory,
@Nonnull Path file, @Nonnull PluginClassLoader classLoader);
@Nonnull public Path getFile();
@Nonnull public PluginClassLoader getClassLoader();
public boolean isInServerClassPath();
}Package: com.hypixel.hytale.common.plugin
Required fields in manifest.json:
name— Plugin nameversion— Semver version stringgroup— Group identifier (e.g.,com.hyperperms)main— Fully qualified main class nameincludesAssetPack— Whether the JAR includes an asset pack
Optional fields:
dependencies— List of required plugin namessoftDependencies— List of optional plugin names
public enum PluginState {
NONE, // Initial state
SETUP, // setup() called
START, // start() called
ENABLED, // Successfully started
SHUTDOWN, // shutdown() in progress
DISABLED // Fully stopped or failed
}public class HyperPermsPlugin extends JavaPlugin {
public HyperPermsPlugin(JavaPluginInit init) {
super(init);
}
@Override
protected void setup() {
// Initialize core systems
}
@Override
protected void start() {
// Register permission provider, commands, events
getCommandRegistry().registerCommand(new HyperPermsCommand(hyperPerms));
getEventRegistry().register(PlayerConnectEvent.class, this::onPlayerConnect);
}
@Override
protected void shutdown() {
// Cleanup
}
}All registrations made through getEventRegistry(), getCommandRegistry(), etc. are automatically cleaned up when the plugin shuts down. No manual unregistration needed for most cases.
Auto-generated as "{manifest.group}.{manifest.name}" (lowercase). Commands registered by the plugin derive permissions from this base:
{basePermission}.command.{commandName}