docs: update documentation; patch ChangeActiveSlotInteraction

This commit is contained in:
luk
2026-02-03 16:44:06 +00:00
parent f8d7b9a781
commit 49a80ebf77
16 changed files with 531 additions and 472 deletions

View File

@@ -1,6 +1,7 @@
# Hytale Server API Reference (LLM-Optimized)
This document is a comprehensive API reference for the Hytale Server modding system, optimized for LLM consumption. All class names, method signatures, and JSON structures are validated against the actual codebase.
This document is a comprehensive API reference for the Hytale Server modding system, optimized for LLM consumption. All
class names, method signatures, and JSON structures are validated against the actual codebase.
---
@@ -8,13 +9,13 @@ This document is a comprehensive API reference for the Hytale Server modding sys
### Core Classes
| Class | Package |
|-------|---------|
| `JavaPlugin` | `com.hypixel.hytale.server.core.plugin.JavaPlugin` |
| `PluginBase` | `com.hypixel.hytale.server.core.plugin.PluginBase` |
| `PluginManifest` | `com.hypixel.hytale.common.plugin.PluginManifest` |
| Class | Package |
|------------------|--------------------------------------------------------|
| `JavaPlugin` | `com.hypixel.hytale.server.core.plugin.JavaPlugin` |
| `PluginBase` | `com.hypixel.hytale.server.core.plugin.PluginBase` |
| `PluginManifest` | `com.hypixel.hytale.common.plugin.PluginManifest` |
| `JavaPluginInit` | `com.hypixel.hytale.server.core.plugin.JavaPluginInit` |
| `PluginState` | `com.hypixel.hytale.server.core.plugin.PluginState` |
| `PluginState` | `com.hypixel.hytale.server.core.plugin.PluginState` |
### Plugin Lifecycle
@@ -23,8 +24,9 @@ PluginState: NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
```
**Lifecycle Methods (exact names):**
- `setup()` - Called during initialization, register components here
- `start()` - Called after setup, plugin becomes active
- `start()` - Called after setup, plugin becomes active
- `shutdown()` - Called during server stop/plugin disable
### Plugin Manifest JSON (exact field names, case-sensitive)
@@ -50,17 +52,17 @@ PluginState: NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
### Registry Methods on PluginBase
| Method | Return Type |
|--------|-------------|
| `getClientFeatureRegistry()` | `ClientFeatureRegistry` |
| `getCommandRegistry()` | `CommandRegistry` |
| `getEventRegistry()` | `EventRegistry` |
| `getBlockStateRegistry()` | `BlockStateRegistry` |
| `getEntityRegistry()` | `EntityRegistry` |
| `getTaskRegistry()` | `TaskRegistry` |
| `getEntityStoreRegistry()` | `ComponentRegistryProxy<EntityStore>` |
| `getChunkStoreRegistry()` | `ComponentRegistryProxy<ChunkStore>` |
| `getAssetRegistry()` | `AssetRegistry` |
| Method | Return Type |
|------------------------------|---------------------------------------|
| `getClientFeatureRegistry()` | `ClientFeatureRegistry` |
| `getCommandRegistry()` | `CommandRegistry` |
| `getEventRegistry()` | `EventRegistry` |
| `getBlockStateRegistry()` | `BlockStateRegistry` |
| `getEntityRegistry()` | `EntityRegistry` |
| `getTaskRegistry()` | `TaskRegistry` |
| `getEntityStoreRegistry()` | `ComponentRegistryProxy<EntityStore>` |
| `getChunkStoreRegistry()` | `ComponentRegistryProxy<ChunkStore>` |
| `getAssetRegistry()` | `AssetRegistry` |
### Configuration Pattern
@@ -79,13 +81,13 @@ MyConfig cfg = config.get();
### Core Interfaces (Package: `com.hypixel.hytale.event`)
| Interface | Description |
|-----------|-------------|
| `IBaseEvent<KeyType>` | Base event interface |
| `IEvent<KeyType>` | Synchronous event, extends IBaseEvent |
| `IAsyncEvent<KeyType>` | Async event, extends IBaseEvent |
| `ICancellable` | Mixin: `isCancelled()`, `setCancelled(boolean)` |
| `IProcessedEvent` | Mixin: `processEvent(String)` |
| Interface | Description |
|------------------------|-------------------------------------------------|
| `IBaseEvent<KeyType>` | Base event interface |
| `IEvent<KeyType>` | Synchronous event, extends IBaseEvent |
| `IAsyncEvent<KeyType>` | Async event, extends IBaseEvent |
| `ICancellable` | Mixin: `isCancelled()`, `setCancelled(boolean)` |
| `IProcessedEvent` | Mixin: `processEvent(String)` |
### EventPriority (exact values)
@@ -100,6 +102,7 @@ LAST = (short)21844 // Runs last
### EventRegistry Methods (IEventRegistry interface)
**Sync Registration:**
```java
// Without key (Void key)
EventRegistration register(Class<? super EventType> eventClass, Consumer<EventType> consumer)
@@ -111,17 +114,20 @@ EventRegistration register(EventPriority priority, Class<? super EventType> even
```
**Global Registration (receives all keys):**
```java
EventRegistration registerGlobal(Class<? super EventType> eventClass, Consumer<EventType> consumer)
EventRegistration registerGlobal(EventPriority priority, Class<? super EventType> eventClass, Consumer<EventType> consumer)
```
**Unhandled Registration (when no other handler processed):**
```java
EventRegistration registerUnhandled(Class<? super EventType> eventClass, Consumer<EventType> consumer)
```
**Async Registration:**
```java
EventRegistration registerAsync(Class<? super EventType> eventClass, Function<CompletableFuture<EventType>, CompletableFuture<EventType>> function)
EventRegistration registerAsyncGlobal(...)
@@ -131,11 +137,13 @@ EventRegistration registerAsyncUnhandled(...)
### Key Event Classes
**Server Events (`com.hypixel.hytale.server.core.event.events`):**
- `BootEvent` - IEvent<Void>
- `ShutdownEvent` - IEvent<Void>
- `PrepareUniverseEvent` - IEvent<Void>
**Player Events (`...event.events.player`):**
- `PlayerConnectEvent` - IEvent<Void>
- `PlayerSetupConnectEvent` - IEvent<Void>, ICancellable
- `PlayerDisconnectEvent` - PlayerRefEvent<Void>
@@ -146,12 +154,14 @@ EventRegistration registerAsyncUnhandled(...)
- `DrainPlayerFromWorldEvent` - IEvent<String>
**World Events (`...universe.world.events`):**
- `AddWorldEvent` - WorldEvent, ICancellable
- `RemoveWorldEvent` - WorldEvent, ICancellable
- `StartWorldEvent` - WorldEvent
- `AllWorldsLoadedEvent` - IEvent<Void>
**ECS Events (`...event.events.ecs`):**
- `BreakBlockEvent` - CancellableEcsEvent
- `PlaceBlockEvent` - CancellableEcsEvent
- `UseBlockEvent` - EcsEvent (with nested `Pre` implementing ICancellableEcsEvent)
@@ -164,16 +174,16 @@ EventRegistration registerAsyncUnhandled(...)
### Core Classes (Package: `com.hypixel.hytale.server.core.command.system`)
| Class | Description |
|-------|-------------|
| `AbstractCommand` | Base command class |
| `CommandRegistry` | Plugin command registration |
| `CommandContext` | Execution context |
| `CommandBase` | Sync command base (override `executeSync`) |
| `AbstractAsyncCommand` | Async command base |
| `AbstractPlayerCommand` | Player-required command |
| `AbstractWorldCommand` | World context command |
| `AbstractCommandCollection` | Parent with subcommands only |
| Class | Description |
|-----------------------------|--------------------------------------------|
| `AbstractCommand` | Base command class |
| `CommandRegistry` | Plugin command registration |
| `CommandContext` | Execution context |
| `CommandBase` | Sync command base (override `executeSync`) |
| `AbstractAsyncCommand` | Async command base |
| `AbstractPlayerCommand` | Player-required command |
| `AbstractWorldCommand` | World context command |
| `AbstractCommandCollection` | Parent with subcommands only |
### AbstractCommand Key Methods
@@ -231,15 +241,15 @@ ArgTypes.forEnum(String name, Class<E> enumClass) // Create enum type
### Core Classes (Package: `com.hypixel.hytale.component`)
| Class | Description |
|-------|-------------|
| `Component<ECS_TYPE>` | Base component interface |
| `ComponentRegistry` | Component type registration |
| `ComponentType<ECS_TYPE, T>` | Registered component type |
| `Store` | ECS data storage |
| `Ref` | Entity reference (ID) |
| `Holder` | Component holder for entity construction |
| `Query` | Entity filtering |
| Class | Description |
|------------------------------|------------------------------------------|
| `Component<ECS_TYPE>` | Base component interface |
| `ComponentRegistry` | Component type registration |
| `ComponentType<ECS_TYPE, T>` | Registered component type |
| `Store` | ECS data storage |
| `Ref` | Entity reference (ID) |
| `Holder` | Component holder for entity construction |
| `Query` | Entity filtering |
### Entity Hierarchy
@@ -264,33 +274,39 @@ void registerSystem(ISystem<EntityStore> system)
### Key Built-in Components
**Transform/Position:**
- `TransformComponent` - Position (Vector3d) and rotation (Vector3f)
- `HeadRotation` - Head rotation angles
- `EntityScaleComponent` - Scale modifier
**Physics:**
- `Velocity` - Velocity vector
- `BoundingBox` - Collision box
- `CollisionResultComponent` - Collision results
- `MovementStatesComponent` - Movement flags (onGround, swimming, etc.)
**Identity:**
- `UUIDComponent` - Unique identifier
- `NetworkId` - Network sync ID
- `DisplayNameComponent` - Display name
**Visual:**
- `ModelComponent` - 3D model reference
- `ActiveAnimationComponent` - Current animations
- `DynamicLight` - Dynamic lighting
**State Flags:**
- `Invulnerable` - Immune to damage
- `Intangible` - Non-collidable
- `Interactable` - Can be interacted with
- `Frozen` - Frozen state
**Player-specific:**
- `Player` - Core player component
- `PlayerRef` - Network connection reference
- `ChunkTracker` - Loaded chunks tracking
@@ -323,14 +339,14 @@ Ref<EntityStore> ref = store.addEntity(holder, AddReason.SPAWN);
### Page System Classes
| Class | Package |
|-------|---------|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages.CustomUIPage` |
| `BasicCustomUIPage` | Same package - no event data parsing |
| `InteractiveCustomUIPage<T>` | Same package - typed event handling |
| `PageManager` | Same package - page lifecycle |
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder.UICommandBuilder` |
| `UIEventBuilder` | `com.hypixel.hytale.server.core.ui.builder.UIEventBuilder` |
| Class | Package |
|------------------------------|----------------------------------------------------------------------------|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages.CustomUIPage` |
| `BasicCustomUIPage` | Same package - no event data parsing |
| `InteractiveCustomUIPage<T>` | Same package - typed event handling |
| `PageManager` | Same package - page lifecycle |
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder.UICommandBuilder` |
| `UIEventBuilder` | `com.hypixel.hytale.server.core.ui.builder.UIEventBuilder` |
### CustomPageLifetime
@@ -437,11 +453,11 @@ player.getPageManager().openCustomPage(ref, store, new MyPage(playerRef));
### Window System
| Class | Package |
|-------|---------|
| `Window` | `com.hypixel.hytale.server.core.entity.entities.player.windows.Window` |
| `WindowManager` | Same package |
| `ContainerWindow`, `CraftingWindow`, etc. | Same package |
| Class | Package |
|-------------------------------------------|------------------------------------------------------------------------|
| `Window` | `com.hypixel.hytale.server.core.entity.entities.player.windows.Window` |
| `WindowManager` | Same package |
| `ContainerWindow`, `CraftingWindow`, etc. | Same package |
### WindowType
@@ -456,11 +472,11 @@ DiagramCrafting(3), StructuralCrafting(4), Processing(5), Memories(6)
### Core Classes (Package: `com.hypixel.hytale.codec`)
| Class | Description |
|-------|-------------|
| `Codec<T>` | Base codec interface |
| `BuilderCodec<T>` | Builder-based codec |
| `KeyedCodec<T>` | Key-value codec |
| Class | Description |
|-------------------|----------------------|
| `Codec<T>` | Base codec interface |
| `BuilderCodec<T>` | Builder-based codec |
| `KeyedCodec<T>` | Key-value codec |
### Primitive Codecs
@@ -503,39 +519,45 @@ Codec<MyEnum> ENUM = Codec.enumCodec(MyEnum.class);
### Core Classes
| Class | Package |
|-------|---------|
| `JsonAsset<K>` | `com.hypixel.hytale.assetstore.JsonAsset` |
| `AssetStore<K,T,M>` | `com.hypixel.hytale.assetstore.AssetStore` |
| `AssetRegistry` | `com.hypixel.hytale.server.core.plugin.AssetRegistry` |
| Class | Package |
|---------------------|-------------------------------------------------------|
| `JsonAsset<K>` | `com.hypixel.hytale.assetstore.JsonAsset` |
| `AssetStore<K,T,M>` | `com.hypixel.hytale.assetstore.AssetStore` |
| `AssetRegistry` | `com.hypixel.hytale.server.core.plugin.AssetRegistry` |
### Key Asset Types (Package: `com.hypixel.hytale.server.core.asset.type`)
**Blocks:**
- `BlockType` - blocktype.config.BlockType
- `BlockSet` - blockset.config.BlockSet
- `BlockSoundSet` - blocksound.config.BlockSoundSet
**Items:**
- `Item` - item.config.Item
- `ItemCategory` - item.config.ItemCategory
- `CraftingRecipe` - item.config.CraftingRecipe
**Visual:**
- `ModelAsset` - model.config.ModelAsset
- `ParticleSystem` - particle.config.ParticleSystem
- `EntityEffect` - entityeffect.config.EntityEffect
**Audio:**
- `SoundEvent` - soundevent.config.SoundEvent
- `SoundSet` - soundset.config.SoundSet
**Environment:**
- `Environment` - environment.config.Environment
- `Weather` - weather.config.Weather
- `Fluid` - fluid.Fluid
**Gameplay:**
- `Projectile` - projectile.config.Projectile
- `GameplayConfig` - gameplay.GameplayConfig
@@ -556,12 +578,12 @@ Codec<MyEnum> ENUM = Codec.enumCodec(MyEnum.class);
### Core Classes
| Class | Package |
|-------|---------|
| `Universe` | `com.hypixel.hytale.server.core.universe.Universe` |
| `World` | `com.hypixel.hytale.server.core.universe.world.World` |
| Class | Package |
|---------------|---------------------------------------------------------------------|
| `Universe` | `com.hypixel.hytale.server.core.universe.Universe` |
| `World` | `com.hypixel.hytale.server.core.universe.world.World` |
| `EntityStore` | `com.hypixel.hytale.server.core.universe.world.storage.EntityStore` |
| `ChunkStore` | `com.hypixel.hytale.server.core.universe.world.storage.ChunkStore` |
| `ChunkStore` | `com.hypixel.hytale.server.core.universe.world.storage.ChunkStore` |
### Universe Access
@@ -590,12 +612,12 @@ boolean paused = world.isPaused();
### Core Classes (Package: `com.hypixel.hytale.server.npc`)
| Class | Description |
|-------|-------------|
| `NPCEntity` | entities.NPCEntity - NPC entity class |
| `Role` | role.Role - Behavior definition |
| Class | Description |
|---------------|--------------------------------------------|
| `NPCEntity` | entities.NPCEntity - NPC entity class |
| `Role` | role.Role - Behavior definition |
| `Instruction` | instructions.Instruction - Behavior action |
| `PathManager` | navigation.PathManager - Pathfinding |
| `PathManager` | navigation.PathManager - Pathfinding |
### NPCEntity Key Methods
@@ -610,9 +632,9 @@ void playAnimation(...)
### Flock System (Package: `com.hypixel.hytale.server.flock`)
| Component | Description |
|-----------|-------------|
| `Flock` | Flock leader/group |
| Component | Description |
|-------------------|---------------------------|
| `Flock` | Flock leader/group |
| `FlockMembership` | Entity's flock membership |
---
@@ -621,9 +643,9 @@ void playAnimation(...)
### Packet System (Package: `com.hypixel.hytale.protocol`)
| Class | Description |
|-------|-------------|
| `Packet` | Base packet interface |
| Class | Description |
|------------------|--------------------------|
| `Packet` | Base packet interface |
| `PacketRegistry` | Packet type registration |
### Key Packet Categories (`protocol.packets.*`)
@@ -639,22 +661,22 @@ void playAnimation(...)
### UI Packets
| Packet | ID | Direction |
|--------|-----|-----------|
| `SetPage` | 216 | S->C |
| `CustomHud` | 217 | S->C |
| `CustomPage` | 218 | S->C |
| `CustomPageEvent` | 219 | C->S |
| Packet | ID | Direction |
|-------------------|-----|-----------|
| `SetPage` | 216 | S->C |
| `CustomHud` | 217 | S->C |
| `CustomPage` | 218 | S->C |
| `CustomPageEvent` | 219 | C->S |
### Window Packets
| Packet | ID | Direction |
|--------|-----|-----------|
| `OpenWindow` | 200 | S->C |
| `UpdateWindow` | 201 | S->C |
| `CloseWindow` | 202 | S->C |
| `ClientOpenWindow` | 203 | C->S |
| `SendWindowAction` | 204 | C->S |
| Packet | ID | Direction |
|--------------------|-----|-----------|
| `OpenWindow` | 200 | S->C |
| `UpdateWindow` | 201 | S->C |
| `CloseWindow` | 202 | S->C |
| `ClientOpenWindow` | 203 | C->S |
| `SendWindowAction` | 204 | C->S |
---
@@ -724,23 +746,29 @@ Place JAR in `earlyplugins/` directory.
### EntityStore Components (130+)
**Transform:** TransformComponent, HeadRotation, PositionDataComponent, EntityScaleComponent, RotateObjectComponent, SnapshotBuffer
**Transform:** TransformComponent, HeadRotation, PositionDataComponent, EntityScaleComponent, RotateObjectComponent,
SnapshotBuffer
**Physics:** Velocity, PhysicsValues, BoundingBox, CollisionResultComponent, KnockbackComponent, MovementStatesComponent, HitboxCollision, Repulsion
**Physics:** Velocity, PhysicsValues, BoundingBox, CollisionResultComponent, KnockbackComponent,
MovementStatesComponent, HitboxCollision, Repulsion
**Player:** Player, MovementManager, CameraManager, ChunkTracker, PlayerInput, PlayerSettings, PlayerSkinComponent, PlayerRef
**Player:** Player, MovementManager, CameraManager, ChunkTracker, PlayerInput, PlayerSettings, PlayerSkinComponent,
PlayerRef
**NPC:** NPCEntity, ValueStore, StateEvaluator, StepComponent, Timers, FailedSpawnComponent
**Combat:** DamageDataComponent, DeathComponent, DeferredCorpseRemoval, CombatActionEvaluator, TargetMemory, DamageMemory
**Combat:** DamageDataComponent, DeathComponent, DeferredCorpseRemoval, CombatActionEvaluator, TargetMemory,
DamageMemory
**Visual:** ModelComponent, PersistentModel, PropComponent, DisplayNameComponent, ActiveAnimationComponent, DynamicLight, Nameplate
**Visual:** ModelComponent, PersistentModel, PropComponent, DisplayNameComponent, ActiveAnimationComponent,
DynamicLight, Nameplate
**Audio:** AudioComponent, MovementAudioComponent
**Identity:** UUIDComponent, NetworkId, EntityViewer, Visible, PersistentRefCount
**State Flags:** Frozen, Intangible, Invulnerable, Interactable, RespondToHit, HiddenFromAdventurePlayers, NewSpawnComponent, FromPrefab, FromWorldGen, DespawnComponent
**State Flags:** Frozen, Intangible, Invulnerable, Interactable, RespondToHit, HiddenFromAdventurePlayers,
NewSpawnComponent, FromPrefab, FromWorldGen, DespawnComponent
**Teleport:** Teleport, PendingTeleport, TeleportHistory, WarpComponent
@@ -762,7 +790,8 @@ Place JAR in `earlyplugins/` directory.
### ChunkStore Components (25+)
**Structure:** BlockChunk, BlockComponentChunk, EntityChunk, ChunkColumn, ChunkSection, BlockSection, FluidSection, EnvironmentChunk
**Structure:** BlockChunk, BlockComponentChunk, EntityChunk, ChunkColumn, ChunkSection, BlockSection, FluidSection,
EnvironmentChunk
**Block State:** BlockState, RespawnBlock, LaunchPad, BlockMapMarker

View File

@@ -2,21 +2,22 @@
## Overview
The Hytale Server provides a comprehensive modding API that allows developers to extend and customize the game. This documentation covers the essential systems and APIs available for mod development.
The Hytale Server provides a comprehensive modding API that allows developers to extend and customize the game. This
documentation covers the essential systems and APIs available for mod development.
## Architecture Overview
The server is built on several core systems:
| System | Purpose |
|--------|---------|
| Plugin System | Mod loading, lifecycle management, and dependency resolution |
| System | Purpose |
|-------------------------------|----------------------------------------------------------------|
| Plugin System | Mod loading, lifecycle management, and dependency resolution |
| Entity Component System (ECS) | High-performance entity management with components and systems |
| Event System | Prioritized event dispatching with sync/async support |
| Command System | Player and console command handling |
| Asset System | Game asset loading and registration |
| Codec System | Data serialization/deserialization framework |
| Protocol Layer | Network communication and packet handling |
| Event System | Prioritized event dispatching with sync/async support |
| Command System | Player and console command handling |
| Asset System | Game asset loading and registration |
| Codec System | Data serialization/deserialization framework |
| Protocol Layer | Network communication and packet handling |
## Package Structure
@@ -121,17 +122,17 @@ Plugins go through the following states:
Your plugin has access to several registries for registration:
| Registry | Access Method | Purpose |
|----------|---------------|---------|
| CommandRegistry | `getCommandRegistry()` | Register custom commands |
| EventRegistry | `getEventRegistry()` | Register event listeners |
| EntityRegistry | `getEntityRegistry()` | Register custom entity types |
| BlockStateRegistry | `getBlockStateRegistry()` | Register block states |
| TaskRegistry | `getTaskRegistry()` | Schedule recurring tasks |
| AssetRegistry | `getAssetRegistry()` | Register custom asset types |
| Registry | Access Method | Purpose |
|-----------------------|------------------------------|-------------------------------|
| CommandRegistry | `getCommandRegistry()` | Register custom commands |
| EventRegistry | `getEventRegistry()` | Register event listeners |
| EntityRegistry | `getEntityRegistry()` | Register custom entity types |
| BlockStateRegistry | `getBlockStateRegistry()` | Register block states |
| TaskRegistry | `getTaskRegistry()` | Schedule recurring tasks |
| AssetRegistry | `getAssetRegistry()` | Register custom asset types |
| ClientFeatureRegistry | `getClientFeatureRegistry()` | Register client-side features |
| EntityStoreRegistry | `getEntityStoreRegistry()` | Register ECS entity stores |
| ChunkStoreRegistry | `getChunkStoreRegistry()` | Register chunk data stores |
| EntityStoreRegistry | `getEntityStoreRegistry()` | Register ECS entity stores |
| ChunkStoreRegistry | `getChunkStoreRegistry()` | Register chunk data stores |
## Next Steps

View File

@@ -36,25 +36,26 @@ The `manifest.json` file must be placed at the root of your JAR:
### Manifest Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `Group` | String | Yes | Maven-style group ID (e.g., `com.example`) |
| `Name` | String | Yes | Plugin name (unique identifier within group) |
| `Version` | String | Yes | Semantic version (e.g., `1.0.0`) |
| `Description` | String | No | Brief description of the plugin |
| `Authors` | String[] | No | List of author names |
| `Website` | String | No | Plugin website or repository URL |
| `Main` | String | Yes | Fully qualified main class name |
| `ServerVersion` | String | No | Required server version range |
| `Dependencies` | Object | No | Required plugin dependencies with version ranges |
| `OptionalDependencies` | Object | No | Optional plugin dependencies |
| `LoadBefore` | String[] | No | Plugins that should load after this one |
| `DisabledByDefault` | Boolean | No | If true, plugin must be explicitly enabled |
| `IncludesAssetPack` | Boolean | No | If true, plugin includes client assets |
| Field | Type | Required | Description |
|------------------------|----------|----------|--------------------------------------------------|
| `Group` | String | Yes | Maven-style group ID (e.g., `com.example`) |
| `Name` | String | Yes | Plugin name (unique identifier within group) |
| `Version` | String | Yes | Semantic version (e.g., `1.0.0`) |
| `Description` | String | No | Brief description of the plugin |
| `Authors` | String[] | No | List of author names |
| `Website` | String | No | Plugin website or repository URL |
| `Main` | String | Yes | Fully qualified main class name |
| `ServerVersion` | String | No | Required server version range |
| `Dependencies` | Object | No | Required plugin dependencies with version ranges |
| `OptionalDependencies` | Object | No | Optional plugin dependencies |
| `LoadBefore` | String[] | No | Plugins that should load after this one |
| `DisabledByDefault` | Boolean | No | If true, plugin must be explicitly enabled |
| `IncludesAssetPack` | Boolean | No | If true, plugin includes client assets |
### Plugin Identifier
Plugins are identified by `Group:Name` format (e.g., `com.example:MyPlugin`). This identifier is used for:
- Dependency resolution
- Permission namespacing (`com.example.myplugin.*`)
- Configuration keys
@@ -121,14 +122,14 @@ public class MyPlugin extends JavaPlugin {
NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
```
| State | Description |
|-------|-------------|
| `NONE` | Initial state before any lifecycle methods |
| `SETUP` | `setup()` is executing; register components here |
| `START` | `start()` is executing; plugin becoming active |
| `ENABLED` | Plugin is fully operational and handling events |
| `SHUTDOWN` | `shutdown()` is executing; cleanup in progress |
| `DISABLED` | Plugin is fully disabled and unloaded |
| State | Description |
|------------|--------------------------------------------------|
| `NONE` | Initial state before any lifecycle methods |
| `SETUP` | `setup()` is executing; register components here |
| `START` | `start()` is executing; plugin becoming active |
| `ENABLED` | Plugin is fully operational and handling events |
| `SHUTDOWN` | `shutdown()` is executing; cleanup in progress |
| `DISABLED` | Plugin is fully disabled and unloaded |
## Configuration
@@ -267,6 +268,7 @@ Commands registered by your plugin will have permissions under:
```
For example, if your plugin is `com.example:MyPlugin` and you register a command `spawn`:
- Base permission: `com.example.myplugin`
- Command permission: `com.example.myplugin.command.spawn`

View File

@@ -1,6 +1,7 @@
# Event System
The Hytale event system provides a powerful mechanism for plugins to react to game events. It supports both synchronous and asynchronous events with priority-based dispatching.
The Hytale event system provides a powerful mechanism for plugins to react to game events. It supports both synchronous
and asynchronous events with priority-based dispatching.
## Event Architecture
@@ -16,28 +17,29 @@ ICancellable // Mixin interface for cancellable events
### Key Classes
| Class | Description |
|-------|-------------|
| `IEvent<K>` | Synchronous event interface |
| `IAsyncEvent<K>` | Asynchronous event interface |
| `ICancellable` | Interface for events that can be cancelled |
| `EventRegistry` | Plugin-specific event registration |
| `SyncEventBusRegistry` | Global synchronous event bus |
| `EventPriority` | Event listener priority levels |
| Class | Description |
|------------------------|--------------------------------------------|
| `IEvent<K>` | Synchronous event interface |
| `IAsyncEvent<K>` | Asynchronous event interface |
| `ICancellable` | Interface for events that can be cancelled |
| `EventRegistry` | Plugin-specific event registration |
| `SyncEventBusRegistry` | Global synchronous event bus |
| `EventPriority` | Event listener priority levels |
## Event Priorities
Events are dispatched to listeners in priority order:
| Priority | Value | Description |
|----------|-------|-------------|
| `FIRST` | -21844 | Runs first, before all others |
| `EARLY` | -10922 | Runs early, after FIRST |
| `NORMAL` | 0 | Default priority |
| `LATE` | 10922 | Runs late, after NORMAL |
| `LAST` | 21844 | Runs last, after all others |
| Priority | Value | Description |
|----------|--------|-------------------------------|
| `FIRST` | -21844 | Runs first, before all others |
| `EARLY` | -10922 | Runs early, after FIRST |
| `NORMAL` | 0 | Default priority |
| `LATE` | 10922 | Runs late, after NORMAL |
| `LAST` | 21844 | Runs last, after all others |
Lower values run first. Use `FIRST` sparingly - typically for monitoring/logging. Use `LAST` for final processing after other plugins have had a chance to modify the event.
Lower values run first. Use `FIRST` sparingly - typically for monitoring/logging. Use `LAST` for final processing after
other plugins have had a chance to modify the event.
## Registering Event Listeners
@@ -148,45 +150,45 @@ getEventRegistry().register(EventPriority.LAST, PlayerInteractEvent.class, event
### Server Lifecycle Events
| Event | Description |
|-------|-------------|
| `BootEvent` | Server boot complete |
| `ShutdownEvent` | Server shutting down |
| Event | Description |
|------------------------|-------------------------|
| `BootEvent` | Server boot complete |
| `ShutdownEvent` | Server shutting down |
| `PrepareUniverseEvent` | Universe initialization |
### Player Events
| Event | Description |
|-------|-------------|
| `PlayerConnectEvent` | Player connected to server |
| `PlayerDisconnectEvent` | Player disconnected |
| `AddPlayerToWorldEvent` | Player added to a world |
| `DrainPlayerFromWorldEvent` | Player removed from a world |
| `PlayerInteractEvent` | Player interaction (cancellable) |
| `PlayerMouseButtonEvent` | Mouse button input (cancellable) |
| Event | Description |
|-----------------------------|----------------------------------|
| `PlayerConnectEvent` | Player connected to server |
| `PlayerDisconnectEvent` | Player disconnected |
| `AddPlayerToWorldEvent` | Player added to a world |
| `DrainPlayerFromWorldEvent` | Player removed from a world |
| `PlayerInteractEvent` | Player interaction (cancellable) |
| `PlayerMouseButtonEvent` | Mouse button input (cancellable) |
### Entity Events
| Event | Description |
|-------|-------------|
| `EntityRemoveEvent` | Entity removed from world |
| Event | Description |
|-----------------------------|-----------------------------|
| `EntityRemoveEvent` | Entity removed from world |
| `LivingEntityUseBlockEvent` | Living entity using a block |
### World Events
| Event | Description |
|-------|-------------|
| `AddWorldEvent` | World added to universe |
| `RemoveWorldEvent` | World removed |
| `StartWorldEvent` | World started |
| Event | Description |
|------------------------|-----------------------------|
| `AddWorldEvent` | World added to universe |
| `RemoveWorldEvent` | World removed |
| `StartWorldEvent` | World started |
| `AllWorldsLoadedEvent` | All worlds finished loading |
### ECS Events
| Event | Description |
|-------|-------------|
| `UseBlockEvent` | Block usage event |
| `DiscoverZoneEvent` | Zone discovery |
| Event | Description |
|---------------------|-------------------|
| `UseBlockEvent` | Block usage event |
| `DiscoverZoneEvent` | Zone discovery |
## Creating Custom Events

View File

@@ -4,7 +4,8 @@ The Hytale command system allows plugins to register custom commands that can be
## Overview
Commands are defined by extending `AbstractCommand` and registered through the plugin's `CommandRegistry`. The system supports:
Commands are defined by extending `AbstractCommand` and registered through the plugin's `CommandRegistry`. The system
supports:
- Required and optional arguments
- Subcommands
@@ -270,6 +271,7 @@ Commands automatically receive permissions based on the plugin's base permission
```
For example, if your plugin is `com.example:MyPlugin` and command is `spawn`:
- Permission: `com.example.myplugin.command.spawn`
### Custom Permissions
@@ -303,10 +305,10 @@ public void execute(CommandContext context, Arguments args) {
Commands can be executed by different sender types:
| Sender Type | Description |
|-------------|-------------|
| `Player` | In-game player |
| `Console` | Server console |
| Sender Type | Description |
|----------------|-------------------------------|
| `Player` | In-game player |
| `Console` | Server console |
| `CommandBlock` | Command block (if applicable) |
```java

View File

@@ -1,6 +1,7 @@
# Entity Component System (ECS)
The Hytale server uses an Entity Component System architecture for managing game entities. This provides high performance and flexibility for handling large numbers of entities with varied behaviors.
The Hytale server uses an Entity Component System architecture for managing game entities. This provides high
performance and flexibility for handling large numbers of entities with varied behaviors.
## ECS Concepts
@@ -16,16 +17,16 @@ The ECS pattern separates data (Components) from behavior (Systems):
### Key Classes
| Class | Description |
|-------|-------------|
| `Component<S>` | Base component interface |
| Class | Description |
|---------------------|--------------------------------------|
| `Component<S>` | Base component interface |
| `ComponentRegistry` | Central registry for component types |
| `Store` | ECS data storage |
| `Ref` | Entity reference (ID wrapper) |
| `Holder<C>` | Component holder/accessor |
| `Archetype` | Entity archetype definition |
| `SystemType` | System type definition |
| `Query` | ECS query for finding entities |
| `Store` | ECS data storage |
| `Ref` | Entity reference (ID wrapper) |
| `Holder<C>` | Component holder/accessor |
| `Archetype` | Entity archetype definition |
| `SystemType` | System type definition |
| `Query` | ECS query for finding entities |
## Components
@@ -80,14 +81,14 @@ public class HealthComponent implements Component<EntityStore> {
The server provides several built-in components in `EntityStore.REGISTRY`:
| Component | Description |
|-----------|-------------|
| `TransformComponent` | Position, rotation, and scale |
| `UUIDComponent` | Unique entity identifier |
| `ModelComponent` | Visual model reference |
| `MovementAudioComponent` | Movement sound effects |
| `PositionDataComponent` | Position tracking data |
| `HeadRotation` | Head rotation for living entities |
| Component | Description |
|--------------------------|-----------------------------------|
| `TransformComponent` | Position, rotation, and scale |
| `UUIDComponent` | Unique entity identifier |
| `ModelComponent` | Visual model reference |
| `MovementAudioComponent` | Movement sound effects |
| `PositionDataComponent` | Position tracking data |
| `HeadRotation` | Head rotation for living entities |
### Registering Components

View File

@@ -1,6 +1,7 @@
# World Management
The Hytale server supports multiple worlds within a single universe. This guide covers world management, chunk handling, and related systems.
The Hytale server supports multiple worlds within a single universe. This guide covers world management, chunk handling,
and related systems.
## Universe

View File

@@ -1,6 +1,7 @@
# Networking and Protocol
The Hytale server uses a packet-based networking system for client-server communication. This guide covers the protocol system, packet types, and how to work with networking in your mods.
The Hytale server uses a packet-based networking system for client-server communication. This guide covers the protocol
system, packet types, and how to work with networking in your mods.
## Overview
@@ -15,36 +16,36 @@ The networking layer is built on QUIC protocol and handles:
## Key Components
| Component | Description |
|-----------|-------------|
| `Packet` | Base interface for all packets |
| `PacketRegistry` | Central packet type registration |
| `PacketHandler` | Manages client connections and packet processing |
| `ServerManager` | Server network manager |
| Component | Description |
|------------------|--------------------------------------------------|
| `Packet` | Base interface for all packets |
| `PacketRegistry` | Central packet type registration |
| `PacketHandler` | Manages client connections and packet processing |
| `ServerManager` | Server network manager |
## Packet Categories
Packets are organized into categories in `com.hypixel.hytale.protocol.packets`:
| Category | Description |
|----------|-------------|
| `connection/` | Connection lifecycle (connect, disconnect, ping) |
| `auth/` | Authentication and session management |
| `player/` | Player-specific packets (movement, actions) |
| `entities/` | Entity creation, updates, removal |
| `world/` | World/chunk data streaming |
| `inventory/` | Inventory operations |
| `interaction/` | Player interactions |
| `interface_/` | UI/interface packets |
| `camera/` | Camera control |
| `setup/` | Initial setup and configuration |
| `window/` | Window/container management |
| `assets/` | Asset loading and management |
| `asseteditor/` | Asset editor tools (dev) |
| `buildertools/` | Building tools |
| `machinima/` | Machinima/cinematic tools |
| `serveraccess/` | Server access control |
| `worldmap/` | World map data |
| Category | Description |
|-----------------|--------------------------------------------------|
| `connection/` | Connection lifecycle (connect, disconnect, ping) |
| `auth/` | Authentication and session management |
| `player/` | Player-specific packets (movement, actions) |
| `entities/` | Entity creation, updates, removal |
| `world/` | World/chunk data streaming |
| `inventory/` | Inventory operations |
| `interaction/` | Player interactions |
| `interface_/` | UI/interface packets |
| `camera/` | Camera control |
| `setup/` | Initial setup and configuration |
| `window/` | Window/container management |
| `assets/` | Asset loading and management |
| `asseteditor/` | Asset editor tools (dev) |
| `buildertools/` | Building tools |
| `machinima/` | Machinima/cinematic tools |
| `serveraccess/` | Server access control |
| `worldmap/` | World map data |
## Packet Structure
@@ -163,45 +164,45 @@ for (Player player : Universe.get().getPlayers()) {
### Connection Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `ConnectionRequestPacket` | C->S | Client requests connection |
| `ConnectionResponsePacket` | S->C | Server accepts/rejects connection |
| `DisconnectPacket` | Both | Connection termination |
| `PingPacket` | Both | Latency measurement |
| Packet | Direction | Description |
|----------------------------|-----------|-----------------------------------|
| `ConnectionRequestPacket` | C->S | Client requests connection |
| `ConnectionResponsePacket` | S->C | Server accepts/rejects connection |
| `DisconnectPacket` | Both | Connection termination |
| `PingPacket` | Both | Latency measurement |
### Player Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `PlayerPositionPacket` | Both | Position update |
| `PlayerInputPacket` | C->S | Player input (movement, actions) |
| `PlayerActionPacket` | C->S | Player actions |
| Packet | Direction | Description |
|------------------------|-----------|----------------------------------|
| `PlayerPositionPacket` | Both | Position update |
| `PlayerInputPacket` | C->S | Player input (movement, actions) |
| `PlayerActionPacket` | C->S | Player actions |
### Entity Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `EntitySpawnPacket` | S->C | Entity creation |
| `EntityUpdatePacket` | S->C | Entity state update |
| `EntityRemovePacket` | S->C | Entity removal |
| `EntityMovePacket` | S->C | Entity movement |
| Packet | Direction | Description |
|----------------------|-----------|---------------------|
| `EntitySpawnPacket` | S->C | Entity creation |
| `EntityUpdatePacket` | S->C | Entity state update |
| `EntityRemovePacket` | S->C | Entity removal |
| `EntityMovePacket` | S->C | Entity movement |
### World Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `ChunkDataPacket` | S->C | Chunk data transfer |
| `BlockChangePacket` | S->C | Block state change |
| `WorldTimePacket` | S->C | World time sync |
| Packet | Direction | Description |
|---------------------|-----------|---------------------|
| `ChunkDataPacket` | S->C | Chunk data transfer |
| `BlockChangePacket` | S->C | Block state change |
| `WorldTimePacket` | S->C | World time sync |
### Inventory Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `InventoryUpdatePacket` | S->C | Inventory contents |
| `SlotChangePacket` | Both | Single slot update |
| `ItemPickupPacket` | S->C | Item pickup notification |
| Packet | Direction | Description |
|-------------------------|-----------|--------------------------|
| `InventoryUpdatePacket` | S->C | Inventory contents |
| `SlotChangePacket` | Both | Single slot update |
| `ItemPickupPacket` | S->C | Item pickup notification |
## Rate Limiting
@@ -284,12 +285,12 @@ player.closeUI();
### UI Packets
| Packet | Direction | Description |
|--------|-----------|-------------|
| `UIOpenPacket` | S->C | Open a UI screen |
| `UIClosePacket` | S->C | Close UI |
| `UIUpdatePacket` | S->C | Update UI data |
| `UIInteractionPacket` | C->S | UI button/element interaction |
| Packet | Direction | Description |
|-----------------------|-----------|-------------------------------|
| `UIOpenPacket` | S->C | Open a UI screen |
| `UIClosePacket` | S->C | Close UI |
| `UIUpdatePacket` | S->C | Update UI data |
| `UIInteractionPacket` | C->S | UI button/element interaction |
## Network Compression

View File

@@ -1,6 +1,7 @@
# Asset System
The Hytale asset system manages game assets including blocks, items, models, sounds, particles, and more. This guide covers how to work with assets and create custom content.
The Hytale asset system manages game assets including blocks, items, models, sounds, particles, and more. This guide
covers how to work with assets and create custom content.
## Overview
@@ -38,19 +39,19 @@ Assets are loaded from:
The server supports many built-in asset types located in `server/core/asset/type/`:
| Asset Type | Description |
|------------|-------------|
| `BlockType` | Block definitions (stone, dirt, etc.) |
| `ItemType` | Item definitions |
| `ModelAsset` | 3D model definitions |
| `SoundEvent` | Sound effect definitions |
| `ParticleAsset` | Particle system definitions |
| `WeatherAsset` | Weather type definitions |
| `EnvironmentAsset` | Environment settings |
| `FluidAsset` | Fluid definitions |
| `EntityEffect` | Entity effect definitions |
| `BiomeAsset` | Biome definitions |
| `StructureAsset` | Structure/prefab definitions |
| Asset Type | Description |
|--------------------|---------------------------------------|
| `BlockType` | Block definitions (stone, dirt, etc.) |
| `ItemType` | Item definitions |
| `ModelAsset` | 3D model definitions |
| `SoundEvent` | Sound effect definitions |
| `ParticleAsset` | Particle system definitions |
| `WeatherAsset` | Weather type definitions |
| `EnvironmentAsset` | Environment settings |
| `FluidAsset` | Fluid definitions |
| `EntityEffect` | Entity effect definitions |
| `BiomeAsset` | Biome definitions |
| `StructureAsset` | Structure/prefab definitions |
## Blocks

View File

@@ -1,6 +1,7 @@
# Configuration System
The Hytale server provides a robust configuration system for both server settings and plugin configurations. This guide covers how to use and extend the configuration system.
The Hytale server provides a robust configuration system for both server settings and plugin configurations. This guide
covers how to use and extend the configuration system.
## Server Configuration

View File

@@ -1,6 +1,7 @@
# Codec and Serialization System
The Hytale server uses a powerful codec system for data serialization and deserialization. This system is used throughout the codebase for configuration, network packets, asset definitions, and data persistence.
The Hytale server uses a powerful codec system for data serialization and deserialization. This system is used
throughout the codebase for configuration, network packets, asset definitions, and data persistence.
## Overview
@@ -25,7 +26,8 @@ public interface Codec<T> {
### DataInput/DataOutput
Codecs work with abstract `DataInput` and `DataOutput` interfaces that can represent different formats (JSON, BSON, etc.).
Codecs work with abstract `DataInput` and `DataOutput` interfaces that can represent different formats (JSON, BSON,
etc.).
## Primitive Codecs

View File

@@ -1,6 +1,7 @@
# Utilities and Common APIs
The Hytale server provides a comprehensive set of utility classes and common APIs. This guide covers the most useful utilities for mod development.
The Hytale server provides a comprehensive set of utility classes and common APIs. This guide covers the most useful
utilities for mod development.
## Math Utilities

View File

@@ -1,6 +1,7 @@
# Early Plugin System (Class Transformation)
The Early Plugin System allows advanced mods to transform Java bytecode before classes are loaded. This is a powerful feature for core modifications that cannot be achieved through the standard plugin API.
The Early Plugin System allows advanced mods to transform Java bytecode before classes are loaded. This is a powerful
feature for core modifications that cannot be achieved through the standard plugin API.
## Overview
@@ -23,6 +24,7 @@ Early plugins are appropriate when:
- Standard plugin APIs don't provide sufficient access
**Prefer standard plugins** when possible. Early plugins:
- Are harder to maintain across server updates
- May conflict with other early plugins
- Can introduce hard-to-debug issues
@@ -223,12 +225,12 @@ public int priority() {
}
```
| Priority | Use Case |
|----------|----------|
| 1000+ | Critical patches (security fixes) |
| 100-999 | Core modifications |
| 0 | Standard transformations |
| -100 to -1 | Post-processing |
| Priority | Use Case |
|------------|-----------------------------------|
| 1000+ | Critical patches (security fixes) |
| 100-999 | Core modifications |
| 0 | Standard transformations |
| -100 to -1 | Post-processing |
## Compatibility Considerations

View File

@@ -1,6 +1,7 @@
# UI System
The Hytale server implements a server-authoritative UI system with two main subsystems: Pages (full-screen UI) and Windows (inventory-style containers).
The Hytale server implements a server-authoritative UI system with two main subsystems: Pages (full-screen UI) and
Windows (inventory-style containers).
## Architecture Overview
@@ -19,14 +20,14 @@ UI System
### Core Classes
| Class | Package | Description |
|-------|---------|-------------|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages` | Abstract base for all custom pages |
| `BasicCustomUIPage` | Same | Simple pages without event data parsing |
| `InteractiveCustomUIPage<T>` | Same | Pages with typed event handling |
| `PageManager` | Same | Manages page state for a player |
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder` | Builds UI DOM commands |
| `UIEventBuilder` | Same | Builds event bindings |
| Class | Package | Description |
|------------------------------|---------------------------------------------------------------|-----------------------------------------|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages` | Abstract base for all custom pages |
| `BasicCustomUIPage` | Same | Simple pages without event data parsing |
| `InteractiveCustomUIPage<T>` | Same | Pages with typed event handling |
| `PageManager` | Same | Manages page state for a player |
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder` | Builds UI DOM commands |
| `UIEventBuilder` | Same | Builds event bindings |
### Page Lifetime
@@ -236,6 +237,7 @@ Value<Integer> border = Value.ref("Pages/Dialog.ui", "BorderWidth");
### Encoding Format
References are encoded in JSON as:
```json
{
"$Document": "Common/Button.ui",
@@ -508,36 +510,36 @@ public enum HudComponent {
### Page Packets
| Packet | ID | Direction | Description |
|--------|-----|-----------|-------------|
| `SetPage` | 216 | S->C | Set built-in page |
| `CustomHud` | 217 | S->C | Update HUD |
| `CustomPage` | 218 | S->C | Send custom page |
| `CustomPageEvent` | 219 | C->S | Page event |
| Packet | ID | Direction | Description |
|-------------------|-----|-----------|-------------------|
| `SetPage` | 216 | S->C | Set built-in page |
| `CustomHud` | 217 | S->C | Update HUD |
| `CustomPage` | 218 | S->C | Send custom page |
| `CustomPageEvent` | 219 | C->S | Page event |
### Window Packets
| Packet | ID | Direction | Description |
|--------|-----|-----------|-------------|
| `OpenWindow` | 200 | S->C | Open window |
| `UpdateWindow` | 201 | S->C | Update window |
| `CloseWindow` | 202 | S->C | Close window |
| `ClientOpenWindow` | 203 | C->S | Request window |
| `SendWindowAction` | 204 | C->S | Window action |
| Packet | ID | Direction | Description |
|--------------------|-----|-----------|----------------|
| `OpenWindow` | 200 | S->C | Open window |
| `UpdateWindow` | 201 | S->C | Update window |
| `CloseWindow` | 202 | S->C | Close window |
| `ClientOpenWindow` | 203 | C->S | Request window |
| `SendWindowAction` | 204 | C->S | Window action |
## Known UI Documents
| Path | Purpose |
|------|---------|
| `Pages/DialogPage.ui` | Dialog/conversation |
| `Pages/BarterPage.ui` | Trading interface |
| `Pages/ShopPage.ui` | Shop interface |
| `Pages/RespawnPage.ui` | Death/respawn |
| `Pages/ChangeModelPage.ui` | Model selection |
| `Pages/WarpListPage.ui` | Teleport list |
| `Pages/CommandListPage.ui` | Command help |
| `Pages/PluginListPage.ui` | Plugin list |
| `Common/TextButton.ui` | Reusable button |
| Path | Purpose |
|----------------------------|---------------------|
| `Pages/DialogPage.ui` | Dialog/conversation |
| `Pages/BarterPage.ui` | Trading interface |
| `Pages/ShopPage.ui` | Shop interface |
| `Pages/RespawnPage.ui` | Death/respawn |
| `Pages/ChangeModelPage.ui` | Model selection |
| `Pages/WarpListPage.ui` | Teleport list |
| `Pages/CommandListPage.ui` | Command help |
| `Pages/PluginListPage.ui` | Plugin list |
| `Common/TextButton.ui` | Reusable button |
## Best Practices

View File

@@ -1,10 +1,12 @@
# Hytale Server Modding Documentation
Welcome to the Hytale Server modding documentation. This guide provides comprehensive information for creating mods and extensions for the Hytale Server.
Welcome to the Hytale Server modding documentation. This guide provides comprehensive information for creating mods and
extensions for the Hytale Server.
## LLM Reference
**[LLM-Optimized API Reference](00-llm-reference.md)** - Complete API reference with exact class names, method signatures, and JSON structures. Use this for quick lookups.
**[LLM-Optimized API Reference](00-llm-reference.md)** - Complete API reference with exact class names, method
signatures, and JSON structures. Use this for quick lookups.
## Documentation Index
@@ -46,6 +48,7 @@ Welcome to the Hytale Server modding documentation. This guide provides comprehe
### Creating Your First Mod
1. Create a `manifest.json`:
```json
{
"Group": "com.example",
@@ -56,6 +59,7 @@ Welcome to the Hytale Server modding documentation. This guide provides comprehe
```
2. Create your main class:
```java
public class MyMod extends JavaPlugin {
public MyMod(JavaPluginInit init) {
@@ -85,23 +89,23 @@ NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
### Available Registries
| Registry | Purpose |
|----------|---------|
| Registry | Purpose |
|-------------------|-----------------|
| `CommandRegistry` | Custom commands |
| `EventRegistry` | Event listeners |
| `EntityRegistry` | Custom entities |
| `AssetRegistry` | Custom assets |
| `TaskRegistry` | Scheduled tasks |
| `EventRegistry` | Event listeners |
| `EntityRegistry` | Custom entities |
| `AssetRegistry` | Custom assets |
| `TaskRegistry` | Scheduled tasks |
### Event Priority
| Priority | Value | Use Case |
|----------|-------|----------|
| FIRST | -21844 | Monitoring/logging |
| EARLY | -10922 | Pre-processing |
| NORMAL | 0 | Standard handling |
| LATE | 10922 | Post-processing |
| LAST | 21844 | Final processing |
| Priority | Value | Use Case |
|----------|--------|--------------------|
| FIRST | -21844 | Monitoring/logging |
| EARLY | -10922 | Pre-processing |
| NORMAL | 0 | Standard handling |
| LATE | 10922 | Post-processing |
| LAST | 21844 | Final processing |
## Package Structure
@@ -120,6 +124,7 @@ com.hypixel.hytale/
## API Highlights
### Events
```java
getEventRegistry().register(PlayerConnectEvent.class, event -> {
Player player = event.getPlayer();
@@ -128,6 +133,7 @@ getEventRegistry().register(PlayerConnectEvent.class, event -> {
```
### Commands
```java
public class MyCommand extends AbstractCommand {
public MyCommand() {
@@ -144,6 +150,7 @@ public class MyCommand extends AbstractCommand {
```
### Entities
```java
public class CustomEntity extends Entity {
public CustomEntity(World world) {
@@ -156,6 +163,7 @@ getEntityRegistry().register("custom", CustomEntity.class, CustomEntity::new);
```
### Configuration
```java
public static final Codec<MyConfig> CODEC = BuilderCodec.of(MyConfig::new)
.with("enabled", Codec.BOOLEAN, c -> c.enabled, true)
@@ -177,6 +185,7 @@ public static final Codec<MyConfig> CODEC = BuilderCodec.of(MyConfig::new)
## Support
For questions and support:
- Check the [Hytale modding forums](#)
- Join the [Discord community](#)
- Report issues on [GitHub](#)
@@ -187,4 +196,5 @@ Contributions to this documentation are welcome. Please submit pull requests wit
---
*This documentation is for Hytale Server modding. For official Hytale information, visit [hytale.com](https://hytale.com).*
*This documentation is for Hytale Server modding. For official Hytale information,
visit [hytale.com](https://hytale.com).*

View File

@@ -14,6 +14,7 @@ import com.hypixel.hytale.server.core.entity.EntityUtils;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.InteractionManager;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.event.events.ecs.ChangeHotbarSlotEvent;
import com.hypixel.hytale.server.core.meta.DynamicMetaStore;
import com.hypixel.hytale.server.core.meta.MetaKey;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
@@ -21,146 +22,146 @@ import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Int
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.Collector;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.event.events.ecs.ChangeHotbarSlotEvent;
import javax.annotation.Nonnull;
public class ChangeActiveSlotInteraction extends Interaction {
@Nonnull
public static final ChangeActiveSlotInteraction DEFAULT_INTERACTION = new ChangeActiveSlotInteraction("*Change_Active_Slot");
@Nonnull
public static final RootInteraction DEFAULT_ROOT = new RootInteraction(
"*Default_Swap",
new InteractionCooldown("ChangeActiveSlot", 0.0F, false, InteractionManager.DEFAULT_CHARGE_TIMES, true, false),
DEFAULT_INTERACTION.getId()
);
@Deprecated
public static final MetaKey<Runnable> PLACE_MOVED_ITEM = CONTEXT_META_REGISTRY.registerMetaObject(i -> null);
private static final int UNSET_INT = Integer.MIN_VALUE;
@Nonnull
public static final BuilderCodec<ChangeActiveSlotInteraction> CODEC = BuilderCodec.builder(
ChangeActiveSlotInteraction.class, ChangeActiveSlotInteraction::new, Interaction.ABSTRACT_CODEC
)
.documentation("Changes the active hotbar slot for the user of the interaction.")
.<Integer>appendInherited(
new KeyedCodec<>("TargetSlot", Codec.INTEGER),
(o, i) -> o.targetSlot = i == null ? Integer.MIN_VALUE : i,
o -> o.targetSlot == Integer.MIN_VALUE ? null : o.targetSlot,
(o, p) -> o.targetSlot = p.targetSlot
)
.addValidator(Validators.range(0, 8))
.add()
.afterDecode(i -> i.cancelOnItemChange = false)
.build();
protected int targetSlot = Integer.MIN_VALUE;
@Nonnull
public static final ChangeActiveSlotInteraction DEFAULT_INTERACTION = new ChangeActiveSlotInteraction("*Change_Active_Slot");
@Nonnull
public static final RootInteraction DEFAULT_ROOT = new RootInteraction(
"*Default_Swap",
new InteractionCooldown("ChangeActiveSlot", 0.0F, false, InteractionManager.DEFAULT_CHARGE_TIMES, true, false),
DEFAULT_INTERACTION.getId()
);
@Deprecated
public static final MetaKey<Runnable> PLACE_MOVED_ITEM = CONTEXT_META_REGISTRY.registerMetaObject(i -> null);
private static final int UNSET_INT = Integer.MIN_VALUE;
@Nonnull
public static final BuilderCodec<ChangeActiveSlotInteraction> CODEC = BuilderCodec.builder(
ChangeActiveSlotInteraction.class, ChangeActiveSlotInteraction::new, Interaction.ABSTRACT_CODEC
)
.documentation("Changes the active hotbar slot for the user of the interaction.")
.<Integer>appendInherited(
new KeyedCodec<>("TargetSlot", Codec.INTEGER),
(o, i) -> o.targetSlot = i == null ? Integer.MIN_VALUE : i,
o -> o.targetSlot == Integer.MIN_VALUE ? null : o.targetSlot,
(o, p) -> o.targetSlot = p.targetSlot
)
.addValidator(Validators.range(0, 8))
.add()
.afterDecode(i -> i.cancelOnItemChange = false)
.build();
protected int targetSlot = Integer.MIN_VALUE;
public ChangeActiveSlotInteraction() {
}
public ChangeActiveSlotInteraction() {
}
private ChangeActiveSlotInteraction(@Nonnull String id) {
super(id);
this.cancelOnItemChange = false;
}
private ChangeActiveSlotInteraction(@Nonnull String id) {
super(id);
this.cancelOnItemChange = false;
}
@Nonnull
@Override
public WaitForDataFrom getWaitForDataFrom() {
return WaitForDataFrom.None;
}
@Override
protected void tick0(
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
) {
if (!firstRun) {
context.getState().state = InteractionState.Finished;
} else {
CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
assert commandBuffer != null;
Ref<EntityStore> ref = context.getEntity();
if (EntityUtils.getEntity(ref, commandBuffer) instanceof LivingEntity livingEntity) {
DynamicMetaStore var15 = context.getMetaStore();
byte slot;
if (this.targetSlot == Integer.MIN_VALUE) {
slot = ((Number)var15.getMetaObject(TARGET_SLOT)).byteValue();
} else {
if (livingEntity.getInventory().getActiveHotbarSlot() == this.targetSlot) {
context.getState().state = InteractionState.Finished;
return;
}
slot = (byte)this.targetSlot;
var15.putMetaObject(TARGET_SLOT, Integer.valueOf(slot));
}
byte previousSlot = livingEntity.getInventory().getActiveHotbarSlot();
ChangeHotbarSlotEvent event = new ChangeHotbarSlotEvent(previousSlot, slot, false);
commandBuffer.invoke(ref, event);
if (event.isCancelled()) {
context.getState().state = InteractionState.Finished;
return;
}
slot = event.getNewSlot();
livingEntity.getInventory().setActiveHotbarSlot(slot);
Runnable action = (Runnable)var15.removeMetaObject(PLACE_MOVED_ITEM);
if (action != null) {
action.run();
}
InteractionManager interactionManager = context.getInteractionManager();
assert interactionManager != null;
InteractionContext forkContext = InteractionContext.forInteraction(interactionManager, ref, InteractionType.SwapTo, commandBuffer);
String forkInteractions = forkContext.getRootInteractionId(InteractionType.SwapTo);
if (forkInteractions != null) {
if (this.targetSlot != Integer.MIN_VALUE) {
forkContext.getMetaStore().putMetaObject(TARGET_SLOT, Integer.valueOf(slot));
}
context.fork(InteractionType.SwapTo, forkContext, RootInteraction.getRootInteractionOrUnknown(forkInteractions), action == null);
}
@Nonnull
@Override
public WaitForDataFrom getWaitForDataFrom() {
return WaitForDataFrom.None;
}
@Override
protected void tick0(
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
) {
if (!firstRun) {
context.getState().state = InteractionState.Finished;
}
}
}
} else {
CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
@Override
protected void simulateTick0(
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
) {
context.getState().state = context.getServerState().state;
}
assert commandBuffer != null;
@Override
public boolean walk(@Nonnull Collector collector, @Nonnull InteractionContext context) {
return false;
}
Ref<EntityStore> ref = context.getEntity();
if (EntityUtils.getEntity(ref, commandBuffer) instanceof LivingEntity livingEntity) {
DynamicMetaStore var15 = context.getMetaStore();
byte slot;
if (this.targetSlot == Integer.MIN_VALUE) {
slot = ((Number) var15.getMetaObject(TARGET_SLOT)).byteValue();
} else {
if (livingEntity.getInventory().getActiveHotbarSlot() == this.targetSlot) {
context.getState().state = InteractionState.Finished;
return;
}
@Override
public boolean needsRemoteSync() {
return true;
}
slot = (byte) this.targetSlot;
var15.putMetaObject(TARGET_SLOT, Integer.valueOf(slot));
}
@Nonnull
@Override
protected com.hypixel.hytale.protocol.Interaction generatePacket() {
return new com.hypixel.hytale.protocol.ChangeActiveSlotInteraction();
}
byte previousSlot = livingEntity.getInventory().getActiveHotbarSlot();
ChangeHotbarSlotEvent event = new ChangeHotbarSlotEvent(previousSlot, slot, false);
commandBuffer.invoke(ref, event);
if (event.isCancelled()) {
context.getState().state = InteractionState.Finished;
return;
}
slot = event.getNewSlot();
@Override
protected void configurePacket(com.hypixel.hytale.protocol.Interaction packet) {
super.configurePacket(packet);
com.hypixel.hytale.protocol.ChangeActiveSlotInteraction p = (com.hypixel.hytale.protocol.ChangeActiveSlotInteraction)packet;
p.targetSlot = this.targetSlot;
}
livingEntity.getInventory().setActiveHotbarSlot(slot);
Runnable action = (Runnable) var15.removeMetaObject(PLACE_MOVED_ITEM);
if (action != null) {
action.run();
}
@Nonnull
@Override
public String toString() {
return "ChangeActiveSlotInteraction{targetSlot=" + this.targetSlot + "} " + super.toString();
}
InteractionManager interactionManager = context.getInteractionManager();
assert interactionManager != null;
InteractionContext forkContext = InteractionContext.forInteraction(interactionManager, ref, InteractionType.SwapTo, commandBuffer);
String forkInteractions = forkContext.getRootInteractionId(InteractionType.SwapTo);
if (forkInteractions != null) {
if (this.targetSlot != Integer.MIN_VALUE) {
forkContext.getMetaStore().putMetaObject(TARGET_SLOT, Integer.valueOf(slot));
}
context.fork(InteractionType.SwapTo, forkContext, RootInteraction.getRootInteractionOrUnknown(forkInteractions), action == null);
}
context.getState().state = InteractionState.Finished;
}
}
}
@Override
protected void simulateTick0(
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
) {
context.getState().state = context.getServerState().state;
}
@Override
public boolean walk(@Nonnull Collector collector, @Nonnull InteractionContext context) {
return false;
}
@Override
public boolean needsRemoteSync() {
return true;
}
@Nonnull
@Override
protected com.hypixel.hytale.protocol.Interaction generatePacket() {
return new com.hypixel.hytale.protocol.ChangeActiveSlotInteraction();
}
@Override
protected void configurePacket(com.hypixel.hytale.protocol.Interaction packet) {
super.configurePacket(packet);
com.hypixel.hytale.protocol.ChangeActiveSlotInteraction p = (com.hypixel.hytale.protocol.ChangeActiveSlotInteraction) packet;
p.targetSlot = this.targetSlot;
}
@Nonnull
@Override
public String toString() {
return "ChangeActiveSlotInteraction{targetSlot=" + this.targetSlot + "} " + super.toString();
}
}