Mod Lifecycle
Mods go through a defined lifecycle from loading to shutdown. This guide explains what to do in each phase.
Overview
Section titled “Overview”preLoad()
Section titled “preLoad()”Called before the server is fully initialized. Returns CompletableFuture<Void> (nullable).
@Overridepublic CompletableFuture<Void> preLoad() { return CompletableFuture.runAsync(() -> { // early async initialization if needed });}setup()
Section titled “setup()”The main registration phase. Called when your mod loads.
@Overrideprotected void setup() { // register a command getCommandRegistry().registerCommand(new MyCommand());
// register event listeners getEventRegistry().register(PlayerJoinEvent.class, this::onPlayerJoin);
// register a component this.myComponentType = getEntityStoreRegistry() .registerComponent(MyComponent.class, "MyComponent", MyComponent.CODEC);}See what Hytale's built-in mods register in setup()
| Task | Method |
|---|---|
| Register commands | getCommandRegistry().registerCommand() |
| Register event listeners | getEventRegistry().register() |
| Register components | getEntityStoreRegistry().registerComponent() |
| Register systems | getEntityStoreRegistry().registerSystem() |
| Register block states | getBlockStateRegistry().registerBlockState() |
| Register asset stores | AssetRegistry.register() |
| Register codecs | getCodecRegistry().register() |
| Register interactions | Interaction.CODEC.register() |
| Register entity types | getEntityRegistry().registerEntity() |
start()
Section titled “start()”Called after all mods have completed setup(). Use for initialization that depends on assets or other mods being ready.
@Overrideprotected void start() { // load an asset (not safe during setup - assets may not be loaded yet) ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset("My_Model"); if (modelAsset == null) { throw new IllegalStateException("Model 'My_Model' not found"); } this.model = Model.createUnitScaleModel(modelAsset);
// read config and apply settings MyConfig cfg = this.config.get(); this.maxPlayers = cfg.maxPlayers;
// schedule a recurring task this.saveTask = HytaleServer.SCHEDULED_EXECUTOR .scheduleWithFixedDelay(this::saveData, 5, 5, TimeUnit.MINUTES);}See what Hytale's built-in mods do in start()
| Task | Method |
|---|---|
| Load asset references | ModelAsset.getAssetMap().getAsset() |
| Read configuration values | this.config.get() |
| Schedule recurring tasks | HytaleServer.SCHEDULED_EXECUTOR.scheduleWithFixedDelay() |
| Cross-mod integration | PluginManager.getPlugin() |
shutdown()
Section titled “shutdown()”Called when the server stops. Use for cleanup that isn’t handled automatically.
@Overrideprotected void shutdown() { // cancel scheduled tasks if (this.saveTask != null) { this.saveTask.cancel(false); }
// save any pending data this.dataStore.saveToDiskAll();}See what Hytale's built-in mods do in shutdown()
| Task | Method |
|---|---|
| Cancel scheduled tasks | scheduledFuture.cancel(false) |
| Save persistent data | dataStore.saveToDisk() |
| Close external connections | connection.close() |
See Also
Section titled “See Also”- Getting Started - Project structure, build setup, and manifest
- Registries - All available registries and their methods
- Logging - How to log messages
- Configuration - How to use
withConfig()for settings