Sending Packets
Packets are sent through the player's connection:
1// Send to single player2player.getPlayerConnection().write(packet);34// Send to all players in world5for (Player p : world.getPlayers()) {6 p.getPlayerConnection().write(packet);7}thread safe
Packet sending is thread-safe. You don't need
world.execute() for packets.Common Packets
| packet | purpose |
|---|---|
| ShowEventTitle | Display title/subtitle text |
| UpdateMovementSettings | Change player physics |
| SpawnParticleSystem | Spawn particle effects |
| UpdateModel | Change entity appearance |
| PlaySound | Play sound effects |
| TeleportEntity | Move entities instantly |
Packet Examples
ShowEventTitle
1// Create formatted title text2FormattedMessage title = new FormattedMessage(3 "WELCOME", // rawText4 null, // messageId5 null, // children6 null, // params7 null, // messageParams8 "#00FF88", // color (hex)9 MaybeBool.True, // bold10 MaybeBool.False, // italic11 MaybeBool.False, // monospace12 MaybeBool.False, // underlined13 null, // link14 false // markupEnabled15);1617FormattedMessage subtitle = new FormattedMessage(18 "Enjoy your stay",19 null, null, null, null,20 "#AAAAAA",21 MaybeBool.False, // bold22 MaybeBool.True, // italic23 MaybeBool.False, // monospace24 MaybeBool.False, // underlined25 null, false26);2728// Create and send packet29ShowEventTitle packet = new ShowEventTitle(30 0.5f, // fadeIn (seconds)31 0.5f, // fadeOut (seconds)32 3.0f, // duration (seconds)33 null, // icon34 true, // isMajor35 title, // primaryTitle36 subtitle // secondaryTitle37);3839player.getPlayerConnection().write(packet);no strikethrough!
FormattedMessage does NOT have strikethrough. Params 9-10 are monospace and underlined.
SpawnParticleSystem
1// Get player position (returns Vector3d, not Position)2TransformComponent transform = player.getTransformComponent();3Vector3d pos = transform.getPosition();45// Create particle packet6SpawnParticleSystem packet = new SpawnParticleSystem(7 "Poof_Large", // particle name8 new Position(pos.x, pos.y + 1, pos.z), // spawn position9 new Direction(0f, 0f, 0f), // direction10 1.5f, // scale11 null // color (null = default)12);1314// Send to all nearby players15for (Player p : world.getPlayers()) {16 p.getPlayerConnection().write(packet);17}UpdateMovementSettings
1// Get default movement settings2MovementSettings settings = MovementConfig.DEFAULT_MOVEMENT.toPacket();34// Modify speed5settings.baseSpeed *= 2.0f; // Double speed6settings.forwardWalkSpeedMultiplier *= 2.0f;7settings.backwardWalkSpeedMultiplier *= 2.0f;8settings.strafeWalkSpeedMultiplier *= 2.0f;910// Modify jump11settings.jumpForce *= 1.5f; // 50% higher jumps1213// Apply to player14UpdateMovementSettings packet = new UpdateMovementSettings(settings);15player.getPlayerConnection().write(packet);Discovering Packets
Find available packets in the server JAR:
1# List all packet classes2jar tf HytaleServer.jar | grep "protocol/packets"34# Inspect packet constructor5javap -public -cp HytaleServer.jar \6 com.hypixel.hytale.server.protocol.packets.ShowEventTitleMaybeBool Enum
common gotcha
The
MaybeBool enum uses PascalCase: MaybeBool.True,MaybeBool.False, MaybeBool.Null. NOT TRUE/FALSE.1// CORRECT2MaybeBool.True3MaybeBool.False4MaybeBool.Null // for "unset" / default56// WRONG - will not compile7MaybeBool.TRUE8MaybeBool.FALSEBroadcast Helper
Create utilities for common packet operations:
PacketUtils.javajava
1public class PacketUtils {2 3 public static void broadcast(World world, Object packet) {4 for (Player player : world.getPlayers()) {5 player.getPlayerConnection().write(packet);6 }7 }8 9 public static void broadcastExcept(World world, Player except, Object packet) {10 for (Player player : world.getPlayers()) {11 if (!player.equals(except)) {12 player.getPlayerConnection().write(packet);13 }14 }15 }16 17 public static void broadcastNear(Position center, double radius, Object packet) {18 // Send to players within radius of position19 for (Player player : getPlayersNear(center, radius)) {20 player.getPlayerConnection().write(packet);21 }22 }23}