Hytale Plugin Development
Create server-side plugins for Hytale using Java 25 and Gradle.
Overview
Hytale uses a server-side first modding approach. All plugins run on the server - players don't need to install anything to join modded servers.
Tech Stack:
-
Java 25 - Required JDK version
-
Gradle 9.2 - Build system
-
Antigravity - Recommended IDE (AI-assisted development!)
First-Time Setup Flow
When a user asks to create a plugin, guide them through this:
Step 1: Prerequisites Check
I'll help you create that plugin! First, let me verify your setup:
Prerequisites:
- Java 25 (download from Adoptium or Oracle)
- Gradle (I can run commands for you in Antigravity!)
If you're using Antigravity, you're all set - I can handle builds directly!
Step 2: Install Java 25
Windows:
Download from Adoptium
winget install EclipseAdoptium.Temurin.25.JDK
Or download manually from: https://adoptium.net/
Step 3: Create Project from Template
The easiest way to start - use the community template:
Clone the official template (Darkhax/Jared)
git clone https://github.com/Darkhax-Hytale/HytalePluginTemplate.git MyPlugin cd MyPlugin
Or create manually with this structure:
MyPlugin/ ├── build.gradle.kts ├── settings.gradle.kts ├── gradle.properties └── src/ └── main/ └── java/ └── com/ └── yourname/ └── myplugin/ └── MyPlugin.java
Step 4: Open in Antigravity
-
Open the project folder in Antigravity
-
I'll automatically detect the Gradle project
-
Use gradle build via run_command to build
-
I can help you write, debug, and test code!
Alternative: IntelliJ IDEA
-
Open IntelliJ IDEA
-
File → Open → Select project folder
-
File → Project Structure → Project → SDK → Select Java 25
-
Let Gradle sync complete
Plugin Lifecycle
Every plugin extends JavaPlugin with these lifecycle methods:
package com.yourname.myplugin;
import com.hytale.server.plugin.JavaPlugin;
public class MyPlugin extends JavaPlugin {
@Override
public void setup() {
// Called during server setup phase
// Register commands, events, configs here
getLogger().info("MyPlugin setting up...");
}
@Override
public void start() {
// Called when server starts
// Initialize runtime features
getLogger().info("MyPlugin started!");
}
@Override
public void shutdown() {
// Called during server shutdown
// Clean up resources, save data
getLogger().info("MyPlugin shutting down...");
}
}
Lifecycle Order
Server Boot → setup() → start() → [Running] → shutdown() → Server Stop
Command Registration
Register custom commands in setup() :
@Override public void setup() { registerCommand("hello", (sender, args) -> { sender.sendMessage("Hello from MyPlugin!"); return true; });
registerCommand("spawn", (sender, args) -> {
if (sender instanceof Player player) {
player.teleportToSpawn();
player.sendMessage("Teleported to spawn!");
}
return true;
});
}
Command with Arguments
registerCommand("give", (sender, args) -> { if (args.length < 2) { sender.sendMessage("Usage: /give <player> <item>"); return false; } String playerName = args[0]; String itemId = args[1]; // Implementation... return true; });
Event System
Event Types
Category Examples
Server Lifecycle BootEvent , ShutdownEvent , PluginSetupEvent
Player Events PlayerJoinEvent , PlayerQuitEvent , PlayerChatEvent
World Events WorldLoadEvent , ChunkLoadEvent
Entity Events EntitySpawnEvent , EntityDamageEvent
Block Events BlockBreakEvent , BlockPlaceEvent
Registering Event Listeners
@Override public void setup() { registerEventListener(PlayerJoinEvent.class, event -> { Player player = event.getPlayer(); getServer().broadcastMessage(player.getName() + " joined!"); });
registerEventListener(BlockBreakEvent.class, event -> {
if (event.getBlock().getType().equals("diamond_ore")) {
event.getPlayer().sendMessage("You found diamonds!");
}
});
}
Cancellable Events
registerEventListener(BlockBreakEvent.class, event -> { if (isProtectedArea(event.getBlock().getPosition())) { event.setCancelled(true); event.getPlayer().sendMessage("This area is protected!"); } });
Entity Component System (ECS)
Hytale uses ECS architecture for entities:
Core Concepts
-
Entity: Unique ID, no data or behavior
-
Component: Data container (health, position, inventory)
-
System: Logic that operates on components
Working with Components
// Get a component from an entity HealthComponent health = entity.getComponent(HealthComponent.class); if (health != null) { health.setHealth(health.getHealth() + 10); }
// Check if entity has component if (entity.hasComponent(FlyingComponent.class)) { // Handle flying entity }
Gradle Build Configuration
Setting Up Dependencies (Critical!)
The official maven repo has been unstable. Use this local-first strategy:
Step 1: Extract API from HytaleServer.jar
Windows - find the server JAR:
%appdata%\Hytale\Hytale\install\release\package\game\latest\Server\HytaleServer.jar
Install to local Maven cache:
mvn install:install-file
-Dfile="PATH_TO_JAR/HytaleServer.jar"
-DgroupId=com.hypixel.hytale
-DartifactId=Server
-Dversion=1.0-SNAPSHOT
-Dpackaging=jar
build.gradle.kts
plugins {
java-library
id("hytale-mod") version "0.+" // Community tooling
}
group = "com.yourname" version = "1.0.0"
java { toolchain { languageVersion.set(JavaLanguageVersion.of(25)) // Required! } }
repositories { mavenLocal() // Priority 1: Local cache (from extracted JAR) mavenCentral()
// Priority 2: Community mirror (more stable than official)
maven("https://maven.hytale-modding.info/releases") {
content {
includeGroup("com.hypixel.hytale")
}
}
// JitPack for GitHub-hosted community libs
maven("https://jitpack.io")
}
dependencies { // MUST be compileOnly - server provides at runtime compileOnly("com.hypixel.hytale:Server:1.0-SNAPSHOT") }
Important: Use compileOnly for the server dependency. Bundling it causes ClassCastExceptions.
Building
Build the plugin JAR
gradle build
Output: build/libs/MyPlugin-1.0.0.jar
Installing
For client mods: %APPDATA%/Hytale/UserData/Mods/
For server plugins: Copy to server/mods/ folder (NOT plugins/ )
Project Structure
MyPlugin/ ├── build.gradle.kts # Gradle build script ├── settings.gradle.kts # Gradle settings ├── gradle.properties # Gradle properties ├── src/ │ └── main/ │ ├── java/ │ │ └── com/yourname/myplugin/ │ │ ├── MyPlugin.java # Main plugin class │ │ ├── commands/ # Command handlers │ │ ├── events/ # Event listeners │ │ └── systems/ # ECS systems │ └── resources/ │ └── plugin.json # Plugin metadata └── build/ └── libs/ └── MyPlugin-1.0.0.jar # Built plugin
Quick Reference
Task How
Build plugin gradle build
Install plugin Copy JAR to %APPDATA%/Hytale/UserData/Mods/
Reload plugins /plugin reload in-game
View plugins /plugin list in-game
Debug Use Antigravity terminal + logging
Resources
-
Community Mirror Maven: https://maven.hytale-modding.info/releases
-
Example Plugin (Kaupenjoe): GitHub
-
SimpleClaims (Buuz135): GitHub
-
Hytale Modding Bible: Community API reference on Reddit
-
Kytale Framework: CurseForge
-
Imperat Command Framework: Multi-platform command lib
-
Java 25 Reference: See java-25-hytale skill
-
Gradle Reference: See gradle-hytale skill