Working with players

Find online players, message them, move them, and read or change their state.

A Player is the API handle for someone connected to the server. From it you send messages and titles, play sounds, teleport, change game mode, and read stats like health and experience. Player extends Mob -> Actor -> OfflinePlayer, so everything an entity can do - location, health, teleport - a player can do too. This page covers the player-specific surface; for locations and the level the player lives in, see worlds and blocks.

Get a player

The server hands you the players that are online right now, and looks one up by name or by UUID:

src/endstone_my_plugin/my_plugin.py
players = self.server.online_players          # list[Player], everyone connected now

by_name = self.server.get_player("Steve")     # case-insensitive exact name
by_uuid = self.server.get_player(some_uuid)   # uuid.UUID

get_player returns None when nobody matches - the player may have logged off, or the name may be misspelled. Always check before using the result:

player = self.server.get_player(name)
if player is None:
    sender.send_error_message(f"{name} is not online.")
    return True

Most of the time you don't look players up at all - you receive them. A command handler is passed the sender (often a Player), and events carry the player on event.player.

Message and notify

send_message and send_error_message are inherited from every command sender; the rest are player-only surfaces, each landing in a different spot on screen:

player.send_message("Goes to the chat log.")
player.send_error_message("Red error text in chat.")
player.send_popup("Popup above the hotbar.")
player.send_tip("Tip text, also above the hotbar.")
player.send_toast("Achievement!", "A toast in the top-right corner.")

A title is the large text that fills the centre of the screen, with an optional subtitle under it. The timings are in ticks (20 per second) and have sensible defaults:

player.send_title("Welcome", "to the server", fade_in=10, stay=70, fade_out=20)
player.reset_title()  # clear it and restore default timings

Messages accept colour and format codes, so you can colour any of the strings above.

Play sounds

Sounds play at a location - usually the player's own - with a volume and pitch:

player.play_sound(player.location, "random.levelup", volume=1.0, pitch=1.0)
player.stop_sound("random.levelup")
player.stop_all_sounds()

Move and connect

teleport is inherited from Actor and takes a Location or another actor to teleport to. Build a Location from a dimension plus coordinates:

from endstone.level import Location

spawn = Location(player.dimension, 0.0, 64.0, 0.0)
player.teleport(spawn)         # to a location
player.teleport(other_player)  # straight to another actor

The connection-level controls are player-only:

player.transfer("play.example.com", 19132)  # hand the player to another server
player.kick("Banned for griefing.")          # disconnect with a reason
player.perform_command("time set day")       # run a command as this player

Game mode

A player's game mode is the game_mode property, set with the GameMode enum:

from endstone import GameMode

if player.game_mode == GameMode.SURVIVAL:
    player.game_mode = GameMode.CREATIVE

GameMode has SURVIVAL, CREATIVE, ADVENTURE, and SPECTATOR.

Flight, sneaking, sprinting

Flight is two separate ideas: whether the player is allowed to fly, and whether they currently are. fly_speed and walk_speed tune the movement speeds.

player.allow_flight = True     # enables the double-tap-jump to fly
player.is_flying = True        # put them in the air right now
player.fly_speed = 0.1         # default is 0.05
player.walk_speed = 0.2        # default is 0.1

if player.is_sneaking:
    ...
player.is_sprinting = True

Health and experience

health and max_health are inherited from Mob, measured in half-hearts (a full heart is 2):

player.health = player.max_health  # full heal
player.max_health = 40             # 20 hearts

Experience splits into a level and the fractional exp_progress toward the next level:

player.give_exp(100)           # raw experience points
player.give_exp_levels(5)      # whole levels
player.exp_level = 30          # set the level outright
player.exp_progress = 0.5      # half-way to the next level (0.0 - 1.0)
total = player.total_exp       # read-only running total

A combined example

A /spawn command that teleports the player home, plays a sound, and drops a title - the everyday shape of player work:

src/endstone_my_plugin/my_plugin.py
from endstone import GameMode
from endstone.command import Command, CommandSender
from endstone.level import Location
from endstone.plugin import Plugin

class MyPlugin(Plugin):
    api_version = "0.11"

    commands = {
        "spawn": {
            "description": "Teleport to spawn.",
            "usages": ["/spawn"],
            "permissions": ["my_plugin.command.spawn"],
        }
    }

    def on_command(self, sender: CommandSender, command: Command, args: list[str]) -> bool:
        if command.name == "spawn":
            if not isinstance(sender, Player):
                sender.send_error_message("Only players can use this command.")
                return True

            spawn = Location(sender.dimension, 0.0, 64.0, 0.0)
            sender.teleport(spawn)
            sender.play_sound(spawn, "mob.endermen.portal")
            sender.send_title("Spawn", "Welcome back!")
        return True

Because Player is also an Actor, the same handler could just as well read sender.health, check sender.game_mode, or set sender.allow_flight - the entity API and the player API are one object. See worlds and blocks for Location and the level the player moves through, and forms for richer in-game UI.

On this page