Skip to main content

Entities

session.entityState is an EntityStateTracker — the live entity model.

EntityStateTracker

MemberTypeDescription
entitiesMap<bigint, AbstractEntity>All tracked entities, keyed by runtime id.
playerListMap<string, PlayerListEntry>The player (tab) list, keyed by UUID string.
localPlayerEntityLocalPlayerThe local player.
ctx.on("tick", () => {
for (const entity of ctx.session.entityState.entities.values()) {
console.log(entity.name, entity.position);
}
});

The entity hierarchy

Every value in entities is an AbstractEntity. The concrete subclasses are value exports, so you narrow with instanceof:

AbstractEntity
├── EntityPlayer
│ ├── EntityNetworkPlayer // other players
│ └── EntityLocalPlayer // you — see the Local Player page
├── EntityCreature // mobs
└── EntityItem // dropped items
import { EntityCreature, EntityNetworkPlayer } from "@protohax/userscript";

for (const e of ctx.session.entityState.entities.values()) {
if (e instanceof EntityNetworkPlayer) {
console.log("player", e.username, e.health);
} else if (e instanceof EntityCreature && e.isHostile) {
console.log("hostile mob", e.identifier);
}
}

AbstractEntity

The base every entity shares.

MemberTypeDescription
runtimeIdbigintNetwork runtime id (the key in entities).
positionVector3World position.
prevPositionVector3Position on the previous tick.
motionVector3Current velocity.
rotationVector3Rotation as (pitch, yaw, headYaw).
isOnGroundbooleanWhether the entity is on the ground.
aabbAABBWorld-space bounding box.
get aabbShapeAABBUntranslated box (translate by position for world-space).
tickLivedbigintTicks the entity has existed.
healthnumberCurrent health.
maxHealthnumberMaximum health.
absorptionnumberAbsorption (yellow) health.
scalenumberModel scale.
effectsMap<string, MobEffect>Active status effects, keyed by handle (e.g. minecraft:invisibility).
hurtTimenumberRemaining hurt-animation ticks.
get canBeAttackedbooleanWhether this is a valid attack target.
get namestringDisplay name.
entityEventsEventEmitter<EntityEvents>Per-entity event emitter (see below).
getMetadata<T>(key)T | undefinedRead a raw metadata value by key.

EntityPlayer (adds)

Base of both other players and the local player.

MemberTypeDescription
uuidUUIDPlayer UUID.
usernamestringPlayer name.
gamemodeGameModeCurrent game mode.
permissionLevelPermissionLevelPermission level.
get playerListEntryPlayerListEntry | undefinedThis player's tab-list entry, if present.
get eyePositionVector3Eye position (accounts for sneak/swim/crawl).
get nameColorstring | nullChat/team color code parsed from the name, if any.
get armorColorColor | undefinedTeam armor color, if any.

EntityNetworkPlayer is EntityPlayer with no additional members — it's the type of other players in the world.

EntityCreature (adds)

MemberTypeDescription
identifierstringNormalized entity identifier, e.g. minecraft:zombie.
isLivingbooleanWhether this is a living entity (mob).
isHostilebooleanWhether this is a hostile mob.
isPickablebooleanWhether this entity can be picked/attacked.
isCustombooleanWhether this is a non-vanilla (custom) entity.

EntityItem (adds)

MemberTypeDescription
itemItemStackThe dropped item stack.

Per-entity events — entityEvents

Each entity has its own EventEmitter for changes to that entity:

ctx.on("entity_spawn", (entity) => {
entity.entityEvents.on("health", () => {
console.log(entity.name, "health ->", entity.health);
});
});

The EntityEvents map:

EventPayloadFires when
move()Position/rotation changed.
health()Health changed.
hurt()Entity took damage.
destroy()Entity was removed.
name()Display name changed.
attribute(key: string)An attribute updated.
effect("add" | "remove" | "update", key)A status effect changed.
inventory_update()Inventory changed (does not fire for the local player).
metadata_<key>(value)A specific metadata field changed.

PlayerListEntry

The tab-list entry — present even for players not currently spawned as entities.

MemberType
uuidUUID
entity_unique_idbigint
usernamestring
build_platformnumber
skinPlayerSkin

UUID

MemberSignatureDescription
bytesUint8ArrayRaw 16 bytes.
equals(other)booleanCompare two UUIDs.
toString()stringCanonical string form.
UUID.parse(str)static UUIDParse from string.
UUID.ZEROstatic UUIDThe all-zero UUID.

PlayerSkin

MemberSignatureDescription
get hasVisibleGeometrybooleanSkin has any visible geometry.
get hasValidGeometrybooleanSkin has valid humanoid geometry.
extractAvatar()Uint8Array | undefinedFace/avatar as raw RGBA pixels, if derivable.

GameMode and PermissionLevel

These are string-union types, not enums — compare against the string:

type GameMode =
| "survival" | "creative" | "adventure"
| "survival_spectator" | "creative_spectator"
| "fallback" | "spectator" | number;

type PermissionLevel =
| "visitor" | "member" | "operator" | "custom" | number;

if (player.gamemode === "creative") { /* ... */ }