5.0 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Creating a Plugin | docs | 3 |
This guide walks you through creating your first Hytale plugin from scratch.
Project Structure
A typical Hytale plugin project has this structure:
my-plugin/
├── app/
│ ├── build.gradle.kts
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/myplugin/
│ │ │ └── MyPlugin.java
│ │ └── resources/
│ │ └── manifest.json
│ └── test/
│ └── java/
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
├── build.gradle.kts
├── settings.gradle.kts
└── gradlew
The manifest.json
Every plugin requires a manifest.json file in src/main/resources/:
{
"Group": "com.example",
"Name": "MyPlugin",
"Version": "1.0.0",
"Description": "My first Hytale plugin",
"Authors": [
{
"Name": "Your Name"
}
],
"Main": "com.example.myplugin.MyPlugin",
"ServerVersion": "*",
"Dependencies": {},
"OptionalDependencies": {},
"DisabledByDefault": false,
"IncludesAssetPack": false,
"SubPlugins": []
}
Manifest Fields
| Field | Required | Description |
|---|---|---|
Group |
Yes | Package group (e.g., "com.example") |
Name |
Yes | Plugin name (used for identification) |
Version |
Yes | Semantic version (e.g., "1.0.0") |
Description |
No | Brief description of the plugin |
Authors |
No | List of authors with Name field |
Main |
Yes | Fully qualified main class name |
ServerVersion |
Yes | Server version compatibility ("*" for any) |
Dependencies |
No | Required plugin dependencies |
OptionalDependencies |
No | Optional plugin dependencies |
DisabledByDefault |
No | Whether plugin is disabled by default |
IncludesAssetPack |
No | Whether plugin includes assets |
SubPlugins |
No | List of sub-plugins |
{{< callout type="warning" >}}
All manifest field names use PascalCase (e.g., ServerVersion, not serverVersion).
{{< /callout >}}
Main Plugin Class
Create your main plugin class extending JavaPlugin:
package com.example.myplugin;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import java.util.logging.Level;
public class MyPlugin extends JavaPlugin {
public MyPlugin(JavaPluginInit init) {
super(init);
}
@Override
public void setup() {
// Called during plugin initialization
// Register configs, prepare resources
getLogger().at(Level.INFO).log("MyPlugin is setting up!");
}
@Override
public void start() {
// Called when the plugin starts
// Register commands, events, entities
getLogger().at(Level.INFO).log("MyPlugin has started!");
}
@Override
public void shutdown() {
// Called when the plugin is stopping
// Clean up resources
getLogger().at(Level.INFO).log("MyPlugin is shutting down!");
}
}
{{< callout type="info" >}}
The constructor with JavaPluginInit parameter is required. Always call super(init).
{{< /callout >}}
Logger API
Hytale uses a Flogger-based logging API:
import java.util.logging.Level;
// Basic logging
getLogger().at(Level.INFO).log("Information message");
getLogger().at(Level.WARNING).log("Warning message");
getLogger().at(Level.SEVERE).log("Error message");
// With formatting
getLogger().at(Level.INFO).log("Player %s joined the game", playerName);
build.gradle.kts
Configure your Gradle build file (Kotlin DSL):
plugins {
java
}
group = "com.example"
version = "1.0.0"
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
dependencies {
// Hytale Server API - compile only since it's provided at runtime
compileOnly(files("../../../HytaleServer.jar"))
// Testing
testImplementation(libs.junit)
}
tasks.jar {
archiveBaseName.set("MyPlugin")
}
{{< callout type="info" >}}
The path to HytaleServer.jar depends on where your plugin source is located relative to the game directory.
{{< /callout >}}
Available Registries
Your plugin has access to several registries through the base class:
| Method | Registry Type | Purpose |
|---|---|---|
getEventRegistry() |
EventRegistry | Register event listeners |
getCommandRegistry() |
CommandRegistry | Register commands |
getEntityRegistry() |
EntityRegistry | Register custom entities |
getBlockStateRegistry() |
BlockStateRegistry | Register block states |
getTaskRegistry() |
TaskRegistry | Schedule tasks |
getAssetRegistry() |
AssetRegistry | Register assets |
getEntityStoreRegistry() |
EntityStoreRegistry | Register entity components |
getChunkStoreRegistry() |
ChunkStoreRegistry | Register chunk components |
Next Steps
Learn about the Plugin Lifecycle to understand when each method is called.