Players from Lua
The properties and operations of a player object, from movement and the tab list to sounds, signs and resource packs.
A player object is what players.by_name, players.online() and the player field of an event give you. Properties
are read as p.name and written as p.name = value; operations are methods, p:name(...). The same surface is also
reachable by name with p:get(name), p:set(name, value) (returns whether it was accepted) and p:call(name, ...).
Times are ticks, distances are blocks and texts are MiniMessage. Speeds use the scale a plugin author expects:
fly_speed 0.1 and walk_speed 0.2 are the defaults, within -1 to 1.
local p = players.by_name("Steve")
p.allow_flight = true
p.fly_speed = 0.05
p:tab_list("<gold>Welcome", "<gray>basaltmc.org")
p:sound_at("minecraft:entity.player.levelup", "player", p.x, p.y, p.z, 1, 1, 0)Finding players#
| Call | Returns |
|---|---|
players.online() |
A list of every player online |
players.by_name(name) |
The online player with that name, or nil |
players.by_uuid(uuid) |
The online player with that uuid string, or nil |
players.count() |
How many are online |
For people who are not online, access.known(name) and the other access calls are in
Groups and permissions.
The basics#
| Member | Access | Meaning |
|---|---|---|
p.name, p.uuid |
read | Name and uuid string |
p.online |
read | Whether the player is connected. A player object kept after they left reports false |
p.health, p.food, p.level |
read, write | Health (a number), food (whole number) and experience level |
p.gamemode |
read, write | survival, creative, adventure or spectator |
p.world |
read | The name of the world they are in |
p.x, p.y, p.z |
read | Position |
p.pos |
read | The position as a table { world, x, y, z, chunk_x, chunk_z } with offset(dx, dy, dz) and distance(other) |
p.ping |
read | Latency in milliseconds |
p.sneaking |
read | Whether they are sneaking |
p.held_item |
read | The id of the item in the main hand, or nil |
p.attributes |
read | The names of the attributes that exist |
p.inventory |
read | The inventory object, below |
p.data |
read | Values saved for this player by this plugin, see Storage |
| Call | Does |
|---|---|
p:send(text, [args]) |
A chat message. Text rules, @key and {name} arguments are in Config and lang files |
p:action_bar(text, [args]) |
The text above the hotbar |
p:title(text, [subtitle], [times]) |
A title. times is { fade_in, stay, fade_out } in ticks, 10, 70 and 20 by default |
p:kick([text]) |
Disconnects the player with that message |
p:teleport(pos), p:teleport(world, x, y, z), p:teleport(x, y, z) |
Moves the player, in the same world for the last form. Returns whether it did |
p:give(id, [count]) |
Puts items in the inventory and returns whether it worked |
p:effect(id, [seconds], [level]) |
Gives a potion effect: level counts from 1, no seconds makes it last until removed, 0 seconds removes it. Returns whether the effect exists |
p:attribute(name), p:attribute(name, value) |
Reads an attribute (a number or nil) or sets it, returning whether it did |
p:sound(id, [volume], [pitch]) |
Plays a sound to this player at their position |
p:particle(id, [pos], [count], [speed]) |
Shows particles to this player, at their position when no pos is given |
p:may(node) |
Whether they hold a permission |
p:grant(node), p:deny(node), p:revoke(node) |
Grants or denies a permission for the session on top of their group; revoke drops this plugin's entry. See Groups and permissions |
The inventory object has 41 slots: 0 to 26 are the storage rows, 27 to 35 the hotbar (the selected one is
27 + inventory.held_slot), 36 to 39 armour and 40 the off hand.
| Member | Does |
|---|---|
inv.size, inv.held_slot |
The number of slots and the selected hotbar position, 0 to 8 |
inv.held |
The item in the selected slot, or nil |
inv:get(slot) |
The item in a slot, or nil. An item is { id, count, name, lore, damage, enchantments, components } |
inv:set(slot, item) |
Puts an item (a table, or an id string) in a slot; nil empties it |
inv:add(item, [count]) |
Adds an item where it fits; returns how many could not be placed |
inv:remove(id, [count]) |
Takes up to count (1) of an item; returns how many were taken |
inv:count(id) |
How many of that item the player has |
inv:clear() |
Empties the whole inventory |
Movement and state#
| Property | Type | Meaning |
|---|---|---|
allow_flight |
bool | May fly; resets to the game mode's rule when the game mode changes |
flying |
bool | Is flying (true only when allow_flight) |
fly_speed, walk_speed |
number | Movement speed; walk_speed also writes the movement_speed attribute |
sprinting, sneaking, swimming, gliding |
bool | Server-side state flags |
exhaustion, saturation |
number | Hunger state |
exp |
number | Progress to the next level, 0 to 1 |
total_experience |
int | Setting it resets the player to level 0 and gives that many points |
exp_to_next_level |
int | Read only. Points the current level needs |
health_scale |
number or nil | Scales the health bar the client draws to this many points; nil is off |
sleeping_ignored, collidable, affects_spawning, flying_fall_damage |
bool | Flags held for plugins |
exp_cooldown |
int | A counter held for plugins |
attack_cooldown |
number | Read only. Attack strength, 0 to 1 |
spectator_target |
int | Entity id the spectator camera follows, -1 for none |
enchantment_seed, score |
int | The enchantment seed and the death screen score |
previous_gamemode |
string or nil | Read only. The game mode before the last change |
sleep_ticks |
int | Read only. Ticks asleep |
fishing_hook |
int | Read only. Entity id of the bobber, -1 for none |
seen_win_screen |
bool | Not saved |
view_distance, simulation_distance |
int or nil | Per-player distances in chunks; nil restores the server's |
slot_limit |
int | The most one inventory slot holds, 1 to 99 (default 99); it caps pickups, merges, quick move and cursor stacking, and an item's own limit still applies |
frozen_ticks, freeze_locked |
int, bool | Powder snow freezes players: +1 a tick inside, -2 outside, 140 is fully frozen (1 damage every 40 ticks); leather armour and spectators are immune, and freeze_locked stops the count either way |
Players take cactus, fire and magma floor damage as in vanilla. A game mode change reports its cause to player.gamemode_change.
Tab list, time and weather#
| Property | Type | Meaning |
|---|---|---|
tab_header, tab_footer |
string or nil | This player's own header and footer; while either is set the configured tab list stays off for them |
list_name |
string or nil | The name everybody sees in the tab list; nil is the plain name |
listed |
bool | Everybody sees them in the tab list |
list_order |
int | Tab list sort order |
player_time, player_time_relative, player_weather |
read only | The player's own clock and weather override, nil when none |
compass_target |
list or nil | Read only. { x, y, z } set by set_compass_target |
Client facts#
All read only: locale, client_brand, virtual_host (strings), client_view_distance, client_particles,
main_hand (0 left, 1 right), skin_parts, chat_visibility, protocol_version, pack_status (the last resource
pack answer, -1 for none), and the booleans chat_colors, text_filtering and server_listings.
More state is readable and writable as plain properties: pose (read only, the protocol pose id), use_ticks (read
only, -1 for none), use_remaining (-1 for none), visual_fire (-1 follows the fire, 0 never, 1 always), fixed_pose
(-1 for none), no_physics (spectators always), freeze_locked (only round-trips for now), waypoint_style,
waypoint_color (RGB, -1 for none), body_yaw, hurt_direction, no_action_ticks, maximum_air,
max_no_damage_ticks (the hurt cooldown), shield_delay, saturated_regen_ticks, unsaturated_regen_ticks,
starvation_ticks and killer (uuid of the player credited with the last hit).
Operations#
| Call | Returns | Does |
|---|---|---|
p:give_exp(points), p:give_levels(n) |
true | Adds points or levels |
p:send_health(), p:send_experience() |
true | Resends the real values to the client |
p:fake_health(health, food, saturation), p:fake_experience(progress, level) |
bool | Shows the client other values without changing the player |
p:reset_attack_cooldown() |
true | Restarts the attack ticker |
p:title_part(kind, text) |
bool | kind is title, subtitle or actionbar |
p:title_times(fade_in, stay, fade_out), p:clear_title(reset?) |
bool | Title timing and clearing |
p:tab_list(header, footer) |
true | Sets both at once; nil clears |
p:update_commands() |
true | Resends the command tree |
p:set_player_time(time, relative?), p:reset_player_time() |
true | This player's own clock; an absolute time freezes it |
p:set_player_weather(kind?) |
true | downfall, clear, or nil to reset |
p:hide_entity(id), p:show_entity(id) |
bool | Hides or shows an entity or player for this viewer |
p:can_see(id) |
bool | Whether it is visible to this viewer |
p:visible_by_default(id, visible?) |
bool | Reads or sets whether an entity is visible to viewers that did not ask |
p:list_player(entity_id, listed), p:list_unlisted(entity_id) |
bool | This viewer's tab list entry for another player |
p:set_compass_target(x, y, z) |
bool | Where a compass points |
p:cooldown(item), p:set_cooldown(item, ticks) |
int, true | Ticks left; starts or clears an item cooldown |
p:statistic(key), p:set_statistic(key, n), p:inc_statistic(key, n?) |
int, true | Counters by stored key, such as minecraft:custom/minecraft:jump or minecraft:mined/minecraft:stone |
p:transfer(host, port) |
bool | Moves the client to another server |
p:resource_pack(uuid, url, hash, required?, prompt?), p:remove_resource_pack(uuid?) |
bool | Pushes or pops a pack; nil pops all |
p:border_set(cx, cz, size, warn_blocks?, warn_seconds?), p:border_reset() |
bool | This player's own world border |
p:wake_up(), p:swing(offhand?), p:hurt_animation(yaw) |
bool | Animations; swing and hurt reach everyone in the world |
p:look_at(x, y, z, eyes?) |
bool | Turns the client's view toward a point |
p:chat_completions(action, list) |
bool | Custom chat completions: 0 adds, 1 removes, 2 sets |
p:respawn(), p:chat(text), p:save_data() |
bool | Respawns a dead player, says something in chat, saves the player record |
Using items, combat log and trades#
| Call | Returns | Does |
|---|---|---|
p:use_start(offhand), p:use_complete(), p:use_clear() |
bool | Starts using the item of a hand (eat, draw a bow, raise a shield, spyglass), finishes it now, or drops it unfinished |
p:shoulder(side), p:set_shoulder(side, snbt) |
string | The entity on a shoulder (0 left, 1 right) as its saved compound, or an empty string |
p:riptide(ticks, damage, item_snbt), p:set_riptiding(bool) |
The spin attack state | |
p:firework_boost(item_snbt) |
int | Attaches a rocket to a gliding player; its entity id, or -1 |
p:sleep(x, y, z, force) |
bool | Sleeps in the bed at the position; force skips range, obstruction and time checks |
p:block_entity(x, y, z, block_id, snbt) |
Sends the block entity data of a block to this player only | |
p:load_data() |
Reloads the stored record (position, game mode, inventory, health, experience) into the live player and resyncs the client | |
p:combat(), p:combat_clear(), p:combat_push(type, message_id, direct, cause, damage, fall_distance, location, tick) |
list | The damage log; 8 values per entry: damage type, message id, direct entity id, cause entity id, damage, fall distance, fall location, game tick |
p:resend_recipes() |
The recipe packet and the recipe book again | |
p:open_merchant(title_json, offers_snbt), p:open_trades(entity_id) |
bool | A merchant window with trades a plugin made, or a villager's trades |
p:set_profile(name, value, signature, ...) |
Replaces the profile properties (the skin): the tab list entry is refreshed, the player respawns in place and every viewer sees it again | |
p:report_details(key, value, ...) |
A custom report details packet, at most 32 pairs | |
p:clear_dialog(), p:delete_chat(hex) |
Closes a dialog; removes a signed chat message by the hex of its 256 byte signature | |
p:show_dialog(dialog) |
bool | Shows a dialog: a string starting with { is the dialog in full as SNBT (type, title, body, inputs, buttons), any other is a registry dialog id such as minecraft:server_links; answers come back through player.custom_click, and Bedrock players get the closest form |
p:reenter_configuration() |
bool | Sends the client back to the configuration phase: the player leaves the world, the client runs the configuration again and joins again; false for a client without that phase or translated from another version |
p:as_string() |
string | The player saved as an entity compound in SNBT (position, health, food, experience, game mode, inventory, ender chest, uuid, tags) |
p:window_title(json) |
bool | The open screen again under a new title; the window keeps its contents |
offers_snbt is {offers:[{buy:{id,count,components},buy2:{...},sell:{...},uses,max_uses,xp,price_multiplier,demand,special_price}]}.
Showing the client something else#
These change only what one player sees.
| Call | Does |
|---|---|
p:sound_at(sound, category, x, y, z, volume, pitch, seed) |
Plays a sound; category is master, music, record, weather, block, hostile, neutral, player, ambient, voice or ui |
p:sound_entity(sound, category, entity_id, volume, pitch, seed) |
A sound at an entity's position |
p:stop_sound(sound?, category?) |
Stops matching sounds; with both nil it stops all |
p:particle_at(name, x, y, z, count, ox, oy, oz, sx, sy, sz, force, randomization, data...) |
A particle; data depends on it: block state id, color, dust (rgb, scale), dust transition, spell, number, delay, item id or trail |
p:world_event(id, x, y, z, data) |
A level event |
p:entity_event(entity_id, event) |
An entity event (status byte) |
p:game_event(event, param) |
A raw game event (win game 4, demo 5, elder guardian 10...) |
p:block_change(x, y, z, state_id) |
Shows one block differently |
p:block_damage(x, y, z, stage, entity_id?) |
Cracking stage 0 to 9; -1 clears |
p:sign_text(x, y, z, front, back, color?, glowing?, type?) |
Shows sign text; lines are joined by a newline |
p:open_sign(x, y, z, front?) |
Opens the sign editor |
p:send_equipment(entity_id, slot, snbt) |
Shows an equipment slot differently; slot 0 is the main hand, 7 the saddle, an empty snbt clears |
Stored data#
| Call | Returns | Does |
|---|---|---|
p:known_recipes(), p:discover_recipes(list), p:undiscover_recipes(list), p:has_recipe(id) |
list, int, bool | The recipe book |
p:spawn_point(), p:set_spawn_point(world, x, y, z, yaw), p:clear_spawn_point() |
list, bool | The respawn point { world, x, y, z, yaw } |
p:last_death(), p:set_last_death(dimension, x, y, z) |
list, bool | The recovery compass target |
p:ender_slot(i), p:set_ender_slot(i, snbt) |
string, bool | One ender chest slot as an item compound |
p:post_effects(), p:set_post_effects(list) |
list, bool | Shader post effects shown to the player |