Files
Documentation/content/world/entities/player-api.fr.md
2026-01-20 20:33:59 +01:00

24 KiB

title, type, weight
title type weight
Player API docs 4

The Player class provides extensive APIs for player management, including communication, health, inventory, permissions, and more.

API Overview

{{< cards cols="3" >}} {{< card link="#identity--connection" title="Identity & Connection" subtitle="Name, UUID, network" >}} {{< card link="#communication" title="Communication" subtitle="Messages, titles, sounds" >}} {{< card link="#health--combat" title="Health & Combat" subtitle="HP, damage, effects" >}} {{< card link="#inventory-api" title="Inventory" subtitle="Items, slots, armor" >}} {{< card link="#permissions" title="Permissions" subtitle="Access control" >}} {{< card link="#movement--teleportation" title="Movement" subtitle="Teleport, position" >}} {{< /cards >}}


Identity & Connection

Basic Information

{{< tabs items="Methods,Example" >}} {{< tab >}}

Method Return Type Description
getUuid() UUID Unique player identifier
getDisplayName() String Display name (from PlayerRef username)
getClientViewRadius() int Player's view radius in chunks
getViewRadius() int Effective view radius (min of client and server)
hasPermission(String) boolean Check permission
sendMessage(Message) void Send message to player
getInventory() Inventory Player's inventory
getGameMode() GameMode Current game mode

{{< /tab >}} {{< tab >}}

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Access Player component via ref.getStore()
Player player = ref.getStore().getComponent(ref, Player.getComponentType());

UUID uuid = player.getUuid();
String displayName = player.getDisplayName();
int viewRadius = player.getViewRadius();
GameMode mode = player.getGameMode();

// Check permission
if (player.hasPermission("myplugin.admin")) {
    player.sendMessage(Message.raw("You are an admin!"));
}

// Get PlayerRef for more info
PlayerRef playerRef = ref.getStore().getComponent(ref, PlayerRef.getComponentType());
String username = playerRef.getUsername();
String language = playerRef.getLanguage();

{{< /tab >}} {{< /tabs >}}

PlayerRef (Thread-Safe Reference)

{{< callout type="info" >}} Important: PlayerRef is a component that provides thread-safe access to player data. It's stored in the entity component system and manages the player's connection, position, and various managers. {{< /callout >}}

{{< tabs items="Methods,Entity Reference,Connection & Messaging,Server Transfer" >}} {{< tab >}}

Method Return Type Description
getUuid() UUID Player's unique identifier
getUsername() String Player's username
getLanguage() String Player's language setting
setLanguage(String) void Update language
getReference() Ref<EntityStore> Entity reference (null if not in world)
getHolder() Holder<EntityStore> Entity holder (when not in store)
isValid() boolean Whether reference or holder exists
getTransform() Transform Current position and rotation
getHeadRotation() Vector3f Head rotation
getPacketHandler() PacketHandler Network handler
getChunkTracker() ChunkTracker Chunk loading tracker
getHiddenPlayersManager() HiddenPlayersManager Player visibility manager

{{< /tab >}} {{< tab >}}

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Get PlayerRef via ref.getStore()
PlayerRef playerRef = ref.getStore().getComponent(ref, PlayerRef.getComponentType());

// Check if player is valid
if (playerRef != null && playerRef.isValid()) {
    UUID uuid = playerRef.getUuid();
    String username = playerRef.getUsername();

    // Get entity reference
    Ref<EntityStore> entityRef = playerRef.getReference();
    if (entityRef != null) {
        // Player is in a world - access via entityRef.getStore()
        Player player = entityRef.getStore().getComponent(entityRef, Player.getComponentType());
    }
}

// Get component from PlayerRef (convenience method)
Player playerComponent = playerRef.getComponent(Player.getComponentType());

{{< /tab >}} {{< tab >}}

// Send message to player
playerRef.sendMessage(Message.translation("welcome.message"));

// Get packet handler for more advanced operations
PacketHandler handler = playerRef.getPacketHandler();

// Get player position info
Transform transform = playerRef.getTransform();
Vector3d position = transform.getPosition();
Vector3f rotation = transform.getRotation();
Vector3f headRotation = playerRef.getHeadRotation();

// Update position (called internally by systems)
playerRef.updatePosition(world, transform, headRotation);

{{< /tab >}} {{< tab >}}

// Transfer player to another server (for server networks)
playerRef.referToServer("play.example.com", 25565);

// With custom data payload
byte[] referralData = serializePlayerData(playerRef);
playerRef.referToServer("play.example.com", 25565, referralData);

// Note: Max referral data size is 4096 bytes

{{< /tab >}} {{< /tabs >}}


Communication

Sending Messages

{{< tabs items="Chat Messages,Translation Messages,Notifications" >}} {{< tab >}}

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Send chat message via PlayerRef
PlayerRef playerRef = ref.getStore().getComponent(ref, PlayerRef.getComponentType());

// Simple message
playerRef.sendMessage(Message.raw("Hello, World!"));

// Raw message
playerRef.sendMessage(Message.raw("Plain text message"));

// Using Message interface (IMessageReceiver)
Player player = ref.getStore().getComponent(ref, Player.getComponentType());
player.sendMessage(Message.raw("Message via Player interface"));

{{< /tab >}} {{< tab >}}

// Using translation keys
playerRef.sendMessage(Message.translation("welcome.message"));

// With parameters
playerRef.sendMessage(
    Message.translation("greeting.message")
        .param("name", playerRef.getUsername())
);

// With color
playerRef.sendMessage(
    Message.translation("server.warning")
        .color("#ff5555")
);

{{< /tab >}} {{< tab >}}

// Hytale uses Notifications instead of titles/action bars
PacketHandler handler = playerRef.getPacketHandler();

// Simple notification
NotificationUtil.sendNotification(handler, "Welcome to the server!");

// Notification with style
NotificationUtil.sendNotification(handler,
    Message.raw("Achievement Unlocked!"),
    NotificationStyle.Default
);

// With secondary message
NotificationUtil.sendNotification(handler,
    Message.raw("Quest Complete"),
    Message.raw("You earned 100 XP"),
    NotificationStyle.Default
);

// With icon
NotificationUtil.sendNotification(handler,
    Message.raw("New Item"),
    "icon_name",
    NotificationStyle.Default
);

// With item display
NotificationUtil.sendNotification(handler,
    Message.raw("You received:"),
    Message.raw("Diamond x10"),
    itemWithMetadata,
    NotificationStyle.Default
);

// Send to all players in universe
NotificationUtil.sendNotificationToUniverse(
    Message.raw("Server restarting in 5 minutes!")
);

{{< /tab >}} {{< /tabs >}}

Playing Sounds

// Play 3D sound to player
SoundUtil.playSoundEvent3dToPlayer(
    playerRef,
    TempAssetIdUtil.getSoundEventIndex("SFX_UI_Notification"),
    SoundCategory.UI,
    position,
    componentAccessor
);

// Play 2D sound (no position)
SoundUtil.playSoundEvent2d(
    ref,
    TempAssetIdUtil.getSoundEventIndex("SFX_Player_Pickup_Item"),
    SoundCategory.UI,
    componentAccessor
);

// Play sound via world
world.playSound(soundEvent, position, volume, pitch);

Health & Stats

{{< callout type="info" >}} Hytale uses an EntityStats system for managing health and other stats. Stats are managed via EntityStatComponent and include Health, Oxygen, Stamina, Mana, SignatureEnergy, and Ammo. {{< /callout >}}

Entity Stats System

{{< tabs items="Available Stats,Accessing Stats,Modifying Stats" >}} {{< tab >}}

Stat Description
Health Entity health points
Oxygen Breath/oxygen level
Stamina Physical stamina
Mana Magical energy
SignatureEnergy Special ability energy
Ammo Ammunition count

These stats are defined via asset configuration and indexed at runtime.

// Get stat indices (from DefaultEntityStatTypes)
int healthIndex = DefaultEntityStatTypes.getHealth();
int staminaIndex = DefaultEntityStatTypes.getStamina();
int manaIndex = DefaultEntityStatTypes.getMana();

{{< /tab >}} {{< tab >}}

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Get EntityStatComponent from entity via ref.getStore()
EntityStatComponent statsComponent = ref.getStore().getComponent(
    ref,
    EntityStatComponent.getComponentType()
);

// Get specific stat value
int healthIndex = DefaultEntityStatTypes.getHealth();
float currentHealth = statsComponent.getValue(healthIndex);
float maxHealth = statsComponent.getMaxValue(healthIndex);

// Check percentage
float healthPercent = currentHealth / maxHealth;

{{< /tab >}} {{< tab >}}

// Modify stat values through the stats system
// Stats are typically modified through the EntityStatsModule
// and related systems (DamageSystems, HealSystems, etc.)

// Example: Apply damage via component
// The DamageSystems handle damage application
ref.getStore().putComponent(ref, Damage.getComponentType(),
    new Damage(damageAmount, damageSource));

{{< /tab >}} {{< /tabs >}}

Invulnerability

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Make player invulnerable (adds Invulnerable component)
ref.getStore().putComponent(ref, Invulnerable.getComponentType(), Invulnerable.INSTANCE);

// Remove invulnerability
ref.getStore().tryRemoveComponent(ref, Invulnerable.getComponentType());

// Check invulnerability
boolean isInvulnerable = ref.getStore().getArchetype(ref)
    .contains(Invulnerable.getComponentType());

// Note: Creative mode automatically sets Invulnerable

Spawn Protection

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Players have temporary invulnerability after spawning
Player player = ref.getStore().getComponent(ref, Player.getComponentType());

// Check if player has spawn protection (3 seconds after spawn)
if (player.hasSpawnProtection()) {
    // Player is temporarily invulnerable
}

// Check if waiting for client ready
if (player.isWaitingForClientReady()) {
    // Player hasn't finished loading yet
}

Inventory API

Basic Inventory Operations

{{< tabs items="Get Items,Set Items,Utility Methods" >}} {{< tab >}}

// Get inventory
PlayerInventory inventory = player.getInventory();

// Get item in hand
ItemStack heldItem = player.getHeldItem();
ItemStack mainHand = player.getMainHandItem();
ItemStack offHand = player.getOffHandItem();

// Get specific slot
ItemStack slot5 = inventory.getItem(5);

// Get armor
ArmorInventory armor = player.getArmor();
ItemStack helmet = armor.getHelmet();
ItemStack chestplate = armor.getChestplate();
ItemStack leggings = armor.getLeggings();
ItemStack boots = armor.getBoots();

{{< /tab >}} {{< tab >}}

// Set held item
ItemStack sword = new ItemStack(ItemTypes.DIAMOND_SWORD);
player.setHeldItem(sword);

// Set specific slot
inventory.setItem(0, new ItemStack(ItemTypes.APPLE, 64));

// Set armor
armor.setHelmet(new ItemStack(ItemTypes.DIAMOND_HELMET));
armor.setChestplate(new ItemStack(ItemTypes.DIAMOND_CHESTPLATE));
armor.setLeggings(new ItemStack(ItemTypes.DIAMOND_LEGGINGS));
armor.setBoots(new ItemStack(ItemTypes.DIAMOND_BOOTS));

// Clear slot
inventory.setItem(5, null);

{{< /tab >}} {{< tab >}}

// Give item (finds empty slot)
ItemStack diamond = new ItemStack(ItemTypes.DIAMOND, 64);
boolean success = player.giveItem(diamond);

if (!success) {
    // Inventory full, drop at feet
    player.dropItem(diamond);
}

// Check for item
if (inventory.contains(ItemTypes.DIAMOND)) {
    getLogger().at(Level.INFO).log("Player has diamonds");
}

// Remove item
inventory.remove(ItemTypes.DIAMOND, 10);

// Clear inventory
inventory.clear();

// Count items
int diamondCount = inventory.countItem(ItemTypes.DIAMOND);

{{< /tab >}} {{< /tabs >}}

Advanced Inventory

// Open another inventory (chest, custom UI)
Inventory chest = world.getBlockEntity(chestPos).getInventory();
player.openInventory(chest);

// Create custom inventory
Inventory customInv = new Inventory(27, "Shop");  // 27 slots
customInv.setItem(13, new ItemStack(ItemTypes.DIAMOND, 1));
player.openInventory(customInv);

// Close open inventory
player.closeInventory();

// Get cursor item (what player is holding with mouse)
ItemStack cursor = player.getCursorItem();
player.setCursorItem(null);

Permissions

Permission Checking

{{< tabs items="Basic Checks,Permission Levels,Custom Permissions" >}} {{< tab >}}

// Check single permission
if (player.hasPermission("myplugin.admin")) {
    player.sendMessage("You are an admin!");
}

// Check operator status
if (player.isOp()) {
    player.sendMessage("You are an operator!");
}

// Multiple permission check
if (player.hasPermission("myplugin.fly") ||
    player.hasPermission("myplugin.admin")) {
    enableFlight(player);
}

{{< /tab >}} {{< tab >}}

// Permission hierarchy example
public boolean hasMinimumRank(Player player, String rank) {
    switch (rank) {
        case "owner":
            return player.hasPermission("rank.owner");
        case "admin":
            return player.hasPermission("rank.admin") ||
                   player.hasPermission("rank.owner");
        case "mod":
            return player.hasPermission("rank.mod") ||
                   player.hasPermission("rank.admin") ||
                   player.hasPermission("rank.owner");
        default:
            return true;
    }
}

{{< /tab >}} {{< tab >}}

// Grant permission
player.addPermission("myplugin.vip");

// Revoke permission
player.removePermission("myplugin.vip");

// Get all permissions
Set<String> permissions = player.getPermissions();
for (String perm : permissions) {
    getLogger().at(Level.INFO).log("Has permission: " + perm);
}

// Set operator status
player.setOp(true);

{{< /tab >}} {{< /tabs >}}


Movement & Teleportation

Position & Movement

{{< tabs items="Position Methods,Movement State,Velocity" >}} {{< tab >}}

Method Return Type Description
getPosition() Vector3d Current position
setPosition(Vector3d) void Set position
getEyePosition() Vector3d Eye level position
getRotation() Vector3f Look direction
setRotation(Vector3f) void Set look direction
getEyeDirection() Vector3d Normalized look vector
{{< /tab >}}
{{< tab >}}
Method Return Type Description
-------- ------------- -------------
isOnGround() boolean Whether on solid ground
isSprinting() boolean Whether sprinting
setSprinting(boolean) void Set sprint state
isSneaking() boolean Whether sneaking
setSneaking(boolean) void Set sneak state
isFlying() boolean Whether flying
setFlying(boolean) void Set flying state
isSwimming() boolean Whether swimming
{{< /tab >}}
{{< tab >}}
// Get velocity
Vector3d velocity = player.getVelocity();

// Set velocity (launch player)
player.setVelocity(new Vector3d(0, 1.5, 0));

// Add to velocity
player.addVelocity(new Vector3d(1, 0, 0));

// Apply knockback
player.knockback(new Vector3d(-0.5, 0.5, -0.5));

{{< /tab >}} {{< /tabs >}}

Teleportation

{{< callout type="warning" >}} Hytale uses a component-based teleportation system. You don't call player.teleport() directly. Instead, you add a Teleport component to the entity, and the system handles the teleportation. {{< /callout >}}

{{< tabs items="Basic Usage,Cross-World,Options,System Details" >}} {{< tab >}}

// Get player reference from command context
Ref<EntityStore> playerRef = context.senderAsPlayerRef();

// Teleport to position in same world
Teleport teleport = new Teleport(
    new Vector3d(100, 64, 100),     // position
    new Vector3f(0, 90, 0)          // rotation (pitch, yaw, roll)
);

// Add the teleport component to trigger teleportation
playerRef.getStore().putComponent(playerRef, Teleport.getComponentType(), teleport);

// Using Transform
Transform destination = new Transform(position, rotation);
Teleport teleportFromTransform = new Teleport(destination);

{{< /tab >}} {{< tab >}}

// Get player reference from command context
Ref<EntityStore> playerRef = context.senderAsPlayerRef();

// Teleport to another world
World targetWorld = Universe.get().getWorld("other_world");

Teleport teleport = new Teleport(
    targetWorld,                     // target world
    new Vector3d(0, 64, 0),          // position
    new Vector3f(0, 0, 0)            // rotation
);

playerRef.getStore().putComponent(playerRef, Teleport.getComponentType(), teleport);

// The TeleportSystems.PlayerMoveSystem handles:
// - Same world: Direct position update
// - Different world: Player removal and re-addition to target world

{{< /tab >}} {{< tab >}}

// Teleport with options using fluent builder
Teleport teleport = new Teleport(targetWorld, position, rotation)
    .withHeadRotation(new Vector3f(0, 45, 0))  // Set head rotation
    .withResetRoll()                            // Reset roll to 0
    .withoutVelocityReset();                    // Keep current velocity

// By default:
// - resetVelocity = true (player stops moving)
// - headRotation = same as body rotation

{{< /tab >}} {{< tab >}}

The teleportation flow:

  1. Add Teleport component to entity
  2. TeleportSystems.PlayerMoveSystem detects the component
  3. System sends ClientTeleport packet to player
  4. PendingTeleport component tracks the teleport
  5. When client confirms, position is updated
  6. Teleport component is removed automatically
// Internal packet sent:
ClientTeleport packet = new ClientTeleport(
    teleportId,
    new ModelTransform(position, direction, headRotation),
    resetVelocity
);

{{< /tab >}} {{< /tabs >}}


Game Mode

{{< callout type="info" >}} Hytale currently has two game modes: Adventure and Creative. These differ from Minecraft's game modes. {{< /callout >}}

{{< tabs items="Available Modes,Getting/Setting,Creative Features" >}} {{< tab >}}

Mode Value Description
GameMode.Adventure 0 Standard gameplay with survival mechanics
GameMode.Creative 1 Creative mode with building freedom

{{< /tab >}} {{< tab >}}

// Get current game mode
GameMode mode = player.getGameMode();

// Check game mode
if (mode == GameMode.Creative) {
    // Creative mode logic
} else if (mode == GameMode.Adventure) {
    // Adventure mode logic
}

// Set game mode (requires component accessor)
// Note: This is typically done through systems/commands
Player.setGameMode(playerRef, GameMode.Creative, componentAccessor);

{{< /tab >}} {{< tab >}}

When in Creative mode:

  • Player is marked as Invulnerable
  • canFly is enabled in MovementManager
  • canDecreaseItemStackDurability returns false
  • canApplyItemStackPenalties returns false
  • Permission groups from GameModeType are applied
// GameMode affects these behaviors automatically:
// - Flight enabled/disabled
// - Invulnerability
// - Item durability loss
// - Block placement restrictions

{{< /tab >}} {{< /tabs >}}


Server Actions

Disconnecting Players

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Disconnect player via PacketHandler
PlayerRef playerRef = ref.getStore().getComponent(ref, PlayerRef.getComponentType());

// Disconnect with reason
playerRef.getPacketHandler().disconnect("You have been kicked!");

// Disconnect with translation message
playerRef.getPacketHandler().disconnect(
    Message.translation("server.kick.reason").toString()
);

Player Lookup

// Get all online players through Universe
Universe universe = Universe.get();

// Players are accessed through world contexts
World world = universe.getWorld("main");

// Iterate players in world via entity store
// Players are entities with PlayerRef component
world.getEntityStore().forEach((ref, store) -> {
    PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType());
    if (playerRef != null) {
        String username = playerRef.getUsername();
        UUID uuid = playerRef.getUuid();
        // Process player...
    }
});

Server Transfer

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Transfer player to another server (for server networks)
PlayerRef playerRef = ref.getStore().getComponent(ref, PlayerRef.getComponentType());

// Redirect player to another server
playerRef.referToServer("play.example.com", 25565);

// With custom data (max 4096 bytes)
byte[] playerData = serializePlayerState(playerRef);
playerRef.referToServer("play.example.com", 25565, playerData);

Practical Examples

Welcome Plugin

public class WelcomePlugin extends ServerPlugin {

    @Override
    public void setup(PluginSetup pluginSetup) {
        // Register event listeners
    }

    @Override
    public void start() {
        // Subscribe to player connect event
        HytaleServer.get().getEventBus()
            .subscribe(PlayerConnectEvent.class, this::onPlayerConnect);
    }

    private void onPlayerConnect(PlayerConnectEvent event) {
        String username = event.getUsername();
        UUID uuid = event.getUuid();

        getLogger().at(Level.INFO).log("Player connected: " + username + " (" + uuid + ")");

        // Send welcome message after player is ready
        // Note: PlayerReadyEvent has String key, so use registerGlobal
        getEventRegistry().registerGlobal(PlayerReadyEvent.class, readyEvent -> {
            Player player = readyEvent.getPlayer();
            player.sendMessage(Message.raw("Welcome to the server, " + username + "!"));
        });
    }

    @Override
    public void shutdown() {
        // Cleanup
    }
}

Permission Check Example

public class PermissionPlugin extends ServerPlugin {

    @Override
    public void start() {
        CommandRegistry registry = getCommandRegistry();

        registry.register("admin", context -> {
            CommandSender sender = context.getSource();

            // Check permission
            if (sender instanceof Player player) {
                if (!player.hasPermission("myplugin.admin")) {
                    player.sendMessage(Message.raw("No permission!"));
                    return;
                }

                player.sendMessage(Message.raw("You are an admin!"));
            }
        });
    }
}

Inventory Management

// Get entity reference from command context
Ref<EntityStore> ref = context.senderAsPlayerRef();

// Working with player inventory
Player player = ref.getStore().getComponent(ref, Player.getComponentType());
Inventory inventory = player.getInventory();

// Add item to inventory
ItemStack itemStack = new ItemStack(itemType, amount);
inventory.addItem(itemStack);

// Send inventory update to client
player.sendInventory();

// Access hotbar
HotbarManager hotbar = player.getHotbarManager();

Best Practices

{{< callout type="info" >}} Player API Guidelines:

  • Use PlayerRef to get thread-safe player information
  • Check isValid() before operations on stored references
  • Use permissions via player.hasPermission() for access control
  • Understand the component system: players are entities with components {{< /callout >}}

{{< callout type="warning" >}} Component System: Players in Hytale are entities managed by an ECS. Access player data via ref.getStore() and appropriate component types (Player.getComponentType(), PlayerRef.getComponentType()). {{< /callout >}}

{{< callout type="error" >}} Critical: Never store Ref<EntityStore> or Player references directly in static fields. Use UUID for storage and retrieve references via the component system when needed. {{< /callout >}}