Link Search Menu Expand Document

Face Direction Mask

The face direction mask is used to update the direction the player or NPC is facing. The mask’s structure vary greatly between NPCs and players. Therefore, they will be detailed separately.


Table of contents

Use Cases

The mask is primarily used to make the player face map objects before interacting with them. It is also used in cutscenes to redirect the direction where the players or NPCs face. Upon interacting with objects for example, a variable is set to point to the exact coordinates of where the entity is supposed to look. It however does not ensure that the entity will look at those coordinates in that same server tick. Instead, at the end of each server tick, the server will determine if the respective entity moved by any means(walking, running, teleporting). If they did not move, and the respective variable is set, the game will finally send out the face direction mask. If the entity did move, it will do nothing. The variable is never reset outside when it actually sends the info to the client, because of this, if you click and object and immediately click to move to another coordinate entirely, you will still face that given object once you stop moving.1

NPC mask

Supported variables

The face direction mask allows the server to specify the direction the NPC faces with half-tile precision. Below is a breakdown of the different variables that the server defines:

  • Two absolute coordinates with half-tile precision that define where the NPC will face.
    • The x coordinate.
    • The z coordinate.

Client Code

Below is the refactored version of the client code behind the face direction mask.

All the buffer methods shown below can have different transformations applied on them, depending on the revision of the client. For the purposes of the demonstration, all transformations have been excluded. Because NPC’s face direction mask has half a tile precision, the base X & Z coordinates are subtracted twice.

int faceDirectionX = buffer.readUnsignedShort();
int faceDirectionZ = buffer.readUnsignedShort();
int deltaX = npc.x - (faceDirectionX - Client.baseX - Client.baseX) * 64;
int deltaZ = npc.z - (faceDirectionZ - Client.baseZ - Client.baseZ) * 64;
if (deltaX != 0 || deltaZ != 0) {
    npc.movingOrientation = (int) (Math.atan2((double) deltaX, (double) deltaZ) * 325.949D) & 0x7FF;
}

Player mask

Supported variables

The face direction mask allows the server to specify the direction the player will face. The direction can be calculated by using the method specified in the next section. Below is a breakdown of the different variables that the server defines:

  • The face direction of the player, specified as an unsigned short, giving it a value range of 0 to 65,535(inclusive). Although the theoretical maximum is 65,535, the client will always use the bitwise-and operator to limit the maximum value to 2,047.

Client Code

Below is the refactored version of the client code behind the face direction mask.

All the buffer methods shown below can have different transformations applied on them, depending on the revision of the client. For the purposes of the demonstration, all transformations have been excluded.

player.movingOrientation = readUnsignedShort();
if (player.queueSize == 0) {
    player.orientation = player.movingOrientation;
    player.movingOrientation = -1;
}

Media

Below is an example of the player clicking on an object, but then clicking to run to a different location entirely. The server will still make them face the object at the end of the movement.

face dir gif