feat: Adds branch for Hytale-Tools plugin example (#21)

This commit is contained in:
Neil
2026-06-08 23:39:18 +05:30
committed by GitHub
14 changed files with 453 additions and 221 deletions

22
.github/workflows/gradle.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Verifying Everything Compiles
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Set up JDK 25
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Verify build is not broken
run: ./gradlew build

49
.gitignore vendored
View File

@@ -1,46 +1,11 @@
target/ .gradle/
!.mvn/wrapper/maven-wrapper.jar build/
!**/src/main/**/target/ out/
!**/src/test/**/target/ run/
.idea/
### IntelliJ IDEA ###
.idea
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/*.xml
.idea/libraries/
*.iws
*.iml *.iml
*.ipr *.ipr
*.iws
### Eclipse ###
.apt_generated
.classpath .classpath
.factorypath
.project .project
.settings .settings/
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
### Gradle ###
.gradle
.kotlin
devserver
/.idea/

168
README.md
View File

@@ -4,52 +4,158 @@ A ready-to-use starting point for creating Hytale server plugins with Java, _or
been using the Asset Editor and want to start writing server-side logic — custom commands, event been using the Asset Editor and want to start writing server-side logic — custom commands, event
handling, gameplay systems — this is the simplest place to begin. handling, gameplay systems — this is the simplest place to begin.
## How to start? This template uses the [Hytale Gradle Plugin](https://github.com/AzureDoom/Hytale-Gradle-Plugin),
a Gradle plugin maintained by AzureDoom for Hytale mod/plugin development. It handles the repetitive
project setup work for you, including manifest generation, validation, local server runs, IDE source
setup, and optional hosted Hytale Javadoc injection.
1. Copy the template by downloading it or using the "Use this template" button. ## How to start
2. [Configure or Install the Java SDK](https://hytalemodding.dev/en/docs/guides/plugin/setting-up-env)
to use the latest 25 from JetBrains or similar.
3. Open the project in your favorite IDE, we
recommend [IntelliJ IDEA](https://www.jetbrains.com/idea/download).
4. Optionally, run `./gradlew` if your IDE does not automtically synchronizes.
5. Run the devserver with the Run Configuration created, or `./gradlew devServer`.
> On Windows, use `.\gradlew.bat` instead of `./gradlew`, this script is here to run the 1. Copy the template by downloading it or using the **Use this template** button.
> Gradle without you needing to install the tooling itself, only the Java is required. 2. [Configure or install the Java SDK](https://hytalemodding.dev/en/docs/guides/plugin/setting-up-env)
to use Java 25. JetBrains Runtime is recommended for the best hot-reload/debugging experience.
3. Open the project in your favorite IDE. We recommend
[IntelliJ IDEA](https://www.jetbrains.com/idea/download).
4. Update the project values in `gradle.properties`:
- `rootProject.name` in `settings.gradle.kts`
- `group`
- `manifest_group`
- `mod_name`
- `mod_id`
- `main_class`
- `mod_author`
- `mod_description`
- `mod_url`
5. Optionally run `./gradlew` if your IDE does not automatically sync the project.
6. Prepare the Hytale development environment:
With that you will be prompted in the output to authorize your server, and then you can start ```bash
developing your plugin while the server is live reloading the code changes. ./gradlew setupHytaleDev
```
From here, 7. Run the local development server:
the [HytaleModding guides](https://hytalemodding.dev/en/docs/guides/plugin/build-and-test) cover
more details!
## Scaffoldit Plugin ```bash
./gradlew runServer
```
While there are multiple plugins made for Hytale, the template currently uses a zero-boilerplate one > On Windows, use `./gradlew.bat` or `gradlew.bat` instead of `./gradlew`. The Gradle wrapper is
where you only need the absolute minimum to start. However, you do have access to everything as > included so you do not need to install Gradle separately; only Java is required.
normal if you know what you are doing.
For in-depth configuration, you can visit the [ScaffoldIt Plugin Docs](https://scaffoldit.dev). When the server starts, the output may prompt you to authorize your Hytale server. After that, you
can begin developing your plugin while the server handles local development runs.
From here, the [HytaleModding guides](https://hytalemodding.dev/en/docs/guides/plugin/build-and-test)
cover more details.
## Hytale Gradle Plugin
This template is built around AzureDoom's `com.azuredoom.hytale-tools` Gradle plugin.
The plugin is configured in `build.gradle.kts`:
```kotlin
plugins {
idea
java
id("com.azuredoom.hytale-tools") version "1.+"
}
```
The AzureDoom Maven repository is configured in `settings.gradle.kts`:
```kotlin
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven {
name = "AzureDoom Maven"
url = uri("https://maven.azuredoom.com/mods")
}
}
}
```
Most plugin-specific settings are controlled from `gradle.properties` and passed into the
`hytaleTools` block in `build.gradle.kts`. This keeps common project metadata in one easy-to-edit
place.
For full plugin documentation, configuration options, tasks, and multi-project setup, visit the
[Hytale Gradle Plugin repository](https://github.com/AzureDoom/Hytale-Gradle-Plugin).
## Useful commands
```bash
# Sync/setup the local Hytale development environment
./gradlew setupHytaleDev
# Run the local Hytale server
./gradlew runServer
# Run the server with debugging and hot swap enabled
./gradlew runServer -Ddebug=true -Dhotswap=true
# Check your JVM and hot swap setup
./gradlew hytaleJvmDoctor
# Build the plugin
./gradlew build
# Refresh dependencies if something fails to resolve
./gradlew build --refresh-dependencies
```
## Project structure
```text
src/main/java/ Plugin source code
src/main/resources/ Plugin resources, including manifest.json
gradle.properties Main template configuration
build.gradle.kts Gradle build and Hytale Gradle Plugin configuration
settings.gradle.kts Plugin repositories and project name
```
## Manifest configuration
The generated `manifest.json` is driven by the values in `gradle.properties`, including:
- `manifest_group`
- `mod_id`
- `version`
- `mod_description`
- `mod_author`
- `mod_url`
- `main_class`
- `manifest_dependencies`
- `manifest_opt_dependencies`
- `manifestServerVersion`
After changing these values, run:
```bash
./gradlew updatePluginManifest
```
## Troubleshooting ## Troubleshooting
- **Gradle sync fails in IntelliJ** - **Gradle sync fails in IntelliJ** — Check that Java 25 is installed and configured under
_Check that Java 25 is installed and configured under File → Project Structure → SDKs._ **File → Project Structure → SDKs**.
- **Build fails with missing dependencies** - **The Hytale Gradle Plugin does not resolve** — Make sure `settings.gradle.kts` includes the
_Run `./gradlew build --refresh-dependencies`. Make sure you have internet access!_ AzureDoom Maven repository at `https://maven.azuredoom.com/mods`.
- **Permission denied on `./gradlew`** - **Build fails with missing dependencies** — Run `./gradlew build --refresh-dependencies` and make
_Run `chmod +x gradlew` (macOS/Linux)._ sure you have internet access.
- **Hot-reload doesn't work** - **Permission denied on `./gradlew`** — Run `chmod +x gradlew` on macOS/Linux.
_Verify you're using JetBrains Runtime, not a regular JDK._ - **Hot reload or enhanced class redefinition does not work** — Use JetBrains Runtime and try
`./gradlew hytaleJvmDoctor` to verify your JVM setup.
## Resources ## Resources
- [Hytale Gradle Plugin](https://github.com/AzureDoom/Hytale-Gradle-Plugin)
- [Hytale Modding Guides](https://hytalemodding.dev) - [Hytale Modding Guides](https://hytalemodding.dev)
- [Hytale Modding Discord](https://discord.gg/hytalemodding) - [Hytale Modding Discord](https://discord.gg/hytalemodding)
- [ScaffoldIt Plugin Docs](https://scaffoldit.dev)
## License ## License
Add your own after copying the template, though we recommend using MIT, BSD, or Apache to keep Add your own license after copying the template. We recommend MIT, BSD, or Apache to keep the
the modding community open! modding community open.

View File

@@ -1,11 +1,50 @@
/** plugins {
* NOTE: This is entirely optional and basics can be done in `settings.gradle.kts` // Uncomment if you are using IntelliJ.
*/ // idea
java
id("com.azuredoom.hytale-tools") version "1.+"
}
tasks.withType<Javadoc>().configureEach {
(options as org.gradle.external.javadoc.StandardJavadocDocletOptions).addStringOption("Xdoclint:-missing", "-quiet")
}
group = project.property("group").toString()
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(property("java_version").toString().toInt()))
}
hytaleTools {
javaVersion = property("java_version").toString().toInt()
hytaleVersion = property("hytale_version").toString()
manifestServerVersion = property("manifestServerVersion").toString()
manifestGroup = property("manifest_group").toString()
modId = property("mod_id").toString()
modDescription = property("mod_description").toString()
modUrl = property("mod_url").toString()
mainClass = property("main_class").toString()
modCredits = property("mod_author").toString()
manifestDependencies = property("manifest_dependencies").toString()
manifestOptionalDependencies = property("manifest_opt_dependencies").toString()
curseforgeId = property("curseforgeID").toString()
disabledByDefault = property("disabled_by_default").toString().toBoolean()
includesPack = property("includes_pack").toString().toBoolean()
patchline = property("patchline").toString()
injectServerJavadocsIntoSources = property("injectServerJavadocsIntoSources").toString().toBoolean()
generateAssetsBinary = property("generateAssetsBinary").toString().toBoolean()
// hytaleHomeOverride = property("hytaleHomeOverride").toString()
}
repositories { repositories {
// Any external repositories besides: MavenLocal, MavenCentral, HytaleMaven, and CurseMaven mavenCentral()
} }
dependencies { // Uncomment if you are using IntelliJ.
// Any external dependency you also want to include // idea {
} // module {
// isDownloadSources = true
// isDownloadJavadoc = true
// }
// }

View File

@@ -1,8 +1,86 @@
# Gradle runtime options
# Enables the Gradle daemon for faster repeat builds.
org.gradle.daemon = true org.gradle.daemon = true
org.gradle.parallel=true
# Turn the following on once you finished changing your settings/build:
# org.gradle.configuration-cache=true
# org.gradle.caching=true
# Optional Hytale location for the Assets.zip resolution: # JVM memory used by Gradle while building the project.
# hytale.home_path=... org.gradle.jvmargs = -Xmx3G
# Allows Gradle to build independent tasks in parallel.
org.gradle.parallel = true
# Enables Gradle's local build cache.
org.gradle.caching = true
# Java / Hytale options
# Java version used by the generated mod project.
java_version = 25
# Hytale server version targeted by this mod.
hytale_version = 0.+
# Mod identity
# Java package group used by Gradle.
group = dev.hytalemodding
# Group identifier written into manifest.json.
manifest_group = HytaleModding
# Human-readable mod name.
mod_name = Replace Me
# Fully-qualified plugin entry point class.
main_class = dev.hytalemodding.ExamplePlugin
# Comma-separated author entries. Author names cannot contain spaces.
# Each entry supports: Name, Name|Email, or Name|Email|Url.
# Example: AzureDoom|azuredoom@example.com|https://example.com,SomeOtherAuthor
mod_author = Your_Name|your.email@example.com|https://your-website.com
# Unique lowercase mod identifier.
mod_id = ExamplePlugin
# SPDX-style license identifier or Proprietary.
mod_license = MIT
# Short description written into manifest.json.
mod_description = Description of your plugin
# Project website, source, or download URL.
mod_url = https://your-plugin-website.com
# Initial mod version.
version = 0.0.0
# Manifest / packaging options
# Whether this mod includes an asset pack.
includes_pack = true
# Whether this mod starts disabled by default.
disabled_by_default = false
# Hytale patchline used for dependency resolution.
patchline = release
# Server version mirrored for tooling compatibility.
server_version = 0.5.3
# Server version range written into manifest.json.
manifestServerVersion = >=0.5.3 <0.6.0
# Required manifest dependencies. Format: Group:Name=Version,Other:Mod=*
manifest_dependencies = Hytale:AssetModule=*
# Optional manifest dependencies. Same format as manifest_dependencies.
manifest_opt_dependencies =
# CurseForge project ID used by update checking, if any.
curseforgeID =
# Injects hosted Hytale API docs into generated Vineflower server sources for easier IDE browsing.
injectServerJavadocsIntoSources = true
# Controls whether prepareDecompiledSourcesForIde / idea generate the large hytale-assets.jar IDE binary from Assets.zip. Disable to avoid creating the extra assets jar.
generateAssetsBinary = false
# Optional path to a local Hytale installation, a directory containing Assets.zip, or an Assets.zip file. When set, local dev tasks use this assets zip directly instead of requiring the Gradle cached assets zip.
hytaleHomeOverride = /path/to/Hytale/install/release/package/game/latest/Assets.zip

Binary file not shown.

View File

@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000 networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

5
gradlew vendored
View File

@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@" "$@"

32
gradlew.bat vendored
View File

@@ -23,8 +23,8 @@
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables, and ensure extensions are enabled
if "%OS%"=="Windows_NT" setlocal setlocal EnableExtensions
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,30 +65,18 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* @rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:end :exitWithErrorLevel
@rem End local scope for the variables with windows NT shell @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
if %ERRORLEVEL% equ 0 goto mainEnd "%COMSPEC%" /c exit %ERRORLEVEL%
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,28 +1,16 @@
rootProject.name = "dev.hytalemodding" pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven {
name = "AzureDoom Maven"
url = uri("https://maven.azuredoom.com/mods")
}
}
}
plugins { plugins {
// See documentation on https://scaffoldit.dev id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
id("dev.scaffoldit") version "0.2.+"
} }
// Would you like to do a split project? rootProject.name = "Replace Me"
// Create a folder named "common", then configure details with `common { }`
hytale {
usePatchline("release")
useVersion("latest")
repositories {
// Any external repositories besides: MavenLocal, MavenCentral, HytaleMaven, and CurseMaven
}
dependencies {
// Any external dependency you also want to include
}
manifest {
Group = "HytaleModding"
Name = "ExamplePlugin"
Main = "dev.hytalemodding.ExamplePlugin"
}
}

View File

@@ -3,20 +3,32 @@ package dev.hytalemodding;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent; import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.util.Config;
import dev.hytalemodding.commands.ExampleCommand; import dev.hytalemodding.commands.ExampleCommand;
import dev.hytalemodding.config.ExampleConfig;
import dev.hytalemodding.events.ExampleEvent; import dev.hytalemodding.events.ExampleEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ExamplePlugin extends JavaPlugin { public class ExamplePlugin extends JavaPlugin {
private static Config<ExampleConfig> config = null;
public ExamplePlugin(@Nonnull JavaPluginInit init) { public ExamplePlugin(@Nonnull JavaPluginInit init) {
super(init); super(init);
config = this.withConfig("example_config", ExampleConfig.CODEC);
} }
@Override @Override
protected void setup() { protected void setup() {
config.save();
this.getCommandRegistry().registerCommand(new ExampleCommand("example", "An example command")); this.getCommandRegistry().registerCommand(new ExampleCommand("example", "An example command"));
if (getConfig().get().isEnabledWelcomeMessage()) {
this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady); this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady);
} }
} }
public static Config<ExampleConfig> getConfig() {
return config;
}
}

View File

@@ -0,0 +1,25 @@
package dev.hytalemodding.config;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
public class ExampleConfig {
public static final BuilderCodec<ExampleConfig> CODEC = BuilderCodec.builder(ExampleConfig.class, ExampleConfig::new)
.append(
new KeyedCodec<>("EnableWelcomeMessage", Codec.BOOLEAN),
(exConfig, aBoolean, extraInfo) -> exConfig.enabledWelcomeMessage = aBoolean,
(exConfig, extraInfo) -> exConfig.enabledWelcomeMessage
)
.add()
.build();
private boolean enabledWelcomeMessage;
private ExampleConfig() {}
public boolean isEnabledWelcomeMessage() {
return enabledWelcomeMessage;
}
}

View File

@@ -1,8 +1,11 @@
package dev.hytalemodding.events; package dev.hytalemodding.events;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent; import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
public class ExampleEvent { public class ExampleEvent {

View File

@@ -5,16 +5,23 @@
"Description": "Description of your plugin", "Description": "Description of your plugin",
"Authors": [ "Authors": [
{ {
"Name": "Your Name", "Name": "Your_Name",
"Email": "your.email@example.com", "Email": "your.email@example.com",
"Url": "https://your-website.com" "Url": "https://your-website.com"
} }
], ],
"Website": "https://your-plugin-website.com", "Website": "https://your-plugin-website.com",
"DisabledByDefault": false, "DisabledByDefault": false,
"IncludesAssetPack": false, "IncludesAssetPack": true,
"Dependencies": {}, "Dependencies": {
"OptionalDependencies": {}, "Hytale:AssetModule": "*"
"ServerVersion": "*", },
"Main": "dev.hytalemodding.ExamplePlugin" "OptionalDependencies": {
},
"ServerVersion": ">=0.5.3 <0.6.0",
"Main": "dev.hytalemodding.ExamplePlugin",
"UpdateChecker": {
"CurseForge": ""
}
} }