Skip to content

API reference / @jsprismarine/prismarine / PlayerSession

Class: PlayerSession ​

Defined in: prismarine/src/network/PlayerSession.ts:273

Constructors ​

Constructor ​

new PlayerSession(server, connection, player): PlayerSession

Defined in: prismarine/src/network/PlayerSession.ts:418

Parameters ​

server ​

Server

connection ​

ClientConnection

player ​

Player

Returns ​

PlayerSession

Accessors ​

sender ​

Get Signature ​

get sender(): ChunkSender

Defined in: prismarine/src/network/PlayerSession.ts:452

The queue the scheduler drains - see ChunkRecipient.

Returns ​

ChunkSender

Methods ​

addToPlayerList() ​

addToPlayerList(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2421

Adds the client to the player list of every player inside the server and also to the player itself.

Returns ​

Promise<void>


beginLoadingScreen() ​

beginLoadingScreen(): number

Defined in: prismarine/src/network/PlayerSession.ts:1876

Hands out the Loading Screen Id for a ChangeDimensionPacket about to be sent, and remembers it until PlayerSession.endLoadingScreen hears the client close that screen.

Returns ​

number

A uint32 no other open screen on this session uses.


changeWorld() ​

changeWorld(arrival, options?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1919

Moves the player to another world and walks the client through the dimension change.

Server side first: the record is saved to the world being left, stamped with that world's dimension, the player leaves its roster, the old world's entities come off the client, the chunk bookkeeping is cleared, the position moves, and the player joins the new roster. Then the wire sequence Dragonfly, Geyser and Nukkit agree on: one ChangeDimension with the target's Bedrock id, StopSound for everything playing, NetworkChunkPublisherUpdate at the arrival, the server-sent PlayerAction ChangeDimensionAck, the arrival chunks, and PlayStatus PlayerSpawn. The change stays pending, and the client's PlayerAuthInput is dropped, until the client closes the screen with the id this handed out: see PlayerSession.completeDimensionChange.

A client sent ChangeDimension to the dimension it is already in never closes the screen, so a move between two worlds of the same Bedrock id detours through another dimension first.

A second arrival while a change is pending is held until the client closes the first screen, then carried out; only the latest is kept. A caller whose arrival goes stale while it waits, such as a portal, instead passes whenPending: 'drop': the player is still ticked on the loading screen, and one who arrived inside the exit portal would otherwise be sent back once the 10 tick cooldown ran out, before the client ever closed the first screen. Custom dimension ids are sent after the level announces them in DimensionData.

Parameters ​

arrival ​

Arrival

The world, feet position and rotation the player lands at.

options? ​

What to do with this arrival when a change is already pending.

whenPending? ​

"queue" | "drop"

Returns ​

Promise<void>


clearChunks() ​

clearChunks(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1163

Clear the currently loaded and loading chunks.

Returns ​

Promise<void>

Remarks ​

Usually used for changing dimension, world, etc.

Everything in flight goes with them. The two sets are only the bookkeeping; the queue of coordinates still to send and the chunks already produced but not yet dispatched are the actual work, and they belong to the world being left. Left in place, a dimension change sent the old world's terrain into the new one, and resolved the leftover coordinates against a world where they mean somewhere else entirely.


closeWindow() ​

closeWindow(windowId): boolean

Defined in: prismarine/src/network/PlayerSession.ts:1531

Forgets a window the client reports closed.

The docs have the server delete its container manager when the client's ContainerClose arrives, before answering it. Only a window this session opened can be closed here; any other id is left alone and reported through the return value so the handler can log it.

Parameters ​

windowId ​

number

the Container Id the client sent.

Returns ​

boolean

whether a window with that id was open.


completeCredits() ​

completeCredits(): Promise<boolean>

Defined in: prismarine/src/network/PlayerSession.ts:2117

Finishes held credits: the full dimension change sequence to the held arrival, sent as a respawn, which is how Java's PlayerList.respawn(player, true, ...) answers the credits. Called by ShowCreditsHandler when the client reports the credits finished.

Returns ​

Promise<boolean>

Whether credits were pending. A finish with none pending changes nothing.


completeDimensionChange() ​

completeDimensionChange(loadingScreenId): Promise<boolean>

Defined in: prismarine/src/network/PlayerSession.ts:2184

Finishes a pending world change once the client reports its loading screen closed.

Teleports the client to the exact arrival position, re-sends the attributes and the inventory, which a dimension change is not known to keep, tells the client where its spawn point is from the new dimension, and raises the changed dimension advancement hook. Called by ServerboundLoadingScreenHandler.

Parameters ​

loadingScreenId ​

number

The id the client's EndLoadingScreen carried.

Returns ​

Promise<boolean>

Whether a change was pending under that id. Any other id changes nothing.


considerEntity() ​

considerEntity(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:759

Shows one entity to this client, if it is close enough and not already shown.

The single-entity path, for something that has just entered the world rather than a whole pass over everything in it.

Parameters ​

entity ​

Entity

The entity to consider.

Returns ​

Promise<void>


deliver() ​

deliver(x, z): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:465

Produces one chunk and queues it for the next batch. Called only by the scheduler.

The scheduler takes a coordinate off the queue before calling this, so a failure here has to put the bookkeeping back: loadingChunks is what stops needNewChunks from asking for the same chunk twice, and leaving the hash in it after nothing was sent means that chunk is never requested again - a permanent hole in the player's world for as long as they stay in range of it.

Parameters ​

x ​

number

z ​

number

Returns ​

Promise<void>


despawnAllTrackedEntities() ​

despawnAllTrackedEntities(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:788

Hides every tracked entity from this client and forgets them all.

For a world change. A dimension change does not make the client drop what it holds, so the mobs of the world being left stayed on screen in the new one. Not routed through PlayerSession.reconcileTrackedEntities: that returns early while another pass runs, and a world change cannot be skipped.

Returns ​

Promise<void>


dropEntity() ​

dropEntity(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:775

Hides one entity from this client if it is showing, and forgets it either way.

Unconditional forgetting matters: a stale id left behind would make the tracker believe the client still has an entity it does not, and block it from ever being sent again.

Parameters ​

entity ​

Entity

The entity that is going away.

Returns ​

Promise<void>


endLoadingScreen() ​

endLoadingScreen(id): boolean

Defined in: prismarine/src/network/PlayerSession.ts:1888

Records that the client closed a loading screen.

Parameters ​

id ​

number

The Loading Screen Id from the client's ServerboundLoadingScreenPacket.

Returns ​

boolean

Whether the id belonged to a screen this session had opened and not yet closed.


flush() ​

flush(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:800

Sends what has been produced but not yet dispatched.

Called by the scheduler at the end of its pass, so a partial batch does not sit until the next tick.

Returns ​

Promise<void>


flushQueuedMoves() ​

flushQueuedMoves(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2762

Sends this tick's movement as one batch.

Called once per world tick, after every entity has had its update.

Returns ​

Promise<void>

Resolves once the batch has been framed.


getClientCacheEnabled() ​

getClientCacheEnabled(): boolean

Defined in: prismarine/src/network/PlayerSession.ts:497

Whether this session will use cached blobs in request-mode subchunk responses.

Returns ​

boolean


getConnection() ​

getConnection(): ClientConnection

Defined in: prismarine/src/network/PlayerSession.ts:2846

Returns ​

ClientConnection


getOpenBlockContainer() ​

getOpenBlockContainer(): OpenBlockContainer | undefined

Defined in: prismarine/src/network/PlayerSession.ts:1484

The block container this session has open, or undefined for none.

Returns ​

OpenBlockContainer | undefined


getPlayer() ​

getPlayer(): Player

Defined in: prismarine/src/network/PlayerSession.ts:2850

Returns ​

Player


handleClientCacheBlobStatus() ​

handleClientCacheBlobStatus(packet): Promise<number>

Defined in: prismarine/src/network/PlayerSession.ts:510

Responds to requested blob misses and applies the client's acknowledgements.

Every status is answered, with an empty ClientCacheMissResponse when the client missed nothing. Bedrock Dedicated Server 1.26.60 does the same, 105 answers to 105 statuses in the capture docs/research/sub-chunk-requests-and-blob-cache.md describes. Do not skip the empty one to save a packet: the answer is what closes the client's cache transaction.

Parameters ​

packet ​

ClientCacheBlobStatusPacket

Returns ​

Promise<number>

How many blobs went out.


handleSubChunkRequest() ​

handleSubChunkRequest(packet): Promise<number>

Defined in: prismarine/src/network/PlayerSession.ts:538

Answers requested sections with their bytes, block entities, heightmaps, and cache ids.

The shape of each entry follows a capture of Bedrock Dedicated Server 1.26.60 answering a retail client, recorded in docs/research/sub-chunk-requests-and-blob-cache.md. With the client's blob cache on:

  • A section with blocks carries the hash of its terrain and a payload that is present even when empty. The payload holds the section's block entities only.
  • An all-air section carries neither payload nor hash.
  • The answer is the same whether or not the client has confirmed the blob before.

These look like things to simplify, such as dropping an empty payload or sending the terrain inline to save a round trip. A retail client leaves with a bad packet error (ClientDisconnection-90) on either, so change them only against a new capture.

Parameters ​

packet ​

SubChunkRequestPacket

The requested chunk columns and absolute subchunk center.

Returns ​

Promise<number>


holdsMovementForTeleport() ​

holdsMovementForTeleport(position, handledTeleport): boolean

Defined in: prismarine/src/network/PlayerSession.ts:2402

Whether an input's position must be ignored because the client has not yet handled a teleport the server sent it.

Mojang's packet documentation, on HandledTeleport: "The server should ignore any client predicted positions from the moment a MovePlayerPacket was sent until receipt of this action." That covers every teleport, the one that ends a dimension change included.

The client goes on sending inputs from where it was until it applies the MovePlayer, and the first input from the new place carries HandledTeleport. A retail client was captured doing exactly that, with one stale input arriving after the teleport about one time in three. Taking the stale position moves the player back on the server while the client stands at the target, and the server then sends chunks for the wrong place. A client that stops sending inputs while it waits for chunks never recovers from that.

The hold ends on a HandledTeleport input at the target, which tells two teleports sent in a row apart, or after TELEPORT_ACK_TIMEOUT_TICKS, so a client that never sets the flag is not frozen in place.

Parameters ​

position ​

Vector3

Where the input says the player is.

handledTeleport ​

boolean

Whether the input carries HandledTeleport.

Returns ​

boolean


isConnected() ​

isConnected(): boolean

Defined in: prismarine/src/network/PlayerSession.ts:635

Returns ​

boolean


needNewChunks() ​

needNewChunks(forceResend?, dist?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1005

Parameters ​

forceResend? ​

boolean = false

dist? ​

number

Returns ​

Promise<void>


openBlockContainer() ​

openBlockContainer(at, identifier, contents?): Promise<OpenBlockContainer | undefined>

Defined in: prismarine/src/network/PlayerSession.ts:1309

Opens the screen a block draws, with whatever the block is holding.

The one call the interaction path needs. Until this existed no block opened a container anywhere in this server: a chest, a furnace and a crafting table all did nothing when they were clicked, because openMainInventory was the only ContainerOpen ever sent.

The contents follow the open for the same reason they do there: a window whose contents never arrive is one the client has no reason to keep. Each packet uses the container name that screen assigns to its slots, so a furnace's fuel list arrives under its fuel name. A workstation stores nothing of its own, so no contents follow its open. A crafting table is followed by the player's own inventory under window 0 instead, which is what a Bedrock Dedicated Server 1.26.52 sent after a click on one. Repeated requests for the same open block return the current window without sending another open packet.

Parameters ​

at ​

Vector3

The block position, which is what ContainerOpen carries for a block.

identifier ​

string

The block standing there, which decides the screen.

contents? ​

ContainerEntry[] = []

What the block holds, one entry per slot.

Returns ​

Promise<OpenBlockContainer | undefined>

The window it was opened under, or undefined when the block opens no screen.


openMainInventory() ​

openMainInventory(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1277

Opens the player's own inventory, as the client asked.

Under its own window id rather than under zero. Zero is the inventory the client always has open; asking it to open that one is asking for something it is already doing, and it answered by closing the window again straight away - which is as far as opening an inventory ever got, so no drag inside it was ever attempted.

The contents follow the open, because a window whose contents never arrive is one the client has no reason to keep.

Returns ​

Promise<void>

See ​

https://github.com/pmmp/PocketMine-MP/blob/stable/src/network/mcpe/InventoryManager.php (onClientOpenMainInventory)


openTradeWindow() ​

openTradeWindow(trade): Promise<OpenBlockContainer | undefined>

Defined in: prismarine/src/network/PlayerSession.ts:1417

Opens a villager's trade screen and shows it the trader's offers.

The screen is a window like a block's: it has two payment slots the player's items go into and a result the trade comes out of, and closing it gives the payment back. It differs in being open on an actor, which the packet names, and in what follows the open: an UpdateTradePacket carrying the offers, which the client draws the screen from.

Parameters ​

trade ​

OpenTrade

The trader, where its offers come from and what happens when the player leaves.

Returns ​

Promise<OpenBlockContainer | undefined>

The window, or undefined when this session already has a trade open on that trader.


pendingCreditsArrival() ​

pendingCreditsArrival(): Arrival | undefined

Defined in: prismarine/src/network/PlayerSession.ts:2139

The arrival held while the credits roll on the client, or undefined when none are. While one is held, the client's PlayerAuthInput is dropped, as it is during a pending dimension change.

Returns ​

Arrival | undefined


pendingDimensionChange() ​

pendingDimensionChange(): PendingDimensionChange | undefined

Defined in: prismarine/src/network/PlayerSession.ts:2072

The world change the client has not yet finished loading into, or undefined when the player is settled. While one is pending, the client's positions are still the old world's and PlayerAuthInputHandler drops them.

Returns ​

PendingDimensionChange | undefined


queueChunks() ​

queueChunks(centerX, centerZ, coordinates): void

Defined in: prismarine/src/network/PlayerSession.ts:640

Queues the chunks around a position, nearest first, without sending anything yet.

Parameters ​

centerX ​

number

centerZ ​

number

coordinates ​

[number, number][]

Returns ​

void


queueMoveActor() ​

queueMoveActor(entity, teleport?): void

Defined in: prismarine/src/network/PlayerSession.ts:2748

Adds an entity's movement to this tick's batch.

Sending each one on its own is what made mobs move in fits and starts, and for two reasons. Every packet became its own compressed batch and its own RakNet frame, so thirty mobs cost thirty compressions and thirty frames a tick, per player. Worse, sendDataPacket queues behind any chunk still compressing - so while a walking player streams terrain, every mob's movement waited behind it and then arrived in a burst. Mobs froze and jumped in exactly the rhythm the chunks were arriving in.

One batch a tick fixes both: one compression, one frame, and one place in the queue for the lot of them.

Parameters ​

entity ​

Entity

The entity that moved.

teleport? ​

boolean = false

Returns ​

void


reconcileTrackedEntities() ​

reconcileTrackedEntities(entities?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:726

Shows and hides entities so the client matches where the player now is.

Records an entity as tracked only after its spawn has gone out. Marking first would mean a spawn that failed left the entity flagged as delivered, and nothing would ever send it again - the same lesson flushChunkBatch records for chunks, where it left a permanent hole in the world.

Parameters ​

entities? ​

Iterable<Entity, any, any>

Every entity in the world, and it must be every one - anything tracked and absent from it is taken to have left and is despawned. Defaults to asking the world. For a single arrival, use PlayerSession.considerEntity.

Returns ​

Promise<void>


recordInputTick() ​

recordInputTick(tick): void

Defined in: prismarine/src/network/PlayerSession.ts:1866

Remember the tick of a PlayerAuthInputPacket just handled, so packets about this player can carry it as their PlayerInputTick.

Ticks only move forward; an input that arrives out of order does not wind the value back.

Parameters ​

tick ​

bigint

The packet's Tick field.

Returns ​

void


releaseArrivalChunks() ​

releaseArrivalChunks(loadingScreenId): Promise<boolean>

Defined in: prismarine/src/network/PlayerSession.ts:2158

Lets the columns of a pending dimension change go out, once the client says it has opened that change's loading screen, and sends the ones already waiting.

Until then they are held. A client that decodes a column before it has switched dimension files it under the dimension it is leaving and drops it at the switch, then waits on its loading screen for a column the server believes it has: cinnabar did this on about one full e2e run in two. The client reports the screen open only after its switch has begun, so a column sent from then on lands in the new dimension. Sending the lost ones again is not a remedy: in sub chunk request mode a second LevelChunk resets the column the client holds, and a player standing on it falls through. ARRIVAL_HOLD_TICKS bounds the wait for a client that never reports the screen.

Parameters ​

loadingScreenId ​

number

The id the client's StartLoadingScreen carried.

Returns ​

Promise<boolean>

Whether this released the pending change's columns. Any other id changes nothing.


releaseChangeHeldOverDeath() ​

releaseChangeHeldOverDeath(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2060

Carries out the change PlayerSession.changeWorld held while the player was dead. Called by Player.respawn once the client is told its player is alive. A change still pending, the respawn's own included, carries the held one out when it closes instead.

Returns ​

Promise<void>


removeFromPlayerList() ​

removeFromPlayerList(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2445

Removes a player from other players list

Returns ​

Promise<void>


requestChunk() ​

requestChunk(x, z): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1070

Parameters ​

x ​

number

z ​

number

Returns ​

Promise<void>


send() ​

send(packet): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:925

Sends one packet to this client.

Returns the send rather than dropping it: without this, every await session.send(...) and every Promise.all over a broadcast resolved immediately and any framing error went nowhere.

Parameters ​

packet ​

NetworkPacket<unknown>

The packet to send.

Returns ​

Promise<void>


sendAbilities() ​

sendAbilities(player?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:957

Sends UpdateAbilitiesPacket describing player to this client.

One BASE layer carries every ability, derived from the game mode and op state, with walk speed 0.1, fly speed 0.05 and vertical fly speed 1, the client's own defaults. The target id is the player's runtime id, which the server also uses as its unique id.

Parameters ​

player? ​

Player

The player described. Defaults to this session's own player.

Returns ​

Promise<void>


sendAddActor() ​

sendAddActor(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2476

Writes an entity onto this connection.

Packet construction lives here rather than on the entity: what goes on the wire is the session's business, and an entity that built its own packets also had to reach into the world for the list of players to send them to.

Parameters ​

entity ​

Entity

The entity to show.

Returns ​

Promise<void>


sendAddItemActor() ​

sendAddItemActor(item): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2645

Writes a dropped item onto this connection.

Parameters ​

item ​

Item

The item entity to show.

Returns ​

Promise<void>


sendArmorFor() ​

sendArmorFor(wearer): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2550

Tells this client what a human is wearing and holding in the off hand.

All four armor pieces at once, empty ones included as air: the packet is positional and a client that was sent three would read the next packet's bytes as the fourth. Body is the body armor slot, which HumanInventory does not model, so it is always air. It used to carry the off-hand item, which the client took for body armor.

The off hand goes out as a MobEquipmentPacket for the offhand container, the way the client reports its own off-hand changes.

Parameters ​

wearer ​

Human

Whose armor it is.

Returns ​

Promise<void>


sendAttributes() ​

sendAttributes(attributes?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1813

Send the player's whole attribute set.

The client rebuilds the local player during the spawn sequence, so this has to be sent again once the player is in the world - anything sent before that is thrown away, which is why the hunger bar sat empty however correct the values were here.

Parameters ​

attributes? ​

Attributes = ...

The attributes to send.

Returns ​

Promise<void>


sendAttributesFor() ​

sendAttributesFor(entity, attributes): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1847

Tell this client about another entity's changed attributes.

The gap that made mob combat invisible. Everything above sends the local player's own attributes, with their runtime id baked in, so a mob losing health changed a number on the server that no client was ever told about - the health bar over a hurt zombie never moved, and it died in one apparent hit from full. Attributes only reached a client once, inside the AddActorPacket that spawned the entity.

Parameters ​

entity ​

Entity

Whose attributes these are.

attributes ​

Attribute[]

The ones that changed; nothing is sent for an empty list.

Returns ​

Promise<void>


sendAvailableCommands() ​

sendAvailableCommands(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1711

Tells the client which commands this player may run and what each one takes.

One CommandData per command, each branch of its tree an overload, with overloads that come out the same folded into one. Only commands the player's permissions allow are sent, so the list is built per recipient and sent again when those permissions change.

The list is the command manager's one registry, already flattened into Bedrock's overload shape by @jsprismarine/commands, which carries chained subcommands and therefore the chained /execute tree.

Returns ​

Promise<void>


sendContainerData() ​

sendContainerData(at, properties): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1499

Sets properties on the open block container's screen, which is how a progress bar moves.

A property whose value has not changed since the last send is skipped; see PlayerSession.containerData. Nothing is sent when the screen was opened from a different block, so a station ticking across the world cannot write over the screen the player is actually looking at.

Parameters ​

at ​

Vector3

The block the properties belong to.

properties ​

ReadonlyMap<number, number>

The property values by id, as the station reports them.

Returns ​

Promise<void>


sendContainerSlot() ​

sendContainerSlot(windowId, containerId, slot, item): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1246

Tells this client that one slot of a container it has open now holds something else.

An ItemStackResponse only ever reaches the client that sent the request, so this is the only way to tell the other players standing at the same chest that a stack has gone.

Parameters ​

windowId ​

number

The Container Id this client opened the block under, which is its own.

containerId ​

number

The Container Name the client numbers the slot by.

slot ​

number

The slot within that container.

item ​

Item | null

What is in it now, or null to empty it.

Returns ​

Promise<void>


sendCraftingData() ​

sendCraftingData(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1570

Tells the client which recipes exist.

Until it has these the client proposes nothing and never sends a CRAFTING_RECIPE, so everything below this - the matcher, the stations, the grid - is invisible without it.

The recipes come from the content build's recipe book, and a recipe's net id is its position in that book, which is what an ItemStackRequest names it by. A build that produced no payload sends nothing, so the client proposes nothing it cannot craft.

How many go out is crafting-recipe-limit in the config: 0 sends nothing, -1 sends everything, and it starts at one. See there for why.

Returns ​

Promise<void>


sendCreativeContents() ​

sendCreativeContents(empty?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1595

Parameters ​

empty? ​

boolean = false

Returns ​

Promise<void>


sendDespawn() ​

sendDespawn(player): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2835

Despawn the player entity from another player

Parameters ​

player ​

Player

Returns ​

Promise<void>


sendEquipmentFor() ​

sendEquipmentFor(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2592

Tells this client everything one entity is holding and wearing.

The mob counterpart of PlayerSession.sendArmorFor, which reads a Human's armor container and so cannot serve anything that has no inventory. A data-driven mob keeps its equipment on the body itself, rolled from minecraft:equipment.

Both packets go out whatever the entity is wearing, rather than only the occupied slots. MobArmorEquipmentPacket is positional, so a client sent three pieces reads the next packet's bytes as the fourth, and an empty slot has to travel as air. The main hand is a separate packet because that is the one the client reads a held item from; the off hand follows only when something is in it, the way vanilla sends it.

Parameters ​

entity ​

Entity

Whose equipment it is.

Returns ​

Promise<void>


sendGamemode() ​

sendGamemode(gamemode?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1656

Send gamemode to a client.

Parameters ​

gamemode? ​

Gametype

the numeric gamemode ID.

Returns ​

Promise<void>


sendGameRules() ​

sendGameRules(rules): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1684

Tells this client that game rules changed.

Parameters ​

rules ​

GameRule[]

The rules that changed, spelled as the client spells them.

Returns ​

Promise<void>


sendGameTypeFor() ​

sendGameTypeFor(target): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1671

Tells this client which game type a player now has.

UpdatePlayerGameTypePacket is what the docs have the server send to every client after it accepts a game type change, because each client caches the game type and permission flags of every player it knows about. The Tick is this client's last input tick when the player is its own, so the client can reconcile the movement it predicted while the packet was in flight, and zero for anyone else, as the docs allow.

Parameters ​

target ​

Player

The player whose game type changed.

Returns ​

Promise<void>


sendHandItem() ​

sendHandItem(item): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1630

Sets the item in the player hand.

Parameters ​

item ​

Item

The entity.

Returns ​

Promise<void>


sendHeldItemFor() ​

sendHeldItemFor(entity, item): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2628

Tells this client what another entity is holding.

Parameters ​

entity ​

Entity

Whose hand it is in.

item ​

Item

What they are holding.

Returns ​

Promise<void>


sendInventory() ​

sendInventory(windowId?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1197

Tells the client what the player is carrying.

The send was commented out, so the client was never told: it had no model of the player's own slots, and the server authoritative inventory system will not move a stack into a container it does not know. Every drag was refused on the client's side, before an ItemStackRequest was ever sent.

Parameters ​

windowId? ​

number = WindowIds.INVENTORY

Returns ​

Promise<void>


sendMessage() ​

sendMessage(options): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2307

Send a chat message to the client.

Parameters ​

options ​

The options for the message.

message ​

string

The message to send.

needsTranslation? ​

boolean = false

Whether the message needs translation.

parameters? ​

string[] = []

The parameters for the message.

platformChatId? ​

string = ''

The platform chat ID.

sourceName? ​

string = ''

The source of the message.

type? ​

TextPacketType = TextPacketType.Raw

The type of the message.

xuid? ​

string = ''

The XUID of the player.

Returns ​

Promise<void>

A promise that resolves when the message is sent.


sendMetadata() ​

sendMetadata(metadata?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2224

Parameters ​

metadata? ​

Metadata

Returns ​

Promise<void>


sendMetadataFor() ​

sendMetadataFor(entity, metadata?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2238

Tell this client what another entity now looks like.

The same gap sendAttributesFor fills, for the other half of an entity's state: everything above had the local player's runtime id baked in, so metadata reached a client exactly once, inside the packet that spawned the entity. A creeper could light its fuse, a mob could catch fire, and nobody would ever see either.

Parameters ​

entity ​

Entity

Whose metadata this is.

metadata? ​

Metadata

What to send; the entity's own by default.

Returns ​

Promise<void>


sendMotion() ​

sendMotion(motion): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2216

Hand the client a velocity and let it move the player itself.

The only way to shove a player. Their position is theirs - the server stores what it is told - so setting it from here is overruled by the next movement packet and read as rubber-banding. A velocity is a request the client is happy to honor.

The Tick is the client's last input tick, as the docs ask for a packet about the player: the client rewinds to that tick, applies the velocity and replays what it predicted since. See PlayerSession.recordInputTick.

Parameters ​

motion ​

Vector3

Blocks per tick, in each axis.

Returns ​

Promise<void>


sendMove() ​

sendMove(player, mode?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2356

Sends one player's movement to this client.

Named for what it does. It was broadcastMove, which reads as a fan-out and is not one - the fan-out is World.broadcastMove, and having both made it easy to write the wrong one.

For this client's own player the packet is a server-initiated move: a teleport, a respawn, or a reset after a canceled move event. Its Tick is the client's last input tick, as the docs ask, so the client rewinds to it and replays its predictions from there. For any other player the packet is what this client sees of them, and the tick is zero because it relates to none of this client's inputs.

Parameters ​

player ​

Player

The player that moved.

mode? ​

PositionMode = PositionMode.Normal

What produced the movement.

Returns ​

Promise<void>


sendMoveActor() ​

sendMoveActor(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2730

Tells this connection an entity has moved, on its own.

For a move that happens outside the world tick - a teleport, a command. Movement produced by the tick goes through queueMoveActor instead.

Parameters ​

entity ​

Entity

The entity that moved.

Returns ​

Promise<void>


sendNetworkChunkPublisher() ​

sendNetworkChunkPublisher(distance, savedChunks): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1690

Parameters ​

distance ​

number

savedChunks ​

ChunkCoord[]

Returns ​

Promise<void>


sendPlayerList() ​

sendPlayerList(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2461

Sends the full player list to the player.

Returns ​

Promise<void>


sendPlayStatus() ​

sendPlayStatus(status): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2842

Sends a PlayStatus to this player's client.

Parameters ​

status ​

PlayStatus

Returns ​

Promise<void>


sendRemoveActor() ​

sendRemoveActor(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2670

Takes an entity off this connection.

Parameters ​

entity ​

Entity

The entity to remove.

Returns ​

Promise<void>


sendRemoveActorById() ​

sendRemoveActorById(runtimeId): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2683

Takes an entity off this client by id.

By id rather than by entity because the tracker has to be able to hide something that has already left the world - there is no object left to ask. Correct for every kind of entity: RemoveActorPacket is what both Entity.despawnFrom and Player.despawnFrom end up sending, players included.

Parameters ​

runtimeId ​

bigint

The entity's runtime id.

Returns ​

Promise<void>


sendRespawn() ​

sendRespawn(position, state): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2286

One of the server's two halves of the respawn exchange.

The order matters and is not obvious. SearchingForSpawn goes out the moment the player dies, carrying where they will reappear; the client then shows its death screen. ReadyToSpawn is the answer to the client saying it has finished loading, and goes out only then.

Sending the second in place of the first leaves the client on "Respawning" for ever: it is waiting to be told where it will come back before it will even offer the button.

Player Runtime Id is always 0, as in every Respawn a Bedrock Dedicated Server 1.26.52 sends, at the join and after a death.

Parameters ​

position ​

Vector3

Where the player will reappear.

state ​

PlayerRespawnState

Which half of the exchange this is.

Returns ​

Promise<void>

See ​

https://github.com/pmmp/PocketMine-MP/blob/stable/src/network/mcpe/handler/DeathPacketHandler.php


sendRespawned() ​

sendRespawned(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2256

Tells the client its player is alive again, as a Bedrock Dedicated Server 1.26.52 does when the respawn button is pressed: ActorEvent(SPAWN_ALIVE) for the player, its health, then its attributes and actor data.

No MovePlayer: the client has put itself at the ReadyToSpawn position already.

Returns ​

Promise<void>


sendSettings() ​

sendSettings(player?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:934

Notify a client about change(s) to the adventure settings.

Parameters ​

player? ​

Player

The client-controlled entity

Returns ​

Promise<void>


sendSpawn() ​

sendSpawn(player): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2781

Spawn the player for another player

Parameters ​

player ​

Player

the player to send the AddPlayerPacket to

Returns ​

Promise<void>


sendStatusEffect() ​

sendStatusEffect(entity, effect, change): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2521

Sends one effect state change to this client.

Parameters ​

entity ​

Entity

The actor whose effect changed.

effect ​

StatusEffect

The effect state.

change ​

StatusEffectChange

Whether it was added, updated, or removed.

Returns ​

Promise<void>


sendStatusEffects() ​

sendStatusEffects(entity): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2511

Sends every active effect after the actor that owns them has spawned.

Parameters ​

entity ​

Entity

The spawned actor.

Returns ​

Promise<void>


sendTime() ​

sendTime(tick): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1647

Send the current tick to a client.

Parameters ​

tick ​

number

The tick

Returns ​

Promise<void>


sendTradeOffers() ​

sendTradeOffers(window?): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1453

Sends the open trade screen the trader's offers as they stand, after a trade or a restock.

Parameters ​

window? ​

OpenBlockContainer | undefined = ...

Returns ​

Promise<void>


setClientCacheEnabled() ​

setClientCacheEnabled(enabled): void

Defined in: prismarine/src/network/PlayerSession.ts:491

Enables or clears client blob caching for subsequent subchunk requests.

Parameters ​

enabled ​

boolean

Returns ​

void


setViewDistance() ​

setViewDistance(distance): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1745

Set the client's maximum view distance.

Parameters ​

distance ​

number

The view distance

Returns ​

Promise<void>


startCredits() ​

startCredits(arrival): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:2093

Rolls the end credits on the client and holds the arrival until they finish.

Sent on a player's first exit through the End's portal. The world change waits for the client's ShowCredits Finished rather than going out under the credits screen, because a ChangeDimension during the credits has not been verified against a retail client (open question 4 of the End dragon fight plan); Java holds its transfer the same way, on the PERFORM_RESPAWN exchange. While the arrival is held, the client's PlayerAuthInput is dropped, as during a pending dimension change. The held change is completed by PlayerSession.completeCredits. A disconnect in between strands nobody: the player record already carries seenCredits, so the next join finds the player still in the End, standing in the portal, and transfers them at once.

A second start while one is pending is logged at debug and dropped, like a second changeWorld.

Parameters ​

arrival ​

Arrival

Where the player lands once the credits are over.

Returns ​

Promise<void>


syncAttributes() ​

syncAttributes(): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:1824

Send only the attributes that changed since the last sync, if any.

Called every tick from Player.update: a value nothing tells the client about is a value that only exists on the server.

Returns ​

Promise<void>


tracks() ​

tracks(runtimeId): boolean

Defined in: prismarine/src/network/PlayerSession.ts:711

Whether this client knows about the entity.

True for the player's own entity, which the tracker itself never holds - a client is not sent a spawn for the thing it is driving, but it plainly has it. Without this the gates built on tracks would drop a player's own hurt animation and the pickup animation for the item they just walked over.

Parameters ​

runtimeId ​

bigint

The entity's runtime id.

Returns ​

boolean

true if the client can act on a packet naming that id.


tryDeliverLoaded() ​

tryDeliverLoaded(x, z): CachedChunkDelivery

Defined in: prismarine/src/network/PlayerSession.ts:478

Queues a resident chunk without entering the generation and disk-read depth gate.

Parameters ​

x ​

number

z ​

number

Returns ​

CachedChunkDelivery


update() ​

update(tick): Promise<void>

Defined in: prismarine/src/network/PlayerSession.ts:660

Per-tick work for this client: terrain to request, entities to show or hide.

Both hang off the same question - has the player walked into a different chunk. Asking it here rather than inside each is what stops needNewChunks rebuilding a heap of a few hundred candidates twenty times a second for a player who has not moved, and it is what makes a moving player see entities appear within a tick rather than on the next interval.

Parameters ​

tick ​

number

Returns ​

Promise<void>

Lifecycle ​

disable() ​

disable(): void

Defined in: prismarine/src/network/PlayerSession.ts:447

Takes this client back out of the chunk rotation. Paired with PlayerSession.enable and safe to call more than once.

Returns ​

void


enable() ​

enable(): void

Defined in: prismarine/src/network/PlayerSession.ts:438

Puts this client into the server-wide rotation that feeds it chunks.

Not done in the constructor: a session that is built and then thrown away - a join that fails part way through - would stay in the scheduler's set for the life of the server, because the scheduler only ever skips the disconnected and removes on request.

Returns ​

void