Getting Started
This guide walks you through creating your first Hytale server mod from scratch.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure you have:
- Java 21+ - Hytale server targets Java 21. Your mod must be compiled with JDK 21 or newer, and the server itself runs on Java 21. Use Eclipse Temurin or any other JDK 21+ distribution.
- Maven or Gradle - For building your mod. The examples below use Gradle with the Kotlin DSL.
- A Hytale server - Download from the official Maven repository to test your mod locally.
Project Structure
Section titled “Project Structure”A typical mod project looks like this:
my-first-mod/├── src/│ └── main/│ ├── java/│ │ └── com/example/myfirstmod/│ │ └── MyFirstMod.java│ └── resources/│ ├── manifest.json│ └── Server/│ └── Languages/│ └── en-US/│ └── myfirstmod.lang├── pom.xml # Maven└── build.gradle.kts # or GradleServer Version
Section titled “Server Version”Get the latest server version from Maven:
curl -s "https://maven.hytale.com/release/com/hypixel/hytale/Server/maven-metadata.xml" | sed -n 's/.*<latest>\([^<]*\)<.*/\1/p'Or browse the maven-metadata.xml directly. Replace LATEST_VERSION in the build configuration below.
Build Configuration
Section titled “Build Configuration”<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId> <artifactId>my-first-mod</artifactId> <version>1.0.0</version> <packaging>jar</packaging>
<properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<repositories> <repository> <id>hytale-release</id> <url>https://maven.hytale.com/release</url> </repository> </repositories>
<dependencies> <dependency> <groupId>com.hypixel.hytale</groupId> <artifactId>Server</artifactId> <version>LATEST_VERSION</version> <!-- replace with actual version --> <scope>provided</scope> </dependency> </dependencies>
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build></project>plugins { java}
group = "com.example"version = "1.0.0"
java { toolchain { languageVersion = JavaLanguageVersion.of(21) }}
repositories { mavenCentral() maven { name = "hytale-release" url = uri("https://maven.hytale.com/release") }}
dependencies { compileOnly("com.hypixel.hytale:Server:LATEST_VERSION") // replace with actual version}
tasks.processResources { filesMatching("manifest.json") { expand(project.properties) }}rootProject.name = "my-first-mod"Manifest
Section titled “Manifest”Every mod requires a manifest.json in src/main/resources/:
{ "Group": "com.example", "Name": "MyFirstMod", "Version": "1.0.0", "Description": "My first Hytale mod", "Authors": [ { "Name": "Your Name", "Url": "https://example.com" } ], "Website": "https://example.com/my-first-mod", "Main": "com.example.myfirstmod.MyFirstMod", "ServerVersion": ">=1.0.0", "IncludesAssetPack": true}Manifest Fields
Section titled “Manifest Fields”| Field | Required | Description |
|---|---|---|
Group | No | Namespace for your mod (inherited from parent if in sub-plugin) |
Name | Yes | Unique identifier for your mod |
Version | No | Semantic version (e.g., 1.0.0, 1.2.3-beta) |
Description | No | Short description of what your mod does |
Authors | No | Array of author objects (Name, Email, Url) |
Website | No | URL to your mod’s homepage or repository |
Main | No | Fully qualified class name of your main class |
ServerVersion | No | Semver range for compatible server versions |
Dependencies | No | Map of required mods: {"Group:Name": ">=1.0.0"} |
OptionalDependencies | No | Map of optional mods (same format as Dependencies) |
LoadBefore | No | Map of mods this should load before |
DisabledByDefault | No | If true, mod won’t load unless explicitly enabled |
IncludesAssetPack | No | If true, the JAR is registered as an asset pack. Required for .lang files and other assets bundled in the JAR to load |
SubPlugins | No | Array of nested mod manifests (for mod bundles) |
Main Class & Setup
Section titled “Main Class & Setup”Create your main class extending JavaPlugin:
package com.example.myfirstmod;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import javax.annotation.Nonnull;import java.util.logging.Level;
public class MyFirstMod extends JavaPlugin {
public MyFirstMod(@Nonnull JavaPluginInit init) { super(init); }
@Override protected void setup() { getLogger().at(Level.INFO).log("MyFirstMod is setting up!");
// register commands, events, etc. here // getCommandRegistry().registerCommand(...); // getEventRegistry().register(...); }}The constructor must accept a JavaPluginInit parameter and pass it to the superclass. The setup() method is where you register commands, event listeners, and components — it runs during server startup before the world loads.
See Mod Lifecycle for all lifecycle phases (preLoad, setup, start, shutdown).
See Logging for Flogger formatting and log levels.
Build & Install
Section titled “Build & Install”mvn clean packageOutput: target/my-first-mod-1.0.0.jar
./gradlew buildOutput: build/libs/my-first-mod-1.0.0.jar
Copy the built JAR to your server’s mods/ directory and restart the server.
Next Steps
Section titled “Next Steps”Now that you have a basic mod running:
- Mod Lifecycle - What to register in setup(), start(), and shutdown()
- Translations - Add translatable text with
.langfiles and the Message API - Logging - How to log messages from your mod
- Configuration - Add configurable settings with
withConfig() - Threading - Thread safety rules for the server
- Scheduling - Run repeating or delayed tasks
- Creating Commands - Add custom commands for players
- Listening to Events - React to game events
- Adding Items - Create custom items with asset packs