Hytale Plugin Configuration Files
This skill documents how to create, load, save, and use configuration files in Hytale plugins using the Config<T> API.
Related skills: For Codec/BuilderCodec serialization details, see
hytale-persistent-data. For ECS component registration, seehytale-ecs.
Quick Reference
| Task | Approach |
|---|---|
| Define config class | Plain class with BuilderCodec<T> and default constructor |
| Register config | this.withConfig("Name", MyConfig.CODEC) in plugin field initializer |
| Save config to file | config.save() in setup() (creates file if missing) |
| Read config value | config.get().getSomeValue() |
| Modify config value | config.get().setSomeValue(newVal) then config.save() |
| Config file location | Server mods/ folder |
Configuration Class
A configuration class is a plain Java class (NOT an ECS component) with a BuilderCodec<T> that defines how each field serializes/deserializes.
Critical Rules
- •Codec keys MUST be capitalized — lowercase keys throw an error at load time.
- •Must have a default (no-arg) constructor — the codec uses it as a factory.
- •Does NOT implement
Component— config classes are not ECS components.
Template
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
public class MyConfig {
// === Codec Definition ===
// Keys MUST be capitalized (e.g. "SomeValue", not "someValue")
public static final BuilderCodec<MyConfig> CODEC =
BuilderCodec.builder(MyConfig.class, MyConfig::new)
.append(new KeyedCodec<Integer>("SomeValue", Codec.INTEGER),
(config, value) -> config.someValue = value, // setter
(config) -> config.someValue) // getter
.add()
.append(new KeyedCodec<String>("SomeString", Codec.STRING),
(config, value) -> config.someString = value,
(config) -> config.someString)
.add()
.build();
// === Fields with defaults ===
private int someValue = 12;
private String someString = "My default string";
// === Default Constructor (required) ===
public MyConfig() {
}
// === Getters ===
public int getSomeValue() {
return someValue;
}
public String getSomeString() {
return someString;
}
// === Setters ===
public void setSomeValue(int someValue) {
this.someValue = someValue;
}
public void setSomeString(String someString) {
this.someString = someString;
}
}
Registering and Loading the Config
Rules
- •
withConfig(...)MUST be called as a field initializer (or in the constructor) — calling it aftersetup()throws an error. - •Call
config.save()insetup()to create the config file on disk if it doesn't already exist.
Plugin Setup Template
import com.hypixel.hytale.server.plugin.Config;
import com.hypixel.hytale.server.plugin.JavaPlugin;
public class ExamplePlugin extends JavaPlugin {
// Register config — MUST be a field initializer (before setup())
private final Config<MyConfig> config = this.withConfig("MyConfig", MyConfig.CODEC);
@Override
public void setup() {
// Ensures the config file is created if it doesn't exist
config.save();
}
}
The first argument to withConfig() is the config file name (without extension). The file is created in the server's mods/ folder.
Accessing Config Values
From the Plugin Class
public void someMethod() {
MyConfig myConfig = config.get();
int value = myConfig.getSomeValue();
String str = myConfig.getSomeString();
}
From Other Classes
Pass the plugin instance or expose a getter:
Option A — Pass plugin reference:
public class SomeOtherClass {
private final ExamplePlugin plugin;
public SomeOtherClass(ExamplePlugin plugin) {
this.plugin = plugin;
}
public void someMethod() {
MyConfig myConfig = plugin.getConfig().get();
int value = myConfig.getSomeValue();
String str = myConfig.getSomeString();
}
}
Option B — Expose a typed getter on the plugin:
// In ExamplePlugin
public Config<MyConfig> getPluginConfig() {
return config;
}
Modifying and Saving Config
Changes to config values persist across server restarts when saved:
MyConfig myConfig = config.get();
// Modify values
myConfig.setSomeValue(999);
myConfig.setSomeString("A new string");
// Save changes back to disk
config.save();
Common Codec Types for Config Fields
Use these Codec types in KeyedCodec for your config fields:
| Java Type | Codec | Example Key |
|---|---|---|
int | Codec.INTEGER | "MaxPlayers" |
float | Codec.FLOAT | "SpawnRate" |
double | Codec.DOUBLE | "DamageMultiplier" |
boolean | Codec.BOOLEAN | "EnableFeature" |
String | Codec.STRING | "WelcomeMessage" |
long | Codec.LONG | "CooldownMs" |
List<T> | ListCodec | "AllowedWorlds" |
Map<K,V> | MapCodec | "LevelThresholds" |
Set<T> | SetCodec | "BannedItems" |
For advanced codec usage (nested objects, collections, validators), see the
hytale-persistent-dataskill.
Common Mistakes
| Mistake | Fix |
|---|---|
Lowercase codec key ("someValue") | Capitalize: "SomeValue" |
Calling withConfig() inside setup() | Move to field initializer or constructor |
Forgetting config.save() in setup() | Config file won't be created on first run |
Forgetting .add() after .append(...) | Codec builder chain is incomplete |
Forgetting .build() at end of codec | Codec is not finalized |
| Not saving after modifying values | Changes are lost on restart — call config.save() |
Complete Example
Config Class
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
public class ServerConfig {
public static final BuilderCodec<ServerConfig> CODEC =
BuilderCodec.builder(ServerConfig.class, ServerConfig::new)
.append(new KeyedCodec<Integer>("MaxPlayers", Codec.INTEGER),
(c, v) -> c.maxPlayers = v,
c -> c.maxPlayers)
.add()
.append(new KeyedCodec<Boolean>("PvpEnabled", Codec.BOOLEAN),
(c, v) -> c.pvpEnabled = v,
c -> c.pvpEnabled)
.add()
.append(new KeyedCodec<String>("Motd", Codec.STRING),
(c, v) -> c.motd = v,
c -> c.motd)
.add()
.append(new KeyedCodec<Double>("DamageMultiplier", Codec.DOUBLE),
(c, v) -> c.damageMultiplier = v,
c -> c.damageMultiplier)
.add()
.build();
private int maxPlayers = 20;
private boolean pvpEnabled = true;
private String motd = "Welcome to the server!";
private double damageMultiplier = 1.0;
public ServerConfig() {
}
public int getMaxPlayers() { return maxPlayers; }
public void setMaxPlayers(int maxPlayers) { this.maxPlayers = maxPlayers; }
public boolean isPvpEnabled() { return pvpEnabled; }
public void setPvpEnabled(boolean pvpEnabled) { this.pvpEnabled = pvpEnabled; }
public String getMotd() { return motd; }
public void setMotd(String motd) { this.motd = motd; }
public double getDamageMultiplier() { return damageMultiplier; }
public void setDamageMultiplier(double damageMultiplier) { this.damageMultiplier = damageMultiplier; }
}
Plugin Class
import com.hypixel.hytale.server.plugin.Config;
import com.hypixel.hytale.server.plugin.JavaPlugin;
public class MyPlugin extends JavaPlugin {
private final Config<ServerConfig> config = this.withConfig("ServerConfig", ServerConfig.CODEC);
@Override
public void setup() {
config.save();
}
@Override
public void start() {
ServerConfig cfg = config.get();
getLogger().info("Max players: " + cfg.getMaxPlayers());
getLogger().info("PvP enabled: " + cfg.isPvpEnabled());
getLogger().info("MOTD: " + cfg.getMotd());
getLogger().info("Damage multiplier: " + cfg.getDamageMultiplier());
}
public Config<ServerConfig> getServerConfig() {
return config;
}
}