@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
222 lines (221 loc) • 6.15 kB
TypeScript
/**
* ARCHITECTURE: EntityManager
*
* Tracks all entities (mobs, players, items) in the currently loaded world view.
* Receives entity updates from the active world data source and maintains entity state.
*
* ENTITY LIFECYCLE:
* add_actor/add_player → create entity state
* move_actor_absolute/move_actor_delta → update position
* set_actor_data → update metadata
* remove_actor → delete entity state
*
* INTERPOLATION:
* Server sends at ~20 TPS, client renders at 60 FPS.
* We store previous + current positions and interpolate between them.
*/
/** Shared 3D coordinate shape used in most Bedrock packets. */
export interface IBedrockVec3 {
x?: number;
y?: number;
z?: number;
X?: number;
Y?: number;
Z?: number;
pitch?: number;
yaw?: number;
head_yaw?: number;
}
export interface IAddActorPacket {
runtime_id?: number;
runtime_entity_id?: number;
unique_id?: number;
unique_entity_id?: number;
entity_type?: string;
identifier?: string;
position?: IBedrockVec3;
rotation?: IBedrockVec3;
velocity?: IBedrockVec3;
metadata?: Record<string, unknown>;
}
export interface IAddPlayerPacket {
runtime_id?: number;
runtime_entity_id?: number;
unique_id?: number;
unique_entity_id?: number;
username?: string;
user_name?: string;
position?: IBedrockVec3;
rotation?: IBedrockVec3;
metadata?: Record<string, unknown>;
}
export interface IRemoveActorPacket {
runtime_entity_id?: number;
entity_id_self?: number;
}
export interface IMoveActorAbsolutePacket {
runtime_entity_id?: number;
runtime_id?: number;
position?: IBedrockVec3;
rotation?: IBedrockVec3;
rotation_x?: number;
rotation_y?: number;
rotation_y_head?: number;
}
export interface IMovePlayerPacket {
runtime_id?: number;
runtime_entity_id?: number;
position?: IBedrockVec3;
rotation?: IBedrockVec3;
pitch?: number;
yaw?: number;
head_yaw?: number;
}
export interface ISetActorMotionPacket {
runtime_entity_id?: number;
runtime_id?: number;
velocity?: IBedrockVec3;
}
export interface ISetActorDataPacket {
runtime_entity_id?: number;
runtime_id?: number;
metadata?: Record<string, unknown>;
}
export interface IMoveEntityDeltaPacket {
runtime_entity_id?: number;
runtime_id?: number;
x?: number;
y?: number;
z?: number;
rot_x?: number;
rot_y?: number;
rot_y_head?: number;
}
export interface IEntityState {
runtimeId: number;
uniqueId?: number;
typeId: string;
displayName?: string;
position: {
x: number;
y: number;
z: number;
};
prevPosition: {
x: number;
y: number;
z: number;
};
rotation: {
x: number;
y: number;
z: number;
};
prevRotation: {
x: number;
y: number;
z: number;
};
velocity: {
x: number;
y: number;
z: number;
};
isPlayer: boolean;
username?: string;
health?: number;
metadata?: Record<string, any>;
lastUpdateTime: number;
interpolationAlpha: number;
}
export default class EntityManager {
private _entities;
private _playerEntities;
private _localPlayerRuntimeId;
get entities(): Map<number, IEntityState>;
get entityCount(): number;
getEntityByRuntimeId(runtimeId: number): IEntityState | undefined;
get localPlayerRuntimeId(): number | undefined;
setLocalPlayerRuntimeId(id: number): void;
/**
* Find the closest entity within the player's look direction (for attacking).
* Uses a simple sphere check + dot product test rather than full AABB raycast.
* Returns the entity's runtime ID or undefined if none found.
*/
findEntityInLookDirection(eyePos: {
x: number;
y: number;
z: number;
}, lookDir: {
x: number;
y: number;
z: number;
}, maxDist?: number): number | undefined;
/**
* Handle add_actor packet — a non-player entity spawns.
*/
handleAddActor(packet: IAddActorPacket): void;
/**
* Handle add_player packet — another player spawns.
*/
handleAddPlayer(packet: IAddPlayerPacket): void;
/**
* Handle remove_entity packet.
* Note: remove_entity uses entity_id_self which is the UNIQUE entity ID (zigzag64),
* not the runtime ID. We need to search by uniqueId since our Map is keyed by runtimeId.
*/
handleRemoveActor(packet: IRemoveActorPacket): void;
/**
* Handle move_actor_absolute packet.
*/
handleMoveActorAbsolute(packet: IMoveActorAbsolutePacket): void;
/**
* Handle move_player packet.
*/
handleMovePlayer(packet: IMovePlayerPacket): void;
/**
* Handle set_actor_motion packet.
*/
handleSetActorMotion(packet: ISetActorMotionPacket): void;
/**
* Handle set_actor_data packet (entity metadata flags).
*/
handleSetActorData(packet: ISetActorDataPacket): void;
/**
* Handle move_entity_delta packet (incremental entity movement).
* This is the most frequent entity movement packet — applies deltas to current position/rotation.
*/
handleMoveEntityDelta(packet: IMoveEntityDeltaPacket): void;
/**
* Update interpolation for all entities. Call every render frame.
* @param deltaMs Milliseconds since last frame
*/
updateInterpolation(deltaMs: number): void;
/**
* Get interpolated position for an entity.
*/
getInterpolatedPosition(runtimeId: number): {
x: number;
y: number;
z: number;
} | undefined;
/**
* Get interpolated rotation for an entity.
*/
getInterpolatedRotation(runtimeId: number): {
x: number;
y: number;
z: number;
} | undefined;
/**
* Get all entities as an array.
*/
getAllEntities(): IEntityState[];
/**
* Clear all entities (dimension change).
*/
clear(): void;
private _extractPosition;
private _extractRotation;
private _lerpAngle;
}