---
title: Player Events
type: docs
weight: 1
---

Events triggered by player actions and state changes.

## Connection Events

### PlayerSetupConnectEvent

{{< badge "Cancellable" >}}

Fired during player connection setup. Can be cancelled to prevent connection or redirect to another server.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| uuid | `UUID` | Player's unique identifier |
| username | `String` | Player's username |
| auth | `PlayerAuthentication` | Authentication information |
| referralData | `byte[]` | Data from referral (if redirected) |
| referralSource | `HostAddress` | Server that referred player |
{{< /tab >}}
{{< tab >}}
- `getUuid()` - Returns player UUID
- `getUsername()` - Returns player username
- `getAuth()` - Returns authentication data
- `getReferralData()` - Returns referral data (may be null)
- `isReferralConnection()` - Check if redirected from another server
- `getReferralSource()` - Returns source server address
- `referToServer(host, port)` - Redirect player to another server
- `referToServer(host, port, data)` - Redirect with data
- `getReason()` - Get disconnect reason message
- `setReason(String)` - Set disconnect reason message
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel connection
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
    String username = event.getUsername();
    UUID uuid = event.getUuid();

    // Ban check
    if (isBanned(uuid)) {
        event.setCancelled(true);
        event.setReason("You are banned from this server!");
        return;
    }

    // Redirect to different server based on condition
    if (shouldRedirect(uuid)) {
        event.referToServer("lobby.example.com", 25565);
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PlayerConnectEvent

Fired when a player connects to the server. Use this to set the spawn world.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| playerRef | `PlayerRef` | Reference to the connecting player |
| world | `World` | The world player will spawn in |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getPlayerRef()` - Returns the player reference
- `getPlayer()` - Returns the Player object (deprecated)
- `getWorld()` - Returns current spawn world (may be null)
- `setWorld(World)` - Set the world player will spawn in
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerConnectEvent.class, event -> {
    PlayerRef playerRef = event.getPlayerRef();
    getLogger().at(Level.INFO).log("Player connecting: " + playerRef.getUsername());

    // Set spawn world
    World lobbyWorld = Universe.get().getWorld("lobby");
    if (lobbyWorld != null) {
        event.setWorld(lobbyWorld);
    }
});
```
{{< /tab >}}
{{< /tabs >}}

{{< callout type="warning" >}}
The `getPlayer()` method is deprecated. Prefer using `getPlayerRef()` or `getHolder()` to access player data.
{{< /callout >}}

---

### PlayerSetupDisconnectEvent

Fired when a player disconnects during the setup phase (before fully connecting).

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| uuid | `UUID` | Player's unique identifier |
| username | `String` | Player's username |
| auth | `PlayerAuthentication` | Authentication information |
| disconnectReason | `DisconnectReason` | Why the player disconnected |
{{< /tab >}}
{{< tab >}}
- `getUuid()` - Returns player UUID
- `getUsername()` - Returns player username
- `getAuth()` - Returns authentication data
- `getDisconnectReason()` - Returns disconnect reason
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerSetupDisconnectEvent.class, event -> {
    String username = event.getUsername();
    PacketHandler.DisconnectReason reason = event.getDisconnectReason();

    getLogger().at(Level.INFO).log("Player " + username + " disconnected during setup: " + reason);

    // Cleanup any pre-connection data
    cleanupPendingData(event.getUuid());
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PlayerReadyEvent

Fired when a player is fully ready and loaded into the game. This is the safe point to interact with the player.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The player object |
| readyId | `int` | Ready event identifier |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns the entity store reference
- `getReadyId()` - Returns the ready event ID
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerReadyEvent.class, event -> {
    Player player = event.getPlayer();

    // Player is fully loaded, safe to send complex data
    player.sendMessage(Message.raw("Welcome to the server!"));
    loadPlayerData(player);
    sendWelcomeScreen(player);
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PlayerDisconnectEvent

Fired when a player disconnects from the server.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `PlayerRef` | Reference to the disconnecting player |
{{< /tab >}}
{{< tab >}}
- `getPlayerRef()` - Returns the player reference
- `getDisconnectReason()` - Returns why the player disconnected
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
    PlayerRef playerRef = event.getPlayerRef();

    savePlayerData(playerRef.getUuid());
    getLogger().at(Level.INFO).log(playerRef.getUsername() + " has left the server");

    // Check disconnect reason
    PacketHandler.DisconnectReason reason = event.getDisconnectReason();
    getLogger().at(Level.INFO).log("Reason: " + reason);
});
```
{{< /tab >}}
{{< /tabs >}}

---

## World Events

### AddPlayerToWorldEvent

Fired when a player is added to a world.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| world | `World` | The world being entered |
| broadcastJoinMessage | `boolean` | Whether to broadcast join message |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getWorld()` - Returns the world
- `shouldBroadcastJoinMessage()` - Check if join message will be sent
- `setBroadcastJoinMessage(boolean)` - Control join message broadcast
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(AddPlayerToWorldEvent.class, event -> {
    World world = event.getWorld();

    // Disable default join message for silent joins
    if (isSilentJoin(event.getHolder())) {
        event.setBroadcastJoinMessage(false);
    }

    applyWorldEffects(event.getHolder(), world);
});
```
{{< /tab >}}
{{< /tabs >}}

---

### DrainPlayerFromWorldEvent

Fired when a player is removed from a world (before teleporting to another or disconnecting).

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| holder | `Holder<EntityStore>` | Entity store holder |
| world | `World` | The world being left |
| transform | `Transform` | Player's position/rotation |
{{< /tab >}}
{{< tab >}}
- `getHolder()` - Returns the entity store holder
- `getWorld()` - Returns the world being left
- `setWorld(World)` - Change destination world
- `getTransform()` - Returns player's transform
- `setTransform(Transform)` - Set spawn transform in new world
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(DrainPlayerFromWorldEvent.class, event -> {
    World world = event.getWorld();

    removeWorldEffects(event.getHolder());
    saveWorldProgress(event.getHolder(), world);

    // Optionally redirect to different world
    World newWorld = Universe.get().getWorld("hub");
    if (newWorld != null) {
        event.setWorld(newWorld);
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Chat Events

### PlayerChatEvent

{{< badge "Cancellable" >}} {{< badge "Async" >}}

Fired when a player sends a chat message. This event is asynchronous.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| sender | `PlayerRef` | The player sending the message |
| targets | `List<PlayerRef>` | Players who will receive the message |
| content | `String` | The message content |
| formatter | `Formatter` | Message formatting handler |
{{< /tab >}}
{{< tab >}}
- `getSender()` - Returns the sending player reference
- `setSender(PlayerRef)` - Change the sender
- `getContent()` - Returns the message content
- `setContent(String)` - Modify the message
- `getTargets()` - Returns message recipients
- `setTargets(List<PlayerRef>)` - Change recipients
- `getFormatter()` - Returns the message formatter
- `setFormatter(Formatter)` - Set custom formatter
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the message
{{< /tab >}}
{{< tab >}}
```java
// PlayerChatEvent has String key and is async - use registerAsyncGlobal()
getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
    return future.thenApply(event -> {
        PlayerRef sender = event.getSender();
        String message = event.getContent();

        // Filter bad words
        if (containsBadWord(message)) {
            event.setCancelled(true);
            // Use PlayerRef.sendMessage() directly
            sender.sendMessage(Message.raw("Please don't use that word!"));
            return event;
        }

        // Add prefix based on rank
        String prefix = getPlayerPrefix(sender);
        event.setContent(prefix + message);

        // Custom formatter
        event.setFormatter((playerRef, msg) ->
            Message.translation("custom.chat.format")
                .param("name", playerRef.getUsername())
                .param("message", msg)
        );

        return event;
    });
});
```
{{< /tab >}}
{{< /tabs >}}

{{< callout type="info" >}}
**Async Event:** This event runs asynchronously. Use `sender.getReference()` to check if the player is still online (returns null or invalid reference if disconnected).
{{< /callout >}}

---

## Crafting Events

### PlayerCraftEvent

{{< badge "Deprecated" >}}

Fired when a player crafts an item.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< callout type="warning" >}}
**Deprecated:** This event is marked for removal. Use `CraftRecipeEvent` from the ECS events instead.
{{< /callout >}}

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| ref | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The crafting player |
| craftedRecipe | `CraftingRecipe` | The recipe being crafted |
| quantity | `int` | Number of items crafted |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getCraftedRecipe()` - Returns the crafting recipe
- `getQuantity()` - Returns number crafted
{{< /tab >}}
{{< tab >}}
```java
// Deprecated - prefer CraftRecipeEvent
getEventRegistry().register(PlayerCraftEvent.class, event -> {
    Player player = event.getPlayer();
    CraftingRecipe recipe = event.getCraftedRecipe();
    int quantity = event.getQuantity();

    getLogger().at(Level.INFO).log(player.getDisplayName() + " crafted " + quantity + " items");
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Input Events

### PlayerMouseButtonEvent

{{< badge "Cancellable" >}}

Fired when a player presses a mouse button.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `PlayerRef` | Reference to the player |
| clientUseTime | `long` | Client-side timestamp |
| itemInHand | `Item` | The item being held |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
| screenPoint | `Vector2f` | Screen coordinates |
| mouseButton | `MouseButtonEvent` | Which button was pressed |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getPlayerRefComponent()` - Returns PlayerRef component
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns held item
- `getTargetBlock()` - Returns targeted block position
- `getTargetEntity()` - Returns targeted entity
- `getScreenPoint()` - Returns screen coordinates
- `getMouseButton()` - Returns mouse button info
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the input
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerMouseButtonEvent.class, event -> {
    Player player = event.getPlayer();

    // Prevent input during cutscene
    if (isInCutscene(player)) {
        event.setCancelled(true);
        return;
    }

    // Custom item interaction
    Item item = event.getItemInHand();
    if (item != null && item.getId().equals("magic_wand")) {
        handleMagicWandUse(player, event.getTargetBlock());
    }
});
```
{{< /tab >}}
{{< /tabs >}}

---

### PlayerMouseMotionEvent

{{< badge "Cancellable" >}}

Fired when a player moves their mouse (camera rotation, aiming).

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| playerRef | `Ref<EntityStore>` | Entity store reference |
| player | `Player` | The player |
| clientUseTime | `long` | Client-side timestamp |
| itemInHand | `Item` | The item being held |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
| screenPoint | `Vector2f` | Screen coordinates |
| mouseMotion | `MouseMotionEvent` | Mouse motion data |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getPlayerRef()` - Returns entity store reference
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns held item
- `getTargetBlock()` - Returns targeted block position
- `getTargetEntity()` - Returns targeted entity
- `getScreenPoint()` - Returns screen coordinates
- `getMouseMotion()` - Returns mouse motion data
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel the motion event
{{< /tab >}}
{{< tab >}}
```java
getEventRegistry().register(PlayerMouseMotionEvent.class, event -> {
    Player player = event.getPlayer();

    // Track what the player is looking at
    Entity target = event.getTargetEntity();
    if (target != null) {
        updatePlayerTarget(player, target);
    }

    // Track camera movement for analytics
    trackCameraMovement(player, event.getMouseMotion());
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Interaction Events

### PlayerInteractEvent

{{< badge "Deprecated" >}} {{< badge "Cancellable" >}}

Fired when a player interacts with the world.

**Package:** `com.hypixel.hytale.server.core.event.events.player`

{{< callout type="warning" >}}
**Deprecated:** This event is deprecated. Use more specific events like `UseBlockEvent`, `PlayerMouseButtonEvent`, or ECS interaction events instead.
{{< /callout >}}

{{< tabs items="Fields,Methods,Example" >}}
{{< tab >}}
| Field | Type | Description |
|-------|------|-------------|
| actionType | `InteractionType` | Type of interaction |
| clientUseTime | `long` | Client timestamp |
| itemInHand | `ItemStack` | Item being used |
| targetBlock | `Vector3i` | Block being targeted |
| targetEntity | `Entity` | Entity being targeted |
{{< /tab >}}
{{< tab >}}
- `getPlayer()` - Returns the Player object
- `getActionType()` - Returns interaction type
- `getClientUseTime()` - Returns client timestamp
- `getItemInHand()` - Returns item in hand
- `getTargetBlock()` - Returns targeted block
- `getTargetEntity()` - Returns targeted entity
- `getTargetRef()` - Returns target entity reference
- `isCancelled()` - Check if cancelled
- `setCancelled(boolean)` - Cancel interaction
{{< /tab >}}
{{< tab >}}
```java
// Deprecated - prefer UseBlockEvent or PlayerMouseButtonEvent
getEventRegistry().register(PlayerInteractEvent.class, event -> {
    Player player = event.getPlayer();
    InteractionType action = event.getActionType();

    // Handle interaction
});
```
{{< /tab >}}
{{< /tabs >}}

---

## Practical Examples

### Complete Welcome System

```java
public class WelcomePlugin extends JavaPlugin {

    private final Set<UUID> firstJoinPlayers = new HashSet<>();

    @Override
    public void start() {
        // Track setup phase
        getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
            if (isFirstJoin(event.getUuid())) {
                firstJoinPlayers.add(event.getUuid());
            }
        });

        // Welcome when fully ready
        getEventRegistry().register(PlayerReadyEvent.class, event -> {
            Player player = event.getPlayer();

            if (firstJoinPlayers.remove(player.getUuid())) {
                // First time player
                player.sendMessage(Message.raw("Welcome to the server for the first time!"));
                giveStarterKit(player);
            } else {
                // Returning player
                player.sendMessage(Message.raw("Welcome back, " + player.getDisplayName() + "!"));
            }
        });

        // Save on disconnect
        getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
            savePlayerData(event.getPlayerRef().getUuid());
        });
    }
}
```

### Server Referral System

```java
public class ReferralPlugin extends JavaPlugin {

    @Override
    public void start() {
        getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
            // Check if player came from referral
            if (event.isReferralConnection()) {
                byte[] data = event.getReferralData();
                HostAddress source = event.getReferralSource();
                getLogger().at(Level.INFO).log("Player referred from " + source.host);
            }

            // Redirect based on load balancing
            String targetServer = getOptimalServer();
            if (!isThisServer(targetServer)) {
                event.referToServer(targetServer, 25565, createReferralData());
            }
        });
    }
}
```

### Chat Filter System

```java
public class ChatFilterPlugin extends JavaPlugin {

    private final Set<String> bannedWords = new HashSet<>();
    private final Map<UUID, Integer> warnings = new HashMap<>();

    @Override
    public void start() {
        loadBannedWords();

        getEventRegistry().register(PlayerChatEvent.class, event -> {
            PlayerRef sender = event.getSender();
            String message = event.getContent().toLowerCase();

            for (String banned : bannedWords) {
                if (message.contains(banned)) {
                    event.setCancelled(true);

                    Player player = sender.getPlayer();
                    if (player != null) {
                        int count = warnings.merge(sender.getUuid(), 1, Integer::sum);
                        player.sendMessage(Message.raw("Warning " + count + "/3: Watch your language!"));

                        if (count >= 3) {
                            player.kick("Too many chat violations");
                        }
                    }
                    return;
                }
            }
        });
    }
}
```
