UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

222 lines (221 loc) 6.15 kB
/** * 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; }