First decide: Pack or Plugin?
Use a Pack when the project is primarily data and assets: blocks, items, models, textures, sounds, NPC content, recipes, or behavior configured through Hytale's Asset Editor. Use a Plugin when you need Java code, commands, event listeners, services, persistence, or deeper server-side systems.
A plugin can include an asset pack, but code should not become the default answer to content the Asset Editor already supports. Keeping data-driven content in assets makes iteration and compatibility easier.
Requirements in 2026
- Hytale installed through the official launcher.
- Java 25 JDK configured as the project SDK.
- IntelliJ IDEA Community or Ultimate.
- Git if you clone the project instead of downloading a ZIP.
- A separate local project folder that is not inside the live Mods directory.
java -versionThe output must point to Java 25 for the current recommended plugin setup. Also check IntelliJ's Project SDK and Gradle JVM; your terminal can use Java 25 while Gradle silently uses another version.
Step 1: start from the maintained example project
CurseForge's current Hytale plugin documentation recommends the example project maintained for Hytale plugin development. It adds the server to the classpath, creates a local run setup, and builds a shareable JAR.
git clone https://github.com/Build-9/Hytale-Example-Project.git FoxWelcome
cd FoxWelcomeBefore opening the project, change the project name in settings.gradle and review the values in gradle.properties. Renaming early avoids Gradle and IDE caches retaining the example identity.
Know the project structure
FoxWelcome/
build.gradle
gradle.properties
settings.gradle
gradlew
gradlew.bat
src/main/java/
com/icedfox/foxwelcome/FoxWelcomePlugin.java
src/main/resources/
manifest.jsonKeep the Java package path, the package declaration, the class name, and the manifest Main value synchronized. Most "plugin appears but does not load" errors begin with one of those four names drifting.
Step 2: configure manifest.json
Edit src/main/resources/manifest.json. The exact server version changes with Hytale releases, so take the supported value from the current template or server build instead of inventing one.
{
"Group": "IcedFoxStudios",
"Name": "FoxWelcome",
"Version": "1.0.0",
"Description": "A small welcome plugin for test servers.",
"Authors": [
{
"Name": "Iced Fox Studios"
}
],
"Website": "https://www.icedfoxstudios.com/",
"ServerVersion": "COPY_FROM_THE_CURRENT_TEMPLATE",
"Dependencies": {},
"OptionalDependencies": {},
"DisabledByDefault": false,
"Main": "com.icedfox.foxwelcome.FoxWelcomePlugin",
"IncludesAssetPack": false
}Fields that deserve attention
GroupandNameform the plugin identity and should remain stable after release.Versionshould change for every public file.ServerVersionprotects users from loading the plugin against an incompatible server build.DependenciesandOptionalDependenciesdescribe load relationships with other plugins.Mainis the fully qualified Java entry class.IncludesAssetPackshould be true only when the JAR actually bundles assets.
Step 3: create the plugin entry class
The current API exposes a Java plugin base class and lifecycle methods. This minimal entry point logs each stage and gives you a safe place to register commands, events, configuration, and services later.
package com.icedfox.foxwelcome;
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 final class FoxWelcomePlugin extends JavaPlugin {
public FoxWelcomePlugin(@Nonnull JavaPluginInit init) {
super(init);
getLogger().at(Level.INFO).log("FoxWelcome loaded");
}
@Override
protected void setup() {
getLogger().at(Level.INFO).log("FoxWelcome setup");
// Register commands, event listeners, and services here.
}
@Override
protected void start() {
getLogger().at(Level.INFO).log("FoxWelcome enabled");
}
@Override
public void shutdown() {
getLogger().at(Level.INFO).log("FoxWelcome disabled");
// Save state and close resources here.
}
}Keep the first build boring: one class, no external libraries, and clear log messages. Once the plugin loads predictably, add one command or one event listener at a time using the current server API.
Step 4: build the plugin
Use the Gradle wrapper included with the project so every contributor uses the same Gradle setup.
gradlew.bat clean build./gradlew clean buildThe output JAR normally appears under build/libs/. Some templates expose an additional shaded-JAR task when dependencies must be bundled. Follow the task names in the exact template version you cloned.
Step 5: run and authenticate the local server
Open the project in IntelliJ and select the generated HytaleServer run configuration. On first use, the server must be authenticated with your Hytale account from the server terminal:
auth login deviceOpen the URL shown by the terminal and complete the device login. The example project also documents encrypted persistence for local convenience:
auth persistence Encrypted.gitignore and inspect the release archive manually.Connect from the Hytale client through Local Server or 127.0.0.1. Confirm all three lifecycle messages appear and that the server shuts down cleanly.
Step 6: test the release JAR like a player
A successful IDE run does not prove the distributable JAR is correct. Copy the built JAR directly into:
%AppData%\Hytale\UserData\Mods- Remove older JARs for the same plugin.
- Place the new JAR directly in the Mods folder, not inside another folder.
- Launch Hytale and open the target world's mod settings.
- Enable the plugin for that world.
- Load the world and inspect the server/client logs.
- Repeat after restarting the game to catch persistence and load-order problems.
Keep the plugin maintainable
Once the entry point works, split responsibilities before the class becomes a storage room:
com/icedfox/foxwelcome/
FoxWelcomePlugin.java
commands/
listeners/
services/
storage/
config/
util/- Register commands through the plugin command registry so ownership and permissions are correct.
- Register listeners through the plugin event registry and keep registration handles where cleanup is required.
- Store plugin data under the data directory exposed by the plugin API.
- Keep Hytale API dependencies compile-only when the server provides them.
- Bundle only third-party libraries you are licensed to distribute and actually need.
Prepare a CurseForge release
Create the Hytale project under the correct CurseForge class, then upload the plugin JAR from build/libs/. Include:
- A concise description of what the plugin changes.
- The exact compatible Hytale/server build or range.
- Dependencies and whether they are required or optional.
- Installation and per-world enablement instructions.
- Permissions, commands, configuration path, and defaults.
- A useful changelog for that file, not a repeated project description.
Upload a JAR for a plugin, a ZIP for a Pack, and a ZIP under the Worlds class for a custom world. Test the exact file you upload.
Common Hytale plugin problems
Gradle uses the wrong Java version
Check the terminal, IntelliJ Project SDK, and Gradle JVM separately. Restart the Gradle daemon after changing Java configuration.
The plugin does not appear
Confirm the JAR is directly in UserData/Mods, the manifest is packaged at the expected resource path, and the JSON is valid.
The plugin appears but fails to load
Match Main to the package and class exactly. Then check ServerVersion, dependencies, Java version, and the first server log error.
The plugin loads but does nothing
Confirm it is enabled for the current world. Add one lifecycle log and one small registration at a time so you know whether setup, start, commands, or events are failing.
The IDE works but the release JAR fails
Inspect the JAR contents and dependency packaging. Your IDE classpath can include libraries that are missing from the distributed artifact.
The local server cannot be joined
Complete device authentication, check the terminal for server startup errors, and connect through Local Server or 127.0.0.1.
Frequently asked questions
Do I need Java for every Hytale mod?
No. Packs use data and assets and can be built with the Asset Editor and related tools. Java 25 is needed for current Plugin development.
Can a plugin include custom models and items?
Yes, a plugin can include an asset pack when its manifest and build are configured for it. Keep assets organized under the expected Common and Server structures and test the packaged JAR.
Should I make an Early Plugin?
Not for normal gameplay features. Early or bootstrap plugins perform low-level class transformation and should be reserved for cases the standard plugin API cannot handle.
Primary sources checked
- CurseForge Support: Getting Started with Hytale Plugins
- Recommended Hytale Example Project
- CurseForge: How to Create Hytale Packs and Plugins
- Hytale Server API: JavaPlugin
- Hytale Server API: PluginManifest