How to add license keys to a Hytale plugin
Short answer: add the SunLicense Java SDK (shaded and relocated), read the buyer's key from your plugin's config.json, check it on a background thread when the plugin starts, and gate every command and event on the result. A network error is not a no: keep running and check again later.
// build.gradle.kts: implementation("com.sunlicense:sunlicense:0.0.1"), shaded and relocated
private static volatile boolean active;
private final SunLicense client = new SunLicense.Builder()
.baseUrl("https://api.sunlicense.com").token("slk_…").build(); // API key from your build, never git
private final ScheduledExecutorService checks = Executors.newSingleThreadScheduledExecutor();
@Override
protected void start() {
checks.scheduleAtFixedRate(() -> {
try {
SunLicense.Result r = client.validate(config.get().licenseKey(), Map.of("host", machineId()));
active = r.getStatus() != 400; // only a 400 is SunLicense saying no
if (!active) getLogger().atSevere().log("License rejected: " + r.getBody());
} catch (SunLicense.SunLicenseException e) {
active = true; // unreachable: keep running, check again later
}
}, 0, 6, TimeUnit.HOURS);
}
public static boolean active() { return active; } // every command and event: if (!MyPlugin.active()) return;Start from the template instead: the Hytale plugin template is the Paper template ported to Hytale's plugin API (built against server 0.7.5, Java 25): config.json with Hytale's own codecs, BuiltByBit placeholders, a stable machine id, masked keys, a signed offline license fallback, /myplugin status and recheck, tests and CI.
Or let your AI agent do it: paste the setup prompt into your coding agent in the plugin's folder.
Free plan: 3 products, 100 licenses, no credit card. Create a free account.
Step by step
- In the dashboard: a product, a policy (a machine is a server) and an API key, which can only validate.
- Add the SDK with Shadow and relocate it into your own package.
- Keep the API key out of git:
~/.gradle/gradle.properties(sunlicenseApiKey=slk_…), written into a resource at build time. - The buyer's key goes in
mods/<Group>_<Name>/config.json(LicenseKey), or a%%__SUNLICENSE__%%placeholder that BuiltByBit fills in on download. - Register in
setup(), check instart(). Hytale loads your config beforesetup();start()runs once every plugin is set up. Do the network call on your own executor, never on a world thread, and shut it down inshutdown(). - Machine id as
host: a hash of OS, architecture and host name (snippet in the Paper guide). - Results: 200 activates your features, 400 deactivates them with the reason, anything else keeps running and retries in about 10 minutes, or uses an offline license.
Early access
Hytale is in early access and its plugin API changes between updates. Check which server version you build against (hytaleVersion in the template's gradle.properties) after every Hytale update; the license check itself is plain Java and HTTP, so it doesn't change with the game.
Selling it
BuiltByBit has a Hytale category and the %%__SUNLICENSE__%% placeholder works the same as for Minecraft. Say in the listing that the plugin checks its license online and keeps running when the check can't reach SunLicense. Other stores: SunLicense issues a key per purchase (integrations).
More on licensing Hytale plugins.
