docs: update documentation; patch ChangeActiveSlotInteraction
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# Hytale Server API Reference (LLM-Optimized)
|
# 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
|
### Core Classes
|
||||||
|
|
||||||
| Class | Package |
|
| Class | Package |
|
||||||
|-------|---------|
|
|------------------|--------------------------------------------------------|
|
||||||
| `JavaPlugin` | `com.hypixel.hytale.server.core.plugin.JavaPlugin` |
|
| `JavaPlugin` | `com.hypixel.hytale.server.core.plugin.JavaPlugin` |
|
||||||
| `PluginBase` | `com.hypixel.hytale.server.core.plugin.PluginBase` |
|
| `PluginBase` | `com.hypixel.hytale.server.core.plugin.PluginBase` |
|
||||||
| `PluginManifest` | `com.hypixel.hytale.common.plugin.PluginManifest` |
|
| `PluginManifest` | `com.hypixel.hytale.common.plugin.PluginManifest` |
|
||||||
| `JavaPluginInit` | `com.hypixel.hytale.server.core.plugin.JavaPluginInit` |
|
| `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
|
### Plugin Lifecycle
|
||||||
|
|
||||||
@@ -23,8 +24,9 @@ PluginState: NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Lifecycle Methods (exact names):**
|
**Lifecycle Methods (exact names):**
|
||||||
|
|
||||||
- `setup()` - Called during initialization, register components here
|
- `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
|
- `shutdown()` - Called during server stop/plugin disable
|
||||||
|
|
||||||
### Plugin Manifest JSON (exact field names, case-sensitive)
|
### Plugin Manifest JSON (exact field names, case-sensitive)
|
||||||
@@ -50,17 +52,17 @@ PluginState: NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
|
|||||||
|
|
||||||
### Registry Methods on PluginBase
|
### Registry Methods on PluginBase
|
||||||
|
|
||||||
| Method | Return Type |
|
| Method | Return Type |
|
||||||
|--------|-------------|
|
|------------------------------|---------------------------------------|
|
||||||
| `getClientFeatureRegistry()` | `ClientFeatureRegistry` |
|
| `getClientFeatureRegistry()` | `ClientFeatureRegistry` |
|
||||||
| `getCommandRegistry()` | `CommandRegistry` |
|
| `getCommandRegistry()` | `CommandRegistry` |
|
||||||
| `getEventRegistry()` | `EventRegistry` |
|
| `getEventRegistry()` | `EventRegistry` |
|
||||||
| `getBlockStateRegistry()` | `BlockStateRegistry` |
|
| `getBlockStateRegistry()` | `BlockStateRegistry` |
|
||||||
| `getEntityRegistry()` | `EntityRegistry` |
|
| `getEntityRegistry()` | `EntityRegistry` |
|
||||||
| `getTaskRegistry()` | `TaskRegistry` |
|
| `getTaskRegistry()` | `TaskRegistry` |
|
||||||
| `getEntityStoreRegistry()` | `ComponentRegistryProxy<EntityStore>` |
|
| `getEntityStoreRegistry()` | `ComponentRegistryProxy<EntityStore>` |
|
||||||
| `getChunkStoreRegistry()` | `ComponentRegistryProxy<ChunkStore>` |
|
| `getChunkStoreRegistry()` | `ComponentRegistryProxy<ChunkStore>` |
|
||||||
| `getAssetRegistry()` | `AssetRegistry` |
|
| `getAssetRegistry()` | `AssetRegistry` |
|
||||||
|
|
||||||
### Configuration Pattern
|
### Configuration Pattern
|
||||||
|
|
||||||
@@ -79,13 +81,13 @@ MyConfig cfg = config.get();
|
|||||||
|
|
||||||
### Core Interfaces (Package: `com.hypixel.hytale.event`)
|
### Core Interfaces (Package: `com.hypixel.hytale.event`)
|
||||||
|
|
||||||
| Interface | Description |
|
| Interface | Description |
|
||||||
|-----------|-------------|
|
|------------------------|-------------------------------------------------|
|
||||||
| `IBaseEvent<KeyType>` | Base event interface |
|
| `IBaseEvent<KeyType>` | Base event interface |
|
||||||
| `IEvent<KeyType>` | Synchronous event, extends IBaseEvent |
|
| `IEvent<KeyType>` | Synchronous event, extends IBaseEvent |
|
||||||
| `IAsyncEvent<KeyType>` | Async event, extends IBaseEvent |
|
| `IAsyncEvent<KeyType>` | Async event, extends IBaseEvent |
|
||||||
| `ICancellable` | Mixin: `isCancelled()`, `setCancelled(boolean)` |
|
| `ICancellable` | Mixin: `isCancelled()`, `setCancelled(boolean)` |
|
||||||
| `IProcessedEvent` | Mixin: `processEvent(String)` |
|
| `IProcessedEvent` | Mixin: `processEvent(String)` |
|
||||||
|
|
||||||
### EventPriority (exact values)
|
### EventPriority (exact values)
|
||||||
|
|
||||||
@@ -100,6 +102,7 @@ LAST = (short)21844 // Runs last
|
|||||||
### EventRegistry Methods (IEventRegistry interface)
|
### EventRegistry Methods (IEventRegistry interface)
|
||||||
|
|
||||||
**Sync Registration:**
|
**Sync Registration:**
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Without key (Void key)
|
// Without key (Void key)
|
||||||
EventRegistration register(Class<? super EventType> eventClass, Consumer<EventType> consumer)
|
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):**
|
**Global Registration (receives all keys):**
|
||||||
|
|
||||||
```java
|
```java
|
||||||
EventRegistration registerGlobal(Class<? super EventType> eventClass, Consumer<EventType> consumer)
|
EventRegistration registerGlobal(Class<? super EventType> eventClass, Consumer<EventType> consumer)
|
||||||
EventRegistration registerGlobal(EventPriority priority, 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):**
|
**Unhandled Registration (when no other handler processed):**
|
||||||
|
|
||||||
```java
|
```java
|
||||||
EventRegistration registerUnhandled(Class<? super EventType> eventClass, Consumer<EventType> consumer)
|
EventRegistration registerUnhandled(Class<? super EventType> eventClass, Consumer<EventType> consumer)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Async Registration:**
|
**Async Registration:**
|
||||||
|
|
||||||
```java
|
```java
|
||||||
EventRegistration registerAsync(Class<? super EventType> eventClass, Function<CompletableFuture<EventType>, CompletableFuture<EventType>> function)
|
EventRegistration registerAsync(Class<? super EventType> eventClass, Function<CompletableFuture<EventType>, CompletableFuture<EventType>> function)
|
||||||
EventRegistration registerAsyncGlobal(...)
|
EventRegistration registerAsyncGlobal(...)
|
||||||
@@ -131,11 +137,13 @@ EventRegistration registerAsyncUnhandled(...)
|
|||||||
### Key Event Classes
|
### Key Event Classes
|
||||||
|
|
||||||
**Server Events (`com.hypixel.hytale.server.core.event.events`):**
|
**Server Events (`com.hypixel.hytale.server.core.event.events`):**
|
||||||
|
|
||||||
- `BootEvent` - IEvent<Void>
|
- `BootEvent` - IEvent<Void>
|
||||||
- `ShutdownEvent` - IEvent<Void>
|
- `ShutdownEvent` - IEvent<Void>
|
||||||
- `PrepareUniverseEvent` - IEvent<Void>
|
- `PrepareUniverseEvent` - IEvent<Void>
|
||||||
|
|
||||||
**Player Events (`...event.events.player`):**
|
**Player Events (`...event.events.player`):**
|
||||||
|
|
||||||
- `PlayerConnectEvent` - IEvent<Void>
|
- `PlayerConnectEvent` - IEvent<Void>
|
||||||
- `PlayerSetupConnectEvent` - IEvent<Void>, ICancellable
|
- `PlayerSetupConnectEvent` - IEvent<Void>, ICancellable
|
||||||
- `PlayerDisconnectEvent` - PlayerRefEvent<Void>
|
- `PlayerDisconnectEvent` - PlayerRefEvent<Void>
|
||||||
@@ -146,12 +154,14 @@ EventRegistration registerAsyncUnhandled(...)
|
|||||||
- `DrainPlayerFromWorldEvent` - IEvent<String>
|
- `DrainPlayerFromWorldEvent` - IEvent<String>
|
||||||
|
|
||||||
**World Events (`...universe.world.events`):**
|
**World Events (`...universe.world.events`):**
|
||||||
|
|
||||||
- `AddWorldEvent` - WorldEvent, ICancellable
|
- `AddWorldEvent` - WorldEvent, ICancellable
|
||||||
- `RemoveWorldEvent` - WorldEvent, ICancellable
|
- `RemoveWorldEvent` - WorldEvent, ICancellable
|
||||||
- `StartWorldEvent` - WorldEvent
|
- `StartWorldEvent` - WorldEvent
|
||||||
- `AllWorldsLoadedEvent` - IEvent<Void>
|
- `AllWorldsLoadedEvent` - IEvent<Void>
|
||||||
|
|
||||||
**ECS Events (`...event.events.ecs`):**
|
**ECS Events (`...event.events.ecs`):**
|
||||||
|
|
||||||
- `BreakBlockEvent` - CancellableEcsEvent
|
- `BreakBlockEvent` - CancellableEcsEvent
|
||||||
- `PlaceBlockEvent` - CancellableEcsEvent
|
- `PlaceBlockEvent` - CancellableEcsEvent
|
||||||
- `UseBlockEvent` - EcsEvent (with nested `Pre` implementing ICancellableEcsEvent)
|
- `UseBlockEvent` - EcsEvent (with nested `Pre` implementing ICancellableEcsEvent)
|
||||||
@@ -164,16 +174,16 @@ EventRegistration registerAsyncUnhandled(...)
|
|||||||
|
|
||||||
### Core Classes (Package: `com.hypixel.hytale.server.core.command.system`)
|
### Core Classes (Package: `com.hypixel.hytale.server.core.command.system`)
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|-----------------------------|--------------------------------------------|
|
||||||
| `AbstractCommand` | Base command class |
|
| `AbstractCommand` | Base command class |
|
||||||
| `CommandRegistry` | Plugin command registration |
|
| `CommandRegistry` | Plugin command registration |
|
||||||
| `CommandContext` | Execution context |
|
| `CommandContext` | Execution context |
|
||||||
| `CommandBase` | Sync command base (override `executeSync`) |
|
| `CommandBase` | Sync command base (override `executeSync`) |
|
||||||
| `AbstractAsyncCommand` | Async command base |
|
| `AbstractAsyncCommand` | Async command base |
|
||||||
| `AbstractPlayerCommand` | Player-required command |
|
| `AbstractPlayerCommand` | Player-required command |
|
||||||
| `AbstractWorldCommand` | World context command |
|
| `AbstractWorldCommand` | World context command |
|
||||||
| `AbstractCommandCollection` | Parent with subcommands only |
|
| `AbstractCommandCollection` | Parent with subcommands only |
|
||||||
|
|
||||||
### AbstractCommand Key Methods
|
### AbstractCommand Key Methods
|
||||||
|
|
||||||
@@ -231,15 +241,15 @@ ArgTypes.forEnum(String name, Class<E> enumClass) // Create enum type
|
|||||||
|
|
||||||
### Core Classes (Package: `com.hypixel.hytale.component`)
|
### Core Classes (Package: `com.hypixel.hytale.component`)
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|------------------------------|------------------------------------------|
|
||||||
| `Component<ECS_TYPE>` | Base component interface |
|
| `Component<ECS_TYPE>` | Base component interface |
|
||||||
| `ComponentRegistry` | Component type registration |
|
| `ComponentRegistry` | Component type registration |
|
||||||
| `ComponentType<ECS_TYPE, T>` | Registered component type |
|
| `ComponentType<ECS_TYPE, T>` | Registered component type |
|
||||||
| `Store` | ECS data storage |
|
| `Store` | ECS data storage |
|
||||||
| `Ref` | Entity reference (ID) |
|
| `Ref` | Entity reference (ID) |
|
||||||
| `Holder` | Component holder for entity construction |
|
| `Holder` | Component holder for entity construction |
|
||||||
| `Query` | Entity filtering |
|
| `Query` | Entity filtering |
|
||||||
|
|
||||||
### Entity Hierarchy
|
### Entity Hierarchy
|
||||||
|
|
||||||
@@ -264,33 +274,39 @@ void registerSystem(ISystem<EntityStore> system)
|
|||||||
### Key Built-in Components
|
### Key Built-in Components
|
||||||
|
|
||||||
**Transform/Position:**
|
**Transform/Position:**
|
||||||
|
|
||||||
- `TransformComponent` - Position (Vector3d) and rotation (Vector3f)
|
- `TransformComponent` - Position (Vector3d) and rotation (Vector3f)
|
||||||
- `HeadRotation` - Head rotation angles
|
- `HeadRotation` - Head rotation angles
|
||||||
- `EntityScaleComponent` - Scale modifier
|
- `EntityScaleComponent` - Scale modifier
|
||||||
|
|
||||||
**Physics:**
|
**Physics:**
|
||||||
|
|
||||||
- `Velocity` - Velocity vector
|
- `Velocity` - Velocity vector
|
||||||
- `BoundingBox` - Collision box
|
- `BoundingBox` - Collision box
|
||||||
- `CollisionResultComponent` - Collision results
|
- `CollisionResultComponent` - Collision results
|
||||||
- `MovementStatesComponent` - Movement flags (onGround, swimming, etc.)
|
- `MovementStatesComponent` - Movement flags (onGround, swimming, etc.)
|
||||||
|
|
||||||
**Identity:**
|
**Identity:**
|
||||||
|
|
||||||
- `UUIDComponent` - Unique identifier
|
- `UUIDComponent` - Unique identifier
|
||||||
- `NetworkId` - Network sync ID
|
- `NetworkId` - Network sync ID
|
||||||
- `DisplayNameComponent` - Display name
|
- `DisplayNameComponent` - Display name
|
||||||
|
|
||||||
**Visual:**
|
**Visual:**
|
||||||
|
|
||||||
- `ModelComponent` - 3D model reference
|
- `ModelComponent` - 3D model reference
|
||||||
- `ActiveAnimationComponent` - Current animations
|
- `ActiveAnimationComponent` - Current animations
|
||||||
- `DynamicLight` - Dynamic lighting
|
- `DynamicLight` - Dynamic lighting
|
||||||
|
|
||||||
**State Flags:**
|
**State Flags:**
|
||||||
|
|
||||||
- `Invulnerable` - Immune to damage
|
- `Invulnerable` - Immune to damage
|
||||||
- `Intangible` - Non-collidable
|
- `Intangible` - Non-collidable
|
||||||
- `Interactable` - Can be interacted with
|
- `Interactable` - Can be interacted with
|
||||||
- `Frozen` - Frozen state
|
- `Frozen` - Frozen state
|
||||||
|
|
||||||
**Player-specific:**
|
**Player-specific:**
|
||||||
|
|
||||||
- `Player` - Core player component
|
- `Player` - Core player component
|
||||||
- `PlayerRef` - Network connection reference
|
- `PlayerRef` - Network connection reference
|
||||||
- `ChunkTracker` - Loaded chunks tracking
|
- `ChunkTracker` - Loaded chunks tracking
|
||||||
@@ -323,14 +339,14 @@ Ref<EntityStore> ref = store.addEntity(holder, AddReason.SPAWN);
|
|||||||
|
|
||||||
### Page System Classes
|
### Page System Classes
|
||||||
|
|
||||||
| Class | Package |
|
| Class | Package |
|
||||||
|-------|---------|
|
|------------------------------|----------------------------------------------------------------------------|
|
||||||
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages.CustomUIPage` |
|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages.CustomUIPage` |
|
||||||
| `BasicCustomUIPage` | Same package - no event data parsing |
|
| `BasicCustomUIPage` | Same package - no event data parsing |
|
||||||
| `InteractiveCustomUIPage<T>` | Same package - typed event handling |
|
| `InteractiveCustomUIPage<T>` | Same package - typed event handling |
|
||||||
| `PageManager` | Same package - page lifecycle |
|
| `PageManager` | Same package - page lifecycle |
|
||||||
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder.UICommandBuilder` |
|
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder.UICommandBuilder` |
|
||||||
| `UIEventBuilder` | `com.hypixel.hytale.server.core.ui.builder.UIEventBuilder` |
|
| `UIEventBuilder` | `com.hypixel.hytale.server.core.ui.builder.UIEventBuilder` |
|
||||||
|
|
||||||
### CustomPageLifetime
|
### CustomPageLifetime
|
||||||
|
|
||||||
@@ -437,11 +453,11 @@ player.getPageManager().openCustomPage(ref, store, new MyPage(playerRef));
|
|||||||
|
|
||||||
### Window System
|
### Window System
|
||||||
|
|
||||||
| Class | Package |
|
| Class | Package |
|
||||||
|-------|---------|
|
|-------------------------------------------|------------------------------------------------------------------------|
|
||||||
| `Window` | `com.hypixel.hytale.server.core.entity.entities.player.windows.Window` |
|
| `Window` | `com.hypixel.hytale.server.core.entity.entities.player.windows.Window` |
|
||||||
| `WindowManager` | Same package |
|
| `WindowManager` | Same package |
|
||||||
| `ContainerWindow`, `CraftingWindow`, etc. | Same package |
|
| `ContainerWindow`, `CraftingWindow`, etc. | Same package |
|
||||||
|
|
||||||
### WindowType
|
### WindowType
|
||||||
|
|
||||||
@@ -456,11 +472,11 @@ DiagramCrafting(3), StructuralCrafting(4), Processing(5), Memories(6)
|
|||||||
|
|
||||||
### Core Classes (Package: `com.hypixel.hytale.codec`)
|
### Core Classes (Package: `com.hypixel.hytale.codec`)
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|-------------------|----------------------|
|
||||||
| `Codec<T>` | Base codec interface |
|
| `Codec<T>` | Base codec interface |
|
||||||
| `BuilderCodec<T>` | Builder-based codec |
|
| `BuilderCodec<T>` | Builder-based codec |
|
||||||
| `KeyedCodec<T>` | Key-value codec |
|
| `KeyedCodec<T>` | Key-value codec |
|
||||||
|
|
||||||
### Primitive Codecs
|
### Primitive Codecs
|
||||||
|
|
||||||
@@ -503,39 +519,45 @@ Codec<MyEnum> ENUM = Codec.enumCodec(MyEnum.class);
|
|||||||
|
|
||||||
### Core Classes
|
### Core Classes
|
||||||
|
|
||||||
| Class | Package |
|
| Class | Package |
|
||||||
|-------|---------|
|
|---------------------|-------------------------------------------------------|
|
||||||
| `JsonAsset<K>` | `com.hypixel.hytale.assetstore.JsonAsset` |
|
| `JsonAsset<K>` | `com.hypixel.hytale.assetstore.JsonAsset` |
|
||||||
| `AssetStore<K,T,M>` | `com.hypixel.hytale.assetstore.AssetStore` |
|
| `AssetStore<K,T,M>` | `com.hypixel.hytale.assetstore.AssetStore` |
|
||||||
| `AssetRegistry` | `com.hypixel.hytale.server.core.plugin.AssetRegistry` |
|
| `AssetRegistry` | `com.hypixel.hytale.server.core.plugin.AssetRegistry` |
|
||||||
|
|
||||||
### Key Asset Types (Package: `com.hypixel.hytale.server.core.asset.type`)
|
### Key Asset Types (Package: `com.hypixel.hytale.server.core.asset.type`)
|
||||||
|
|
||||||
**Blocks:**
|
**Blocks:**
|
||||||
|
|
||||||
- `BlockType` - blocktype.config.BlockType
|
- `BlockType` - blocktype.config.BlockType
|
||||||
- `BlockSet` - blockset.config.BlockSet
|
- `BlockSet` - blockset.config.BlockSet
|
||||||
- `BlockSoundSet` - blocksound.config.BlockSoundSet
|
- `BlockSoundSet` - blocksound.config.BlockSoundSet
|
||||||
|
|
||||||
**Items:**
|
**Items:**
|
||||||
|
|
||||||
- `Item` - item.config.Item
|
- `Item` - item.config.Item
|
||||||
- `ItemCategory` - item.config.ItemCategory
|
- `ItemCategory` - item.config.ItemCategory
|
||||||
- `CraftingRecipe` - item.config.CraftingRecipe
|
- `CraftingRecipe` - item.config.CraftingRecipe
|
||||||
|
|
||||||
**Visual:**
|
**Visual:**
|
||||||
|
|
||||||
- `ModelAsset` - model.config.ModelAsset
|
- `ModelAsset` - model.config.ModelAsset
|
||||||
- `ParticleSystem` - particle.config.ParticleSystem
|
- `ParticleSystem` - particle.config.ParticleSystem
|
||||||
- `EntityEffect` - entityeffect.config.EntityEffect
|
- `EntityEffect` - entityeffect.config.EntityEffect
|
||||||
|
|
||||||
**Audio:**
|
**Audio:**
|
||||||
|
|
||||||
- `SoundEvent` - soundevent.config.SoundEvent
|
- `SoundEvent` - soundevent.config.SoundEvent
|
||||||
- `SoundSet` - soundset.config.SoundSet
|
- `SoundSet` - soundset.config.SoundSet
|
||||||
|
|
||||||
**Environment:**
|
**Environment:**
|
||||||
|
|
||||||
- `Environment` - environment.config.Environment
|
- `Environment` - environment.config.Environment
|
||||||
- `Weather` - weather.config.Weather
|
- `Weather` - weather.config.Weather
|
||||||
- `Fluid` - fluid.Fluid
|
- `Fluid` - fluid.Fluid
|
||||||
|
|
||||||
**Gameplay:**
|
**Gameplay:**
|
||||||
|
|
||||||
- `Projectile` - projectile.config.Projectile
|
- `Projectile` - projectile.config.Projectile
|
||||||
- `GameplayConfig` - gameplay.GameplayConfig
|
- `GameplayConfig` - gameplay.GameplayConfig
|
||||||
|
|
||||||
@@ -556,12 +578,12 @@ Codec<MyEnum> ENUM = Codec.enumCodec(MyEnum.class);
|
|||||||
|
|
||||||
### Core Classes
|
### Core Classes
|
||||||
|
|
||||||
| Class | Package |
|
| Class | Package |
|
||||||
|-------|---------|
|
|---------------|---------------------------------------------------------------------|
|
||||||
| `Universe` | `com.hypixel.hytale.server.core.universe.Universe` |
|
| `Universe` | `com.hypixel.hytale.server.core.universe.Universe` |
|
||||||
| `World` | `com.hypixel.hytale.server.core.universe.world.World` |
|
| `World` | `com.hypixel.hytale.server.core.universe.world.World` |
|
||||||
| `EntityStore` | `com.hypixel.hytale.server.core.universe.world.storage.EntityStore` |
|
| `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
|
### Universe Access
|
||||||
|
|
||||||
@@ -590,12 +612,12 @@ boolean paused = world.isPaused();
|
|||||||
|
|
||||||
### Core Classes (Package: `com.hypixel.hytale.server.npc`)
|
### Core Classes (Package: `com.hypixel.hytale.server.npc`)
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|---------------|--------------------------------------------|
|
||||||
| `NPCEntity` | entities.NPCEntity - NPC entity class |
|
| `NPCEntity` | entities.NPCEntity - NPC entity class |
|
||||||
| `Role` | role.Role - Behavior definition |
|
| `Role` | role.Role - Behavior definition |
|
||||||
| `Instruction` | instructions.Instruction - Behavior action |
|
| `Instruction` | instructions.Instruction - Behavior action |
|
||||||
| `PathManager` | navigation.PathManager - Pathfinding |
|
| `PathManager` | navigation.PathManager - Pathfinding |
|
||||||
|
|
||||||
### NPCEntity Key Methods
|
### NPCEntity Key Methods
|
||||||
|
|
||||||
@@ -610,9 +632,9 @@ void playAnimation(...)
|
|||||||
|
|
||||||
### Flock System (Package: `com.hypixel.hytale.server.flock`)
|
### Flock System (Package: `com.hypixel.hytale.server.flock`)
|
||||||
|
|
||||||
| Component | Description |
|
| Component | Description |
|
||||||
|-----------|-------------|
|
|-------------------|---------------------------|
|
||||||
| `Flock` | Flock leader/group |
|
| `Flock` | Flock leader/group |
|
||||||
| `FlockMembership` | Entity's flock membership |
|
| `FlockMembership` | Entity's flock membership |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -621,9 +643,9 @@ void playAnimation(...)
|
|||||||
|
|
||||||
### Packet System (Package: `com.hypixel.hytale.protocol`)
|
### Packet System (Package: `com.hypixel.hytale.protocol`)
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|------------------|--------------------------|
|
||||||
| `Packet` | Base packet interface |
|
| `Packet` | Base packet interface |
|
||||||
| `PacketRegistry` | Packet type registration |
|
| `PacketRegistry` | Packet type registration |
|
||||||
|
|
||||||
### Key Packet Categories (`protocol.packets.*`)
|
### Key Packet Categories (`protocol.packets.*`)
|
||||||
@@ -639,22 +661,22 @@ void playAnimation(...)
|
|||||||
|
|
||||||
### UI Packets
|
### UI Packets
|
||||||
|
|
||||||
| Packet | ID | Direction |
|
| Packet | ID | Direction |
|
||||||
|--------|-----|-----------|
|
|-------------------|-----|-----------|
|
||||||
| `SetPage` | 216 | S->C |
|
| `SetPage` | 216 | S->C |
|
||||||
| `CustomHud` | 217 | S->C |
|
| `CustomHud` | 217 | S->C |
|
||||||
| `CustomPage` | 218 | S->C |
|
| `CustomPage` | 218 | S->C |
|
||||||
| `CustomPageEvent` | 219 | C->S |
|
| `CustomPageEvent` | 219 | C->S |
|
||||||
|
|
||||||
### Window Packets
|
### Window Packets
|
||||||
|
|
||||||
| Packet | ID | Direction |
|
| Packet | ID | Direction |
|
||||||
|--------|-----|-----------|
|
|--------------------|-----|-----------|
|
||||||
| `OpenWindow` | 200 | S->C |
|
| `OpenWindow` | 200 | S->C |
|
||||||
| `UpdateWindow` | 201 | S->C |
|
| `UpdateWindow` | 201 | S->C |
|
||||||
| `CloseWindow` | 202 | S->C |
|
| `CloseWindow` | 202 | S->C |
|
||||||
| `ClientOpenWindow` | 203 | C->S |
|
| `ClientOpenWindow` | 203 | C->S |
|
||||||
| `SendWindowAction` | 204 | C->S |
|
| `SendWindowAction` | 204 | C->S |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -724,23 +746,29 @@ Place JAR in `earlyplugins/` directory.
|
|||||||
|
|
||||||
### EntityStore Components (130+)
|
### 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
|
**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
|
**Audio:** AudioComponent, MovementAudioComponent
|
||||||
|
|
||||||
**Identity:** UUIDComponent, NetworkId, EntityViewer, Visible, PersistentRefCount
|
**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
|
**Teleport:** Teleport, PendingTeleport, TeleportHistory, WarpComponent
|
||||||
|
|
||||||
@@ -762,7 +790,8 @@ Place JAR in `earlyplugins/` directory.
|
|||||||
|
|
||||||
### ChunkStore Components (25+)
|
### 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
|
**Block State:** BlockState, RespawnBlock, LaunchPad, BlockMapMarker
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,22 @@
|
|||||||
|
|
||||||
## Overview
|
## 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
|
## Architecture Overview
|
||||||
|
|
||||||
The server is built on several core systems:
|
The server is built on several core systems:
|
||||||
|
|
||||||
| System | Purpose |
|
| System | Purpose |
|
||||||
|--------|---------|
|
|-------------------------------|----------------------------------------------------------------|
|
||||||
| Plugin System | Mod loading, lifecycle management, and dependency resolution |
|
| Plugin System | Mod loading, lifecycle management, and dependency resolution |
|
||||||
| Entity Component System (ECS) | High-performance entity management with components and systems |
|
| Entity Component System (ECS) | High-performance entity management with components and systems |
|
||||||
| Event System | Prioritized event dispatching with sync/async support |
|
| Event System | Prioritized event dispatching with sync/async support |
|
||||||
| Command System | Player and console command handling |
|
| Command System | Player and console command handling |
|
||||||
| Asset System | Game asset loading and registration |
|
| Asset System | Game asset loading and registration |
|
||||||
| Codec System | Data serialization/deserialization framework |
|
| Codec System | Data serialization/deserialization framework |
|
||||||
| Protocol Layer | Network communication and packet handling |
|
| Protocol Layer | Network communication and packet handling |
|
||||||
|
|
||||||
## Package Structure
|
## Package Structure
|
||||||
|
|
||||||
@@ -121,17 +122,17 @@ Plugins go through the following states:
|
|||||||
|
|
||||||
Your plugin has access to several registries for registration:
|
Your plugin has access to several registries for registration:
|
||||||
|
|
||||||
| Registry | Access Method | Purpose |
|
| Registry | Access Method | Purpose |
|
||||||
|----------|---------------|---------|
|
|-----------------------|------------------------------|-------------------------------|
|
||||||
| CommandRegistry | `getCommandRegistry()` | Register custom commands |
|
| CommandRegistry | `getCommandRegistry()` | Register custom commands |
|
||||||
| EventRegistry | `getEventRegistry()` | Register event listeners |
|
| EventRegistry | `getEventRegistry()` | Register event listeners |
|
||||||
| EntityRegistry | `getEntityRegistry()` | Register custom entity types |
|
| EntityRegistry | `getEntityRegistry()` | Register custom entity types |
|
||||||
| BlockStateRegistry | `getBlockStateRegistry()` | Register block states |
|
| BlockStateRegistry | `getBlockStateRegistry()` | Register block states |
|
||||||
| TaskRegistry | `getTaskRegistry()` | Schedule recurring tasks |
|
| TaskRegistry | `getTaskRegistry()` | Schedule recurring tasks |
|
||||||
| AssetRegistry | `getAssetRegistry()` | Register custom asset types |
|
| AssetRegistry | `getAssetRegistry()` | Register custom asset types |
|
||||||
| ClientFeatureRegistry | `getClientFeatureRegistry()` | Register client-side features |
|
| ClientFeatureRegistry | `getClientFeatureRegistry()` | Register client-side features |
|
||||||
| EntityStoreRegistry | `getEntityStoreRegistry()` | Register ECS entity stores |
|
| EntityStoreRegistry | `getEntityStoreRegistry()` | Register ECS entity stores |
|
||||||
| ChunkStoreRegistry | `getChunkStoreRegistry()` | Register chunk data stores |
|
| ChunkStoreRegistry | `getChunkStoreRegistry()` | Register chunk data stores |
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
|
|||||||
@@ -36,25 +36,26 @@ The `manifest.json` file must be placed at the root of your JAR:
|
|||||||
|
|
||||||
### Manifest Fields
|
### Manifest Fields
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
|-------|------|----------|-------------|
|
|------------------------|----------|----------|--------------------------------------------------|
|
||||||
| `Group` | String | Yes | Maven-style group ID (e.g., `com.example`) |
|
| `Group` | String | Yes | Maven-style group ID (e.g., `com.example`) |
|
||||||
| `Name` | String | Yes | Plugin name (unique identifier within group) |
|
| `Name` | String | Yes | Plugin name (unique identifier within group) |
|
||||||
| `Version` | String | Yes | Semantic version (e.g., `1.0.0`) |
|
| `Version` | String | Yes | Semantic version (e.g., `1.0.0`) |
|
||||||
| `Description` | String | No | Brief description of the plugin |
|
| `Description` | String | No | Brief description of the plugin |
|
||||||
| `Authors` | String[] | No | List of author names |
|
| `Authors` | String[] | No | List of author names |
|
||||||
| `Website` | String | No | Plugin website or repository URL |
|
| `Website` | String | No | Plugin website or repository URL |
|
||||||
| `Main` | String | Yes | Fully qualified main class name |
|
| `Main` | String | Yes | Fully qualified main class name |
|
||||||
| `ServerVersion` | String | No | Required server version range |
|
| `ServerVersion` | String | No | Required server version range |
|
||||||
| `Dependencies` | Object | No | Required plugin dependencies with version ranges |
|
| `Dependencies` | Object | No | Required plugin dependencies with version ranges |
|
||||||
| `OptionalDependencies` | Object | No | Optional plugin dependencies |
|
| `OptionalDependencies` | Object | No | Optional plugin dependencies |
|
||||||
| `LoadBefore` | String[] | No | Plugins that should load after this one |
|
| `LoadBefore` | String[] | No | Plugins that should load after this one |
|
||||||
| `DisabledByDefault` | Boolean | No | If true, plugin must be explicitly enabled |
|
| `DisabledByDefault` | Boolean | No | If true, plugin must be explicitly enabled |
|
||||||
| `IncludesAssetPack` | Boolean | No | If true, plugin includes client assets |
|
| `IncludesAssetPack` | Boolean | No | If true, plugin includes client assets |
|
||||||
|
|
||||||
### Plugin Identifier
|
### Plugin Identifier
|
||||||
|
|
||||||
Plugins are identified by `Group:Name` format (e.g., `com.example:MyPlugin`). This identifier is used for:
|
Plugins are identified by `Group:Name` format (e.g., `com.example:MyPlugin`). This identifier is used for:
|
||||||
|
|
||||||
- Dependency resolution
|
- Dependency resolution
|
||||||
- Permission namespacing (`com.example.myplugin.*`)
|
- Permission namespacing (`com.example.myplugin.*`)
|
||||||
- Configuration keys
|
- Configuration keys
|
||||||
@@ -121,14 +122,14 @@ public class MyPlugin extends JavaPlugin {
|
|||||||
NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
|
NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
|
||||||
```
|
```
|
||||||
|
|
||||||
| State | Description |
|
| State | Description |
|
||||||
|-------|-------------|
|
|------------|--------------------------------------------------|
|
||||||
| `NONE` | Initial state before any lifecycle methods |
|
| `NONE` | Initial state before any lifecycle methods |
|
||||||
| `SETUP` | `setup()` is executing; register components here |
|
| `SETUP` | `setup()` is executing; register components here |
|
||||||
| `START` | `start()` is executing; plugin becoming active |
|
| `START` | `start()` is executing; plugin becoming active |
|
||||||
| `ENABLED` | Plugin is fully operational and handling events |
|
| `ENABLED` | Plugin is fully operational and handling events |
|
||||||
| `SHUTDOWN` | `shutdown()` is executing; cleanup in progress |
|
| `SHUTDOWN` | `shutdown()` is executing; cleanup in progress |
|
||||||
| `DISABLED` | Plugin is fully disabled and unloaded |
|
| `DISABLED` | Plugin is fully disabled and unloaded |
|
||||||
|
|
||||||
## Configuration
|
## 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`:
|
For example, if your plugin is `com.example:MyPlugin` and you register a command `spawn`:
|
||||||
|
|
||||||
- Base permission: `com.example.myplugin`
|
- Base permission: `com.example.myplugin`
|
||||||
- Command permission: `com.example.myplugin.command.spawn`
|
- Command permission: `com.example.myplugin.command.spawn`
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Event System
|
# 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
|
## Event Architecture
|
||||||
|
|
||||||
@@ -16,28 +17,29 @@ ICancellable // Mixin interface for cancellable events
|
|||||||
|
|
||||||
### Key Classes
|
### Key Classes
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|------------------------|--------------------------------------------|
|
||||||
| `IEvent<K>` | Synchronous event interface |
|
| `IEvent<K>` | Synchronous event interface |
|
||||||
| `IAsyncEvent<K>` | Asynchronous event interface |
|
| `IAsyncEvent<K>` | Asynchronous event interface |
|
||||||
| `ICancellable` | Interface for events that can be cancelled |
|
| `ICancellable` | Interface for events that can be cancelled |
|
||||||
| `EventRegistry` | Plugin-specific event registration |
|
| `EventRegistry` | Plugin-specific event registration |
|
||||||
| `SyncEventBusRegistry` | Global synchronous event bus |
|
| `SyncEventBusRegistry` | Global synchronous event bus |
|
||||||
| `EventPriority` | Event listener priority levels |
|
| `EventPriority` | Event listener priority levels |
|
||||||
|
|
||||||
## Event Priorities
|
## Event Priorities
|
||||||
|
|
||||||
Events are dispatched to listeners in priority order:
|
Events are dispatched to listeners in priority order:
|
||||||
|
|
||||||
| Priority | Value | Description |
|
| Priority | Value | Description |
|
||||||
|----------|-------|-------------|
|
|----------|--------|-------------------------------|
|
||||||
| `FIRST` | -21844 | Runs first, before all others |
|
| `FIRST` | -21844 | Runs first, before all others |
|
||||||
| `EARLY` | -10922 | Runs early, after FIRST |
|
| `EARLY` | -10922 | Runs early, after FIRST |
|
||||||
| `NORMAL` | 0 | Default priority |
|
| `NORMAL` | 0 | Default priority |
|
||||||
| `LATE` | 10922 | Runs late, after NORMAL |
|
| `LATE` | 10922 | Runs late, after NORMAL |
|
||||||
| `LAST` | 21844 | Runs last, after all others |
|
| `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
|
## Registering Event Listeners
|
||||||
|
|
||||||
@@ -148,45 +150,45 @@ getEventRegistry().register(EventPriority.LAST, PlayerInteractEvent.class, event
|
|||||||
|
|
||||||
### Server Lifecycle Events
|
### Server Lifecycle Events
|
||||||
|
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
|-------|-------------|
|
|------------------------|-------------------------|
|
||||||
| `BootEvent` | Server boot complete |
|
| `BootEvent` | Server boot complete |
|
||||||
| `ShutdownEvent` | Server shutting down |
|
| `ShutdownEvent` | Server shutting down |
|
||||||
| `PrepareUniverseEvent` | Universe initialization |
|
| `PrepareUniverseEvent` | Universe initialization |
|
||||||
|
|
||||||
### Player Events
|
### Player Events
|
||||||
|
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
|-------|-------------|
|
|-----------------------------|----------------------------------|
|
||||||
| `PlayerConnectEvent` | Player connected to server |
|
| `PlayerConnectEvent` | Player connected to server |
|
||||||
| `PlayerDisconnectEvent` | Player disconnected |
|
| `PlayerDisconnectEvent` | Player disconnected |
|
||||||
| `AddPlayerToWorldEvent` | Player added to a world |
|
| `AddPlayerToWorldEvent` | Player added to a world |
|
||||||
| `DrainPlayerFromWorldEvent` | Player removed from a world |
|
| `DrainPlayerFromWorldEvent` | Player removed from a world |
|
||||||
| `PlayerInteractEvent` | Player interaction (cancellable) |
|
| `PlayerInteractEvent` | Player interaction (cancellable) |
|
||||||
| `PlayerMouseButtonEvent` | Mouse button input (cancellable) |
|
| `PlayerMouseButtonEvent` | Mouse button input (cancellable) |
|
||||||
|
|
||||||
### Entity Events
|
### Entity Events
|
||||||
|
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
|-------|-------------|
|
|-----------------------------|-----------------------------|
|
||||||
| `EntityRemoveEvent` | Entity removed from world |
|
| `EntityRemoveEvent` | Entity removed from world |
|
||||||
| `LivingEntityUseBlockEvent` | Living entity using a block |
|
| `LivingEntityUseBlockEvent` | Living entity using a block |
|
||||||
|
|
||||||
### World Events
|
### World Events
|
||||||
|
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
|-------|-------------|
|
|------------------------|-----------------------------|
|
||||||
| `AddWorldEvent` | World added to universe |
|
| `AddWorldEvent` | World added to universe |
|
||||||
| `RemoveWorldEvent` | World removed |
|
| `RemoveWorldEvent` | World removed |
|
||||||
| `StartWorldEvent` | World started |
|
| `StartWorldEvent` | World started |
|
||||||
| `AllWorldsLoadedEvent` | All worlds finished loading |
|
| `AllWorldsLoadedEvent` | All worlds finished loading |
|
||||||
|
|
||||||
### ECS Events
|
### ECS Events
|
||||||
|
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
|-------|-------------|
|
|---------------------|-------------------|
|
||||||
| `UseBlockEvent` | Block usage event |
|
| `UseBlockEvent` | Block usage event |
|
||||||
| `DiscoverZoneEvent` | Zone discovery |
|
| `DiscoverZoneEvent` | Zone discovery |
|
||||||
|
|
||||||
## Creating Custom Events
|
## Creating Custom Events
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ The Hytale command system allows plugins to register custom commands that can be
|
|||||||
|
|
||||||
## Overview
|
## 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
|
- Required and optional arguments
|
||||||
- Subcommands
|
- 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`:
|
For example, if your plugin is `com.example:MyPlugin` and command is `spawn`:
|
||||||
|
|
||||||
- Permission: `com.example.myplugin.command.spawn`
|
- Permission: `com.example.myplugin.command.spawn`
|
||||||
|
|
||||||
### Custom Permissions
|
### Custom Permissions
|
||||||
@@ -303,10 +305,10 @@ public void execute(CommandContext context, Arguments args) {
|
|||||||
|
|
||||||
Commands can be executed by different sender types:
|
Commands can be executed by different sender types:
|
||||||
|
|
||||||
| Sender Type | Description |
|
| Sender Type | Description |
|
||||||
|-------------|-------------|
|
|----------------|-------------------------------|
|
||||||
| `Player` | In-game player |
|
| `Player` | In-game player |
|
||||||
| `Console` | Server console |
|
| `Console` | Server console |
|
||||||
| `CommandBlock` | Command block (if applicable) |
|
| `CommandBlock` | Command block (if applicable) |
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Entity Component System (ECS)
|
# 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
|
## ECS Concepts
|
||||||
|
|
||||||
@@ -16,16 +17,16 @@ The ECS pattern separates data (Components) from behavior (Systems):
|
|||||||
|
|
||||||
### Key Classes
|
### Key Classes
|
||||||
|
|
||||||
| Class | Description |
|
| Class | Description |
|
||||||
|-------|-------------|
|
|---------------------|--------------------------------------|
|
||||||
| `Component<S>` | Base component interface |
|
| `Component<S>` | Base component interface |
|
||||||
| `ComponentRegistry` | Central registry for component types |
|
| `ComponentRegistry` | Central registry for component types |
|
||||||
| `Store` | ECS data storage |
|
| `Store` | ECS data storage |
|
||||||
| `Ref` | Entity reference (ID wrapper) |
|
| `Ref` | Entity reference (ID wrapper) |
|
||||||
| `Holder<C>` | Component holder/accessor |
|
| `Holder<C>` | Component holder/accessor |
|
||||||
| `Archetype` | Entity archetype definition |
|
| `Archetype` | Entity archetype definition |
|
||||||
| `SystemType` | System type definition |
|
| `SystemType` | System type definition |
|
||||||
| `Query` | ECS query for finding entities |
|
| `Query` | ECS query for finding entities |
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
@@ -80,14 +81,14 @@ public class HealthComponent implements Component<EntityStore> {
|
|||||||
|
|
||||||
The server provides several built-in components in `EntityStore.REGISTRY`:
|
The server provides several built-in components in `EntityStore.REGISTRY`:
|
||||||
|
|
||||||
| Component | Description |
|
| Component | Description |
|
||||||
|-----------|-------------|
|
|--------------------------|-----------------------------------|
|
||||||
| `TransformComponent` | Position, rotation, and scale |
|
| `TransformComponent` | Position, rotation, and scale |
|
||||||
| `UUIDComponent` | Unique entity identifier |
|
| `UUIDComponent` | Unique entity identifier |
|
||||||
| `ModelComponent` | Visual model reference |
|
| `ModelComponent` | Visual model reference |
|
||||||
| `MovementAudioComponent` | Movement sound effects |
|
| `MovementAudioComponent` | Movement sound effects |
|
||||||
| `PositionDataComponent` | Position tracking data |
|
| `PositionDataComponent` | Position tracking data |
|
||||||
| `HeadRotation` | Head rotation for living entities |
|
| `HeadRotation` | Head rotation for living entities |
|
||||||
|
|
||||||
### Registering Components
|
### Registering Components
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# World Management
|
# 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
|
## Universe
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Networking and Protocol
|
# 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
|
## Overview
|
||||||
|
|
||||||
@@ -15,36 +16,36 @@ The networking layer is built on QUIC protocol and handles:
|
|||||||
|
|
||||||
## Key Components
|
## Key Components
|
||||||
|
|
||||||
| Component | Description |
|
| Component | Description |
|
||||||
|-----------|-------------|
|
|------------------|--------------------------------------------------|
|
||||||
| `Packet` | Base interface for all packets |
|
| `Packet` | Base interface for all packets |
|
||||||
| `PacketRegistry` | Central packet type registration |
|
| `PacketRegistry` | Central packet type registration |
|
||||||
| `PacketHandler` | Manages client connections and packet processing |
|
| `PacketHandler` | Manages client connections and packet processing |
|
||||||
| `ServerManager` | Server network manager |
|
| `ServerManager` | Server network manager |
|
||||||
|
|
||||||
## Packet Categories
|
## Packet Categories
|
||||||
|
|
||||||
Packets are organized into categories in `com.hypixel.hytale.protocol.packets`:
|
Packets are organized into categories in `com.hypixel.hytale.protocol.packets`:
|
||||||
|
|
||||||
| Category | Description |
|
| Category | Description |
|
||||||
|----------|-------------|
|
|-----------------|--------------------------------------------------|
|
||||||
| `connection/` | Connection lifecycle (connect, disconnect, ping) |
|
| `connection/` | Connection lifecycle (connect, disconnect, ping) |
|
||||||
| `auth/` | Authentication and session management |
|
| `auth/` | Authentication and session management |
|
||||||
| `player/` | Player-specific packets (movement, actions) |
|
| `player/` | Player-specific packets (movement, actions) |
|
||||||
| `entities/` | Entity creation, updates, removal |
|
| `entities/` | Entity creation, updates, removal |
|
||||||
| `world/` | World/chunk data streaming |
|
| `world/` | World/chunk data streaming |
|
||||||
| `inventory/` | Inventory operations |
|
| `inventory/` | Inventory operations |
|
||||||
| `interaction/` | Player interactions |
|
| `interaction/` | Player interactions |
|
||||||
| `interface_/` | UI/interface packets |
|
| `interface_/` | UI/interface packets |
|
||||||
| `camera/` | Camera control |
|
| `camera/` | Camera control |
|
||||||
| `setup/` | Initial setup and configuration |
|
| `setup/` | Initial setup and configuration |
|
||||||
| `window/` | Window/container management |
|
| `window/` | Window/container management |
|
||||||
| `assets/` | Asset loading and management |
|
| `assets/` | Asset loading and management |
|
||||||
| `asseteditor/` | Asset editor tools (dev) |
|
| `asseteditor/` | Asset editor tools (dev) |
|
||||||
| `buildertools/` | Building tools |
|
| `buildertools/` | Building tools |
|
||||||
| `machinima/` | Machinima/cinematic tools |
|
| `machinima/` | Machinima/cinematic tools |
|
||||||
| `serveraccess/` | Server access control |
|
| `serveraccess/` | Server access control |
|
||||||
| `worldmap/` | World map data |
|
| `worldmap/` | World map data |
|
||||||
|
|
||||||
## Packet Structure
|
## Packet Structure
|
||||||
|
|
||||||
@@ -163,45 +164,45 @@ for (Player player : Universe.get().getPlayers()) {
|
|||||||
|
|
||||||
### Connection Packets
|
### Connection Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|----------------------------|-----------|-----------------------------------|
|
||||||
| `ConnectionRequestPacket` | C->S | Client requests connection |
|
| `ConnectionRequestPacket` | C->S | Client requests connection |
|
||||||
| `ConnectionResponsePacket` | S->C | Server accepts/rejects connection |
|
| `ConnectionResponsePacket` | S->C | Server accepts/rejects connection |
|
||||||
| `DisconnectPacket` | Both | Connection termination |
|
| `DisconnectPacket` | Both | Connection termination |
|
||||||
| `PingPacket` | Both | Latency measurement |
|
| `PingPacket` | Both | Latency measurement |
|
||||||
|
|
||||||
### Player Packets
|
### Player Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|------------------------|-----------|----------------------------------|
|
||||||
| `PlayerPositionPacket` | Both | Position update |
|
| `PlayerPositionPacket` | Both | Position update |
|
||||||
| `PlayerInputPacket` | C->S | Player input (movement, actions) |
|
| `PlayerInputPacket` | C->S | Player input (movement, actions) |
|
||||||
| `PlayerActionPacket` | C->S | Player actions |
|
| `PlayerActionPacket` | C->S | Player actions |
|
||||||
|
|
||||||
### Entity Packets
|
### Entity Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|----------------------|-----------|---------------------|
|
||||||
| `EntitySpawnPacket` | S->C | Entity creation |
|
| `EntitySpawnPacket` | S->C | Entity creation |
|
||||||
| `EntityUpdatePacket` | S->C | Entity state update |
|
| `EntityUpdatePacket` | S->C | Entity state update |
|
||||||
| `EntityRemovePacket` | S->C | Entity removal |
|
| `EntityRemovePacket` | S->C | Entity removal |
|
||||||
| `EntityMovePacket` | S->C | Entity movement |
|
| `EntityMovePacket` | S->C | Entity movement |
|
||||||
|
|
||||||
### World Packets
|
### World Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|---------------------|-----------|---------------------|
|
||||||
| `ChunkDataPacket` | S->C | Chunk data transfer |
|
| `ChunkDataPacket` | S->C | Chunk data transfer |
|
||||||
| `BlockChangePacket` | S->C | Block state change |
|
| `BlockChangePacket` | S->C | Block state change |
|
||||||
| `WorldTimePacket` | S->C | World time sync |
|
| `WorldTimePacket` | S->C | World time sync |
|
||||||
|
|
||||||
### Inventory Packets
|
### Inventory Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|-------------------------|-----------|--------------------------|
|
||||||
| `InventoryUpdatePacket` | S->C | Inventory contents |
|
| `InventoryUpdatePacket` | S->C | Inventory contents |
|
||||||
| `SlotChangePacket` | Both | Single slot update |
|
| `SlotChangePacket` | Both | Single slot update |
|
||||||
| `ItemPickupPacket` | S->C | Item pickup notification |
|
| `ItemPickupPacket` | S->C | Item pickup notification |
|
||||||
|
|
||||||
## Rate Limiting
|
## Rate Limiting
|
||||||
|
|
||||||
@@ -284,12 +285,12 @@ player.closeUI();
|
|||||||
|
|
||||||
### UI Packets
|
### UI Packets
|
||||||
|
|
||||||
| Packet | Direction | Description |
|
| Packet | Direction | Description |
|
||||||
|--------|-----------|-------------|
|
|-----------------------|-----------|-------------------------------|
|
||||||
| `UIOpenPacket` | S->C | Open a UI screen |
|
| `UIOpenPacket` | S->C | Open a UI screen |
|
||||||
| `UIClosePacket` | S->C | Close UI |
|
| `UIClosePacket` | S->C | Close UI |
|
||||||
| `UIUpdatePacket` | S->C | Update UI data |
|
| `UIUpdatePacket` | S->C | Update UI data |
|
||||||
| `UIInteractionPacket` | C->S | UI button/element interaction |
|
| `UIInteractionPacket` | C->S | UI button/element interaction |
|
||||||
|
|
||||||
## Network Compression
|
## Network Compression
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Asset System
|
# 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
|
## Overview
|
||||||
|
|
||||||
@@ -38,19 +39,19 @@ Assets are loaded from:
|
|||||||
|
|
||||||
The server supports many built-in asset types located in `server/core/asset/type/`:
|
The server supports many built-in asset types located in `server/core/asset/type/`:
|
||||||
|
|
||||||
| Asset Type | Description |
|
| Asset Type | Description |
|
||||||
|------------|-------------|
|
|--------------------|---------------------------------------|
|
||||||
| `BlockType` | Block definitions (stone, dirt, etc.) |
|
| `BlockType` | Block definitions (stone, dirt, etc.) |
|
||||||
| `ItemType` | Item definitions |
|
| `ItemType` | Item definitions |
|
||||||
| `ModelAsset` | 3D model definitions |
|
| `ModelAsset` | 3D model definitions |
|
||||||
| `SoundEvent` | Sound effect definitions |
|
| `SoundEvent` | Sound effect definitions |
|
||||||
| `ParticleAsset` | Particle system definitions |
|
| `ParticleAsset` | Particle system definitions |
|
||||||
| `WeatherAsset` | Weather type definitions |
|
| `WeatherAsset` | Weather type definitions |
|
||||||
| `EnvironmentAsset` | Environment settings |
|
| `EnvironmentAsset` | Environment settings |
|
||||||
| `FluidAsset` | Fluid definitions |
|
| `FluidAsset` | Fluid definitions |
|
||||||
| `EntityEffect` | Entity effect definitions |
|
| `EntityEffect` | Entity effect definitions |
|
||||||
| `BiomeAsset` | Biome definitions |
|
| `BiomeAsset` | Biome definitions |
|
||||||
| `StructureAsset` | Structure/prefab definitions |
|
| `StructureAsset` | Structure/prefab definitions |
|
||||||
|
|
||||||
## Blocks
|
## Blocks
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Configuration System
|
# 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
|
## Server Configuration
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Codec and Serialization System
|
# 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
|
## Overview
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ public interface Codec<T> {
|
|||||||
|
|
||||||
### DataInput/DataOutput
|
### 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
|
## Primitive Codecs
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Utilities and Common APIs
|
# 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
|
## Math Utilities
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Early Plugin System (Class Transformation)
|
# 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
|
## Overview
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ Early plugins are appropriate when:
|
|||||||
- Standard plugin APIs don't provide sufficient access
|
- Standard plugin APIs don't provide sufficient access
|
||||||
|
|
||||||
**Prefer standard plugins** when possible. Early plugins:
|
**Prefer standard plugins** when possible. Early plugins:
|
||||||
|
|
||||||
- Are harder to maintain across server updates
|
- Are harder to maintain across server updates
|
||||||
- May conflict with other early plugins
|
- May conflict with other early plugins
|
||||||
- Can introduce hard-to-debug issues
|
- Can introduce hard-to-debug issues
|
||||||
@@ -223,12 +225,12 @@ public int priority() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Priority | Use Case |
|
| Priority | Use Case |
|
||||||
|----------|----------|
|
|------------|-----------------------------------|
|
||||||
| 1000+ | Critical patches (security fixes) |
|
| 1000+ | Critical patches (security fixes) |
|
||||||
| 100-999 | Core modifications |
|
| 100-999 | Core modifications |
|
||||||
| 0 | Standard transformations |
|
| 0 | Standard transformations |
|
||||||
| -100 to -1 | Post-processing |
|
| -100 to -1 | Post-processing |
|
||||||
|
|
||||||
## Compatibility Considerations
|
## Compatibility Considerations
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# UI System
|
# 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
|
## Architecture Overview
|
||||||
|
|
||||||
@@ -19,14 +20,14 @@ UI System
|
|||||||
|
|
||||||
### Core Classes
|
### Core Classes
|
||||||
|
|
||||||
| Class | Package | Description |
|
| Class | Package | Description |
|
||||||
|-------|---------|-------------|
|
|------------------------------|---------------------------------------------------------------|-----------------------------------------|
|
||||||
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages` | Abstract base for all custom pages |
|
| `CustomUIPage` | `com.hypixel.hytale.server.core.entity.entities.player.pages` | Abstract base for all custom pages |
|
||||||
| `BasicCustomUIPage` | Same | Simple pages without event data parsing |
|
| `BasicCustomUIPage` | Same | Simple pages without event data parsing |
|
||||||
| `InteractiveCustomUIPage<T>` | Same | Pages with typed event handling |
|
| `InteractiveCustomUIPage<T>` | Same | Pages with typed event handling |
|
||||||
| `PageManager` | Same | Manages page state for a player |
|
| `PageManager` | Same | Manages page state for a player |
|
||||||
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder` | Builds UI DOM commands |
|
| `UICommandBuilder` | `com.hypixel.hytale.server.core.ui.builder` | Builds UI DOM commands |
|
||||||
| `UIEventBuilder` | Same | Builds event bindings |
|
| `UIEventBuilder` | Same | Builds event bindings |
|
||||||
|
|
||||||
### Page Lifetime
|
### Page Lifetime
|
||||||
|
|
||||||
@@ -236,6 +237,7 @@ Value<Integer> border = Value.ref("Pages/Dialog.ui", "BorderWidth");
|
|||||||
### Encoding Format
|
### Encoding Format
|
||||||
|
|
||||||
References are encoded in JSON as:
|
References are encoded in JSON as:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"$Document": "Common/Button.ui",
|
"$Document": "Common/Button.ui",
|
||||||
@@ -508,36 +510,36 @@ public enum HudComponent {
|
|||||||
|
|
||||||
### Page Packets
|
### Page Packets
|
||||||
|
|
||||||
| Packet | ID | Direction | Description |
|
| Packet | ID | Direction | Description |
|
||||||
|--------|-----|-----------|-------------|
|
|-------------------|-----|-----------|-------------------|
|
||||||
| `SetPage` | 216 | S->C | Set built-in page |
|
| `SetPage` | 216 | S->C | Set built-in page |
|
||||||
| `CustomHud` | 217 | S->C | Update HUD |
|
| `CustomHud` | 217 | S->C | Update HUD |
|
||||||
| `CustomPage` | 218 | S->C | Send custom page |
|
| `CustomPage` | 218 | S->C | Send custom page |
|
||||||
| `CustomPageEvent` | 219 | C->S | Page event |
|
| `CustomPageEvent` | 219 | C->S | Page event |
|
||||||
|
|
||||||
### Window Packets
|
### Window Packets
|
||||||
|
|
||||||
| Packet | ID | Direction | Description |
|
| Packet | ID | Direction | Description |
|
||||||
|--------|-----|-----------|-------------|
|
|--------------------|-----|-----------|----------------|
|
||||||
| `OpenWindow` | 200 | S->C | Open window |
|
| `OpenWindow` | 200 | S->C | Open window |
|
||||||
| `UpdateWindow` | 201 | S->C | Update window |
|
| `UpdateWindow` | 201 | S->C | Update window |
|
||||||
| `CloseWindow` | 202 | S->C | Close window |
|
| `CloseWindow` | 202 | S->C | Close window |
|
||||||
| `ClientOpenWindow` | 203 | C->S | Request window |
|
| `ClientOpenWindow` | 203 | C->S | Request window |
|
||||||
| `SendWindowAction` | 204 | C->S | Window action |
|
| `SendWindowAction` | 204 | C->S | Window action |
|
||||||
|
|
||||||
## Known UI Documents
|
## Known UI Documents
|
||||||
|
|
||||||
| Path | Purpose |
|
| Path | Purpose |
|
||||||
|------|---------|
|
|----------------------------|---------------------|
|
||||||
| `Pages/DialogPage.ui` | Dialog/conversation |
|
| `Pages/DialogPage.ui` | Dialog/conversation |
|
||||||
| `Pages/BarterPage.ui` | Trading interface |
|
| `Pages/BarterPage.ui` | Trading interface |
|
||||||
| `Pages/ShopPage.ui` | Shop interface |
|
| `Pages/ShopPage.ui` | Shop interface |
|
||||||
| `Pages/RespawnPage.ui` | Death/respawn |
|
| `Pages/RespawnPage.ui` | Death/respawn |
|
||||||
| `Pages/ChangeModelPage.ui` | Model selection |
|
| `Pages/ChangeModelPage.ui` | Model selection |
|
||||||
| `Pages/WarpListPage.ui` | Teleport list |
|
| `Pages/WarpListPage.ui` | Teleport list |
|
||||||
| `Pages/CommandListPage.ui` | Command help |
|
| `Pages/CommandListPage.ui` | Command help |
|
||||||
| `Pages/PluginListPage.ui` | Plugin list |
|
| `Pages/PluginListPage.ui` | Plugin list |
|
||||||
| `Common/TextButton.ui` | Reusable button |
|
| `Common/TextButton.ui` | Reusable button |
|
||||||
|
|
||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
# Hytale Server Modding Documentation
|
# 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 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
|
## Documentation Index
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ Welcome to the Hytale Server modding documentation. This guide provides comprehe
|
|||||||
### Creating Your First Mod
|
### Creating Your First Mod
|
||||||
|
|
||||||
1. Create a `manifest.json`:
|
1. Create a `manifest.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"Group": "com.example",
|
"Group": "com.example",
|
||||||
@@ -56,6 +59,7 @@ Welcome to the Hytale Server modding documentation. This guide provides comprehe
|
|||||||
```
|
```
|
||||||
|
|
||||||
2. Create your main class:
|
2. Create your main class:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class MyMod extends JavaPlugin {
|
public class MyMod extends JavaPlugin {
|
||||||
public MyMod(JavaPluginInit init) {
|
public MyMod(JavaPluginInit init) {
|
||||||
@@ -85,23 +89,23 @@ NONE -> SETUP -> START -> ENABLED -> SHUTDOWN -> DISABLED
|
|||||||
|
|
||||||
### Available Registries
|
### Available Registries
|
||||||
|
|
||||||
| Registry | Purpose |
|
| Registry | Purpose |
|
||||||
|----------|---------|
|
|-------------------|-----------------|
|
||||||
| `CommandRegistry` | Custom commands |
|
| `CommandRegistry` | Custom commands |
|
||||||
| `EventRegistry` | Event listeners |
|
| `EventRegistry` | Event listeners |
|
||||||
| `EntityRegistry` | Custom entities |
|
| `EntityRegistry` | Custom entities |
|
||||||
| `AssetRegistry` | Custom assets |
|
| `AssetRegistry` | Custom assets |
|
||||||
| `TaskRegistry` | Scheduled tasks |
|
| `TaskRegistry` | Scheduled tasks |
|
||||||
|
|
||||||
### Event Priority
|
### Event Priority
|
||||||
|
|
||||||
| Priority | Value | Use Case |
|
| Priority | Value | Use Case |
|
||||||
|----------|-------|----------|
|
|----------|--------|--------------------|
|
||||||
| FIRST | -21844 | Monitoring/logging |
|
| FIRST | -21844 | Monitoring/logging |
|
||||||
| EARLY | -10922 | Pre-processing |
|
| EARLY | -10922 | Pre-processing |
|
||||||
| NORMAL | 0 | Standard handling |
|
| NORMAL | 0 | Standard handling |
|
||||||
| LATE | 10922 | Post-processing |
|
| LATE | 10922 | Post-processing |
|
||||||
| LAST | 21844 | Final processing |
|
| LAST | 21844 | Final processing |
|
||||||
|
|
||||||
## Package Structure
|
## Package Structure
|
||||||
|
|
||||||
@@ -120,6 +124,7 @@ com.hypixel.hytale/
|
|||||||
## API Highlights
|
## API Highlights
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
|
|
||||||
```java
|
```java
|
||||||
getEventRegistry().register(PlayerConnectEvent.class, event -> {
|
getEventRegistry().register(PlayerConnectEvent.class, event -> {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
@@ -128,6 +133,7 @@ getEventRegistry().register(PlayerConnectEvent.class, event -> {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class MyCommand extends AbstractCommand {
|
public class MyCommand extends AbstractCommand {
|
||||||
public MyCommand() {
|
public MyCommand() {
|
||||||
@@ -144,6 +150,7 @@ public class MyCommand extends AbstractCommand {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Entities
|
### Entities
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public class CustomEntity extends Entity {
|
public class CustomEntity extends Entity {
|
||||||
public CustomEntity(World world) {
|
public CustomEntity(World world) {
|
||||||
@@ -156,6 +163,7 @@ getEntityRegistry().register("custom", CustomEntity.class, CustomEntity::new);
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static final Codec<MyConfig> CODEC = BuilderCodec.of(MyConfig::new)
|
public static final Codec<MyConfig> CODEC = BuilderCodec.of(MyConfig::new)
|
||||||
.with("enabled", Codec.BOOLEAN, c -> c.enabled, true)
|
.with("enabled", Codec.BOOLEAN, c -> c.enabled, true)
|
||||||
@@ -177,6 +185,7 @@ public static final Codec<MyConfig> CODEC = BuilderCodec.of(MyConfig::new)
|
|||||||
## Support
|
## Support
|
||||||
|
|
||||||
For questions and support:
|
For questions and support:
|
||||||
|
|
||||||
- Check the [Hytale modding forums](#)
|
- Check the [Hytale modding forums](#)
|
||||||
- Join the [Discord community](#)
|
- Join the [Discord community](#)
|
||||||
- Report issues on [GitHub](#)
|
- 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).*
|
||||||
|
|||||||
@@ -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.InteractionContext;
|
||||||
import com.hypixel.hytale.server.core.entity.InteractionManager;
|
import com.hypixel.hytale.server.core.entity.InteractionManager;
|
||||||
import com.hypixel.hytale.server.core.entity.LivingEntity;
|
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.DynamicMetaStore;
|
||||||
import com.hypixel.hytale.server.core.meta.MetaKey;
|
import com.hypixel.hytale.server.core.meta.MetaKey;
|
||||||
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
|
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.RootInteraction;
|
||||||
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.data.Collector;
|
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.universe.world.storage.EntityStore;
|
||||||
import com.hypixel.hytale.server.core.event.events.ecs.ChangeHotbarSlotEvent;
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ChangeActiveSlotInteraction extends Interaction {
|
public class ChangeActiveSlotInteraction extends Interaction {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static final ChangeActiveSlotInteraction DEFAULT_INTERACTION = new ChangeActiveSlotInteraction("*Change_Active_Slot");
|
public static final ChangeActiveSlotInteraction DEFAULT_INTERACTION = new ChangeActiveSlotInteraction("*Change_Active_Slot");
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static final RootInteraction DEFAULT_ROOT = new RootInteraction(
|
public static final RootInteraction DEFAULT_ROOT = new RootInteraction(
|
||||||
"*Default_Swap",
|
"*Default_Swap",
|
||||||
new InteractionCooldown("ChangeActiveSlot", 0.0F, false, InteractionManager.DEFAULT_CHARGE_TIMES, true, false),
|
new InteractionCooldown("ChangeActiveSlot", 0.0F, false, InteractionManager.DEFAULT_CHARGE_TIMES, true, false),
|
||||||
DEFAULT_INTERACTION.getId()
|
DEFAULT_INTERACTION.getId()
|
||||||
);
|
);
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static final MetaKey<Runnable> PLACE_MOVED_ITEM = CONTEXT_META_REGISTRY.registerMetaObject(i -> null);
|
public static final MetaKey<Runnable> PLACE_MOVED_ITEM = CONTEXT_META_REGISTRY.registerMetaObject(i -> null);
|
||||||
private static final int UNSET_INT = Integer.MIN_VALUE;
|
private static final int UNSET_INT = Integer.MIN_VALUE;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static final BuilderCodec<ChangeActiveSlotInteraction> CODEC = BuilderCodec.builder(
|
public static final BuilderCodec<ChangeActiveSlotInteraction> CODEC = BuilderCodec.builder(
|
||||||
ChangeActiveSlotInteraction.class, ChangeActiveSlotInteraction::new, Interaction.ABSTRACT_CODEC
|
ChangeActiveSlotInteraction.class, ChangeActiveSlotInteraction::new, Interaction.ABSTRACT_CODEC
|
||||||
)
|
)
|
||||||
.documentation("Changes the active hotbar slot for the user of the interaction.")
|
.documentation("Changes the active hotbar slot for the user of the interaction.")
|
||||||
.<Integer>appendInherited(
|
.<Integer>appendInherited(
|
||||||
new KeyedCodec<>("TargetSlot", Codec.INTEGER),
|
new KeyedCodec<>("TargetSlot", Codec.INTEGER),
|
||||||
(o, i) -> o.targetSlot = i == null ? Integer.MIN_VALUE : i,
|
(o, i) -> o.targetSlot = i == null ? Integer.MIN_VALUE : i,
|
||||||
o -> o.targetSlot == Integer.MIN_VALUE ? null : o.targetSlot,
|
o -> o.targetSlot == Integer.MIN_VALUE ? null : o.targetSlot,
|
||||||
(o, p) -> o.targetSlot = p.targetSlot
|
(o, p) -> o.targetSlot = p.targetSlot
|
||||||
)
|
)
|
||||||
.addValidator(Validators.range(0, 8))
|
.addValidator(Validators.range(0, 8))
|
||||||
.add()
|
.add()
|
||||||
.afterDecode(i -> i.cancelOnItemChange = false)
|
.afterDecode(i -> i.cancelOnItemChange = false)
|
||||||
.build();
|
.build();
|
||||||
protected int targetSlot = Integer.MIN_VALUE;
|
protected int targetSlot = Integer.MIN_VALUE;
|
||||||
|
|
||||||
public ChangeActiveSlotInteraction() {
|
public ChangeActiveSlotInteraction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChangeActiveSlotInteraction(@Nonnull String id) {
|
private ChangeActiveSlotInteraction(@Nonnull String id) {
|
||||||
super(id);
|
super(id);
|
||||||
this.cancelOnItemChange = false;
|
this.cancelOnItemChange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public WaitForDataFrom getWaitForDataFrom() {
|
public WaitForDataFrom getWaitForDataFrom() {
|
||||||
return WaitForDataFrom.None;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tick0(
|
||||||
|
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
|
||||||
|
) {
|
||||||
|
if (!firstRun) {
|
||||||
context.getState().state = InteractionState.Finished;
|
context.getState().state = InteractionState.Finished;
|
||||||
}
|
} else {
|
||||||
}
|
CommandBuffer<EntityStore> commandBuffer = context.getCommandBuffer();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
assert commandBuffer != null;
|
||||||
protected void simulateTick0(
|
|
||||||
boolean firstRun, float time, @Nonnull InteractionType type, @Nonnull InteractionContext context, @Nonnull CooldownHandler cooldownHandler
|
|
||||||
) {
|
|
||||||
context.getState().state = context.getServerState().state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
Ref<EntityStore> ref = context.getEntity();
|
||||||
public boolean walk(@Nonnull Collector collector, @Nonnull InteractionContext context) {
|
if (EntityUtils.getEntity(ref, commandBuffer) instanceof LivingEntity livingEntity) {
|
||||||
return false;
|
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
|
slot = (byte) this.targetSlot;
|
||||||
public boolean needsRemoteSync() {
|
var15.putMetaObject(TARGET_SLOT, Integer.valueOf(slot));
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
byte previousSlot = livingEntity.getInventory().getActiveHotbarSlot();
|
||||||
@Override
|
ChangeHotbarSlotEvent event = new ChangeHotbarSlotEvent(previousSlot, slot, false);
|
||||||
protected com.hypixel.hytale.protocol.Interaction generatePacket() {
|
commandBuffer.invoke(ref, event);
|
||||||
return new com.hypixel.hytale.protocol.ChangeActiveSlotInteraction();
|
if (event.isCancelled()) {
|
||||||
}
|
context.getState().state = InteractionState.Finished;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slot = event.getNewSlot();
|
||||||
|
|
||||||
@Override
|
livingEntity.getInventory().setActiveHotbarSlot(slot);
|
||||||
protected void configurePacket(com.hypixel.hytale.protocol.Interaction packet) {
|
Runnable action = (Runnable) var15.removeMetaObject(PLACE_MOVED_ITEM);
|
||||||
super.configurePacket(packet);
|
if (action != null) {
|
||||||
com.hypixel.hytale.protocol.ChangeActiveSlotInteraction p = (com.hypixel.hytale.protocol.ChangeActiveSlotInteraction)packet;
|
action.run();
|
||||||
p.targetSlot = this.targetSlot;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
InteractionManager interactionManager = context.getInteractionManager();
|
||||||
@Override
|
|
||||||
public String toString() {
|
assert interactionManager != null;
|
||||||
return "ChangeActiveSlotInteraction{targetSlot=" + this.targetSlot + "} " + super.toString();
|
|
||||||
}
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user