Skip to content
mc-protocol
Esc
↑↓navigate↵open⌘Jpreview
On this page

Login

Play 0x31, server → client.

play · 0x31 · clientbound (server → client)

Starts the play state; this is the ‘join game’ packet. It carries the player’s entityId, hardcore flag, dimension list, view and simulation distances, and the spawn info for the current dimension (dimension type, name, seed hash, game mode, and so on). The server sends it once, right after the configuration state finishes, and the client uses it to set up the world before receiving chunks.

Sent by the server, read by the client. Listen for it with client.on("Login", (data) => …) on the receiving side.

Fields

Field Type Notes
entityId Int
isHardcore Boolean
worldNames Array
maxPlayers VarInt
viewDistance VarInt
simulationDistance VarInt
reducedDebugInfo Boolean
enableRespawnScreen Boolean
doLimitedCrafting Boolean
worldState SpawnInfo
onlineMode Boolean
enforcesSecureChat Boolean

Send it

const WORLD = "minecraft:overworld";

await client.sendPacket("Login", {
  entityId: 1,
  isHardcore: false,
  worldNames: [WORLD],
  maxPlayers: 20,
  viewDistance: 8,
  simulationDistance: 2,
  reducedDebugInfo: false,
  enableRespawnScreen: true,
  doLimitedCrafting: false,
  worldState: {
    dimension: 0, // index into the dimension_type registry
    name: WORLD,
    hashedSeed: 0n,
    gamemode: 1, // creative
    previousGamemode: 255, // none
    isDebug: false,
    isFlat: true,
    death: null,
    portalCooldown: 0,
    seaLevel: -63,
  },
  onlineMode: false,
  enforcesSecureChat: false,
});

The first packet after entering play. entityId becomes the player’s own ID; reuse it in entity packets. worldState.dimension is the index of the dimension type in the registry sent during configuration. See Building a server for the full spawn sequence.

Field aliases listed under Notes are accepted as alternative keys when writing.

Source: src/Core/Versions/776/Packets/play/clientbound/Login.ts

Was this page helpful?