11 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| All Registries | docs | 2 |
Complete reference of all registries available in the Hytale Plugin API.
Registry Overview
Registries are accessed through PluginBase methods:
public class MyPlugin extends PluginBase {
@Override
public void start() {
EventRegistry events = getEventRegistry();
CommandRegistry commands = getCommandRegistry();
TaskRegistry tasks = getTaskRegistry();
AssetRegistry assets = getAssetRegistry();
BlockStateRegistry blocks = getBlockStateRegistry();
CodecRegistry codecs = getCodecRegistry();
EntityRegistry entities = getEntityRegistry();
}
}
EventRegistry
Manages event listeners and dispatching.
Methods
| Method | Description |
|---|---|
register(Class, Consumer) |
Register event handler |
register(EventPriority, Class, Consumer) |
Register with priority |
registerGlobal(Class, Consumer) |
Register global handler |
registerAsync(Class, Function) |
Register async handler |
unregister(listener) |
Remove listener |
Example
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.event.EventPriority;
import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.Message;
import java.util.logging.Level;
EventRegistry events = getEventRegistry();
// Use getPlayerRef() - getPlayer() is deprecated
events.register(PlayerConnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
playerRef.sendMessage(Message.raw("Welcome!"));
});
events.register(EventPriority.FIRST, PlayerDisconnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
getLogger().at(Level.INFO).log(playerRef.getUsername() + " left");
});
CommandRegistry
Manages command registration and execution.
Methods
| Method | Description |
|---|---|
registerCommand(AbstractCommand) |
Register a command |
Example
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.CommandRegistry;
import com.hypixel.hytale.server.core.Message;
import java.util.concurrent.CompletableFuture;
CommandRegistry commands = getCommandRegistry();
// Register a command - AbstractCommand.execute() returns CompletableFuture<Void>
commands.registerCommand(new AbstractCommand("hello", "my_plugin.commands.hello.description") {
@Override
protected CompletableFuture<Void> execute(CommandContext ctx) {
ctx.sender().sendMessage(Message.raw("Hello, World!"));
return null; // Return null for synchronous completion
}
});
{{< callout type="info" >}}
Note: Create a dedicated command class by extending AbstractCommand for complex commands. See Creating Commands for details.
{{< /callout >}}
TaskRegistry
Tracks asynchronous tasks for cleanup during plugin shutdown.
{{< callout type="warning" >}}
Important: TaskRegistry does NOT have runAsync(), runSync(), runLater(), or runRepeating() methods. Use Java's standard concurrency APIs instead.
{{< /callout >}}
Methods
| Method | Description |
|---|---|
registerTask(CompletableFuture<Void>) |
Register a CompletableFuture for tracking |
registerTask(ScheduledFuture<Void>) |
Register a ScheduledFuture for tracking |
Example
// Async operation
CompletableFuture<Void> task = CompletableFuture.runAsync(() -> {
// Background work
Data result = heavyComputation();
world.execute(() -> {
playerRef.sendMessage(Message.raw("Done: " + result));
});
});
getTaskRegistry().registerTask(task);
// Delayed operation (3 seconds)
CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS)
.execute(() -> {
world.execute(() -> {
getLogger().at(Level.INFO).log("3 seconds passed!");
});
});
// Repeating operation
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> repeating = scheduler.scheduleAtFixedRate(() -> {
broadcastTime();
}, 0, 5, TimeUnit.MINUTES);
getTaskRegistry().registerTask((ScheduledFuture<Void>) repeating);
AssetRegistry
Registers custom asset stores with the game.
Package: com.hypixel.hytale.server.core.plugin.registry
{{< callout type="warning" >}}
Important: AssetRegistry does NOT provide getItem(), getBlockType(), etc. methods. To access assets, use the asset class's static methods directly.
{{< /callout >}}
Methods
| Method | Description |
|---|---|
register(AssetStore) |
Register a custom AssetStore |
Accessing Assets
Assets are accessed via their class's static methods, not through AssetRegistry:
import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
// Get items by string ID directly (DefaultAssetMap)
DefaultAssetMap<String, Item> itemMap = Item.getAssetMap();
Item sword = itemMap.getAsset("iron_sword");
// Get block types
DefaultAssetMap<String, BlockType> blockMap = BlockType.getAssetMap();
BlockType stone = blockMap.getAsset("stone");
{{< callout type="info" >}}
Note: Most assets like Item and BlockType use DefaultAssetMap where you can access by string key directly. Some assets like Interaction use IndexedLookupTableAssetMap which requires getting the index first.
{{< /callout >}}
Custom Asset Store Registration
AssetRegistry assets = getAssetRegistry();
// Register a custom asset store
assets.register(MyCustomAsset.getAssetStore());
BlockStateRegistry
Manages block states and their properties.
Methods
| Method | Description |
|---|---|
getBlockState(BlockType) |
Get default state |
getBlockState(BlockType, Properties) |
Get state with properties |
Example
BlockStateRegistry blocks = getBlockStateRegistry();
BlockState stone = blocks.getBlockState(stoneType);
world.setBlockState(x, y, z, stone);
Codec Registration
Package: com.hypixel.hytale.server.core.plugin.registry
{{< callout type="warning" >}}
Important: There is no simple CodecRegistry class. Instead, use the typed getCodecRegistry() methods with codec map parameters.
{{< /callout >}}
Methods
| Method | Description |
|---|---|
getCodecRegistry(StringCodecMapCodec) |
Get CodecMapRegistry for string-keyed codecs |
getCodecRegistry(AssetCodecMapCodec) |
Get CodecMapRegistry.Assets for asset codecs |
getCodecRegistry(MapKeyMapCodec) |
Get MapKeyMapRegistry for map-keyed codecs |
Example
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.plugin.registry.CodecMapRegistry;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
// Register a custom interaction type using the Interaction CODEC
CodecMapRegistry.Assets<Interaction, ?> registry =
getCodecRegistry(Interaction.CODEC);
registry.register("MyCustomInteraction", MyCustomInteraction.class, MyCustomInteraction.CODEC);
For simple data serialization, use BuilderCodec directly:
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
// Define a codec for your data class
public static final BuilderCodec<PlayerData> CODEC = BuilderCodec.builder(PlayerData.class, PlayerData::new)
.append(new KeyedCodec<>("name", Codec.STRING),
(obj, val) -> obj.name = val,
obj -> obj.name)
.add()
.build();
EntityRegistry
Registers custom entity types with the game.
Package: com.hypixel.hytale.server.core.modules.entity
{{< callout type="warning" >}}
Important: EntityRegistry is for registering custom entity types, NOT for spawning entities. To spawn entities, use World.spawnEntity().
{{< /callout >}}
Methods
| Method | Description |
|---|---|
registerEntity(String, Class, Function, Codec) |
Register a custom entity type |
Registering Custom Entities
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.codec.DirectDecodeCodec;
EntityRegistry entities = getEntityRegistry();
// Register a custom entity type
entities.registerEntity(
"my_custom_entity",
MyCustomEntity.class,
world -> new MyCustomEntity(world),
MyCustomEntity.CODEC
);
Spawning Entities
To spawn entities at runtime, use World:
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.entity.Entity;
World world = player.getWorld();
// Spawn an entity
Entity entity = world.spawnEntity(entityClass, position);
Registry Access Patterns
Lazy Initialization
public class MyPlugin extends PluginBase {
private EventRegistry events;
private CommandRegistry commands;
@Override
public void start() {
this.events = getEventRegistry();
this.commands = getCommandRegistry();
registerEvents();
registerCommands();
}
private void registerEvents() {
events.register(PlayerConnectEvent.class, this::onJoin);
}
private void registerCommands() {
commands.register(new MyCommand());
}
}
Helper Methods
public class MyPlugin extends JavaPlugin {
public void runOnWorldThread(World world, Runnable task) {
world.execute(task);
}
public void runAsync(Runnable task) {
CompletableFuture.runAsync(task);
}
public Item getItem(String id) {
return getAssetRegistry().getItem(id);
}
}
Thread Safety
{{< callout type="warning" >}} Registry Thread Safety:
- Most registries are designed for world thread access
- Each World runs on its own dedicated thread
- Use
world.execute()when accessing from async code - TaskRegistry is thread-safe for task registration {{< /callout >}}
// Safe async pattern
World world = player.getWorld();
PlayerRef playerRef = player.getPlayerRef();
CompletableFuture.runAsync(() -> {
// Background work
Data result = compute();
// Return to world thread for game state changes
world.execute(() -> {
// Access other registries here safely
EventRegistry events = getEventRegistry();
playerRef.sendMessage(Message.raw("Result: " + result));
});
});