197 lines
5.0 KiB
Markdown
197 lines
5.0 KiB
Markdown
---
|
|
title: Creating a Plugin
|
|
type: docs
|
|
weight: 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/`:
|
|
|
|
```json
|
|
{
|
|
"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`:
|
|
|
|
```java
|
|
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:
|
|
|
|
```java
|
|
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):
|
|
|
|
```kotlin
|
|
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](../plugin-lifecycle) to understand when each method is called.
|