hytopia
Version:
The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.
1,429 lines (1,307 loc) • 225 kB
TypeScript
import type { AnyPacket } from '@hytopia.com/server-protocol';
import type { ErrorEvent as ErrorEvent_2 } from 'ws';
import EventEmitter from 'eventemitter3';
import http from 'http';
import type { IncomingMessage } from 'http';
import type { InputSchema } from '@hytopia.com/server-protocol';
import type { LobbyMembershipDto } from '@hytopia.com/creative-lib/dist/impl/getSession';
import mediasoup from 'mediasoup';
import protocol from '@hytopia.com/server-protocol';
import RAPIER from '@dimforge/rapier3d-simd-compat';
import { SdpMatrix3 } from '@dimforge/rapier3d-simd-compat';
import type { Socket } from 'net';
import { WebSocket as WebSocket_2 } from 'ws';
/**
* Represents a audio playback in a world.
*
* @remarks
* Audio instances are created directly as instances.
* They support a variety of configuration options through
* the {@link AudioOptions} constructor argument.
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link AudioEventPayloads}
*
* @example
* ```typescript
* (new Audio({
* uri: 'music/song.mp3', // relative to the server's assets directory in the project root, resolves to assets/music/song.mp3
* loop: true,
* volume: 0.5,
* })).play(world);
* ```
*
* @eventProperty
*
* @public
*/
export declare class Audio extends EventRouter implements protocol.Serializable {
/**
* @param options - The options for the Audio instance.
*/
constructor(options: AudioOptions);
/** The unique identifier for the audio. */
get id(): number | undefined;
/** The entity to which the audio is attached if explicitly set. */
get attachedToEntity(): Entity | undefined;
/** The cutoff distance where the audio will be reduced to 0 volume. */
get cutoffDistance(): number;
/** The duration of the audio in seconds if explicitly set. */
get duration(): number | undefined;
/** The detune of the audio in cents if explicitly set. */
get detune(): number | undefined;
/** The amount of distortion to apply to the audio if explicitly set. */
get distortion(): number | undefined;
/** Whether the audio is looped. */
get loop(): boolean;
/** The offset time in seconds from which the audio should start playing if explicitly set. */
get offset(): number | undefined;
/** Whether the audio has loaded into the world. Audio is loaded the first time play() is called. */
get isLoaded(): boolean;
/** Whether the audio is currently playing. */
get isPlaying(): boolean;
/** Whether the audio is positional (Entity or position attached). */
get isPositional(): boolean;
/** The position of the audio in the world if explicitly set. */
get position(): Vector3Like | undefined;
/** The playback rate of the audio if explicitly set. */
get playbackRate(): number | undefined;
/** The reference distance of the audio if explicitly set. */
get referenceDistance(): number;
/** The server tick at which the audio started playing. */
get startTick(): number | undefined;
/** The URI of the audio asset. */
get uri(): string;
/** The volume of the audio if explicitly set. */
get volume(): number | undefined;
/** The world the audio is in if already loaded. */
get world(): World | undefined;
/**
* Plays or resumes the audio.
*
* @param world - The world to play the audio in.
* @param restart - If true, the audio will restart from the beginning if it is already playing.
*/
play(world: World, restart?: boolean): void;
/**
* Pauses the audio.
*/
pause(): void;
/**
* Sets the entity to which the audio is attached, following its position.
*
* @param entity - The entity to attach the Audio to.
*/
setAttachedToEntity(entity: Entity): void;
/**
* Sets the cutoff distance of the audio.
*
* @remarks
* The cutoff distance defines the maximum range at which the audio can be heard.
* Beyond this distance, the audio volume becomes zero. As the listener moves
* from the reference distance toward the cutoff distance, the volume decreases
* linearly, providing a natural spatial audio experience with smooth volume
* falloff based on distance.
*
* @param cutoffDistance - The cutoff distance.
*/
setCutoffDistance(cutoffDistance: number): void;
/**
* Sets the detune of the audio.
*
* @param detune - The detune in cents.
*/
setDetune(detune: number): void;
/**
* Sets the distortion of the audio.
*
* @param distortion - The distortion amount.
*/
setDistortion(distortion: number): void;
/**
* Sets the position of the audio. Will detach from entity if attached.
*
* @param position - The position in the world.
*/
setPosition(position: Vector3Like): void;
/**
* Sets the playback rate of the audio.
*
* @param playbackRate - The playback rate.
*/
setPlaybackRate(playbackRate: number): void;
/**
* Sets the reference distance of the audio.
*
* @remarks
* The reference distance defines the range within which the audio plays at
* full volume. When a listener is within this distance from the audio source,
* they will hear the sound at its maximum volume. Beyond this distance, the
* volume decreases linearly until reaching the cutoff distance, where the
* sound becomes inaudible. This creates a natural spatial audio experience
* with smooth volume falloff based on distance.
*
* @param referenceDistance - The reference distance.
*/
setReferenceDistance(referenceDistance: number): void;
/**
* Sets the volume of the audio.
*
* @param volume - The volume level.
*/
setVolume(volume: number): void;
}
/** Event types an Audio instance can emit. See {@link AudioEventPayloads} for the payloads. @public */
export declare enum AudioEvent {
PAUSE = "AUDIO.PAUSE",
PLAY = "AUDIO.PLAY",
PLAY_RESTART = "AUDIO.PLAY_RESTART",
SET_ATTACHED_TO_ENTITY = "AUDIO.SET_ATTACHED_TO_ENTITY",
SET_CUTOFF_DISTANCE = "AUDIO.SET_CUTOFF_DISTANCE",
SET_DETUNE = "AUDIO.SET_DETUNE",
SET_DISTORTION = "AUDIO.SET_DISTORTION",
SET_POSITION = "AUDIO.SET_POSITION",
SET_PLAYBACK_RATE = "AUDIO.SET_PLAYBACK_RATE",
SET_REFERENCE_DISTANCE = "AUDIO.SET_REFERENCE_DISTANCE",
SET_VOLUME = "AUDIO.SET_VOLUME"
}
/** Event payloads for Audio emitted events. @public */
export declare interface AudioEventPayloads {
/** Emitted when the audio is paused. */
[AudioEvent.PAUSE]: {
audio: Audio;
};
/** Emitted when the audio is played. */
[AudioEvent.PLAY]: {
audio: Audio;
};
/** Emitted when the audio is restarted. */
[AudioEvent.PLAY_RESTART]: {
audio: Audio;
};
/** Emitted when the audio is attached to an entity. */
[AudioEvent.SET_ATTACHED_TO_ENTITY]: {
audio: Audio;
entity: Entity | undefined;
};
/** Emitted when the audio's cutoff distance is set. */
[AudioEvent.SET_CUTOFF_DISTANCE]: {
audio: Audio;
cutoffDistance: number;
};
/** Emitted when the audio's detune is set. */
[AudioEvent.SET_DETUNE]: {
audio: Audio;
detune: number;
};
/** Emitted when the audio's distortion is set. */
[AudioEvent.SET_DISTORTION]: {
audio: Audio;
distortion: number;
};
/** Emitted when the audio's position is set. */
[AudioEvent.SET_POSITION]: {
audio: Audio;
position: Vector3Like;
};
/** Emitted when the audio's playback rate is set. */
[AudioEvent.SET_PLAYBACK_RATE]: {
audio: Audio;
playbackRate: number;
};
/** Emitted when the audio's reference distance is set. */
[AudioEvent.SET_REFERENCE_DISTANCE]: {
audio: Audio;
referenceDistance: number;
};
/** Emitted when the audio's volume is set. */
[AudioEvent.SET_VOLUME]: {
audio: Audio;
volume: number;
};
}
/**
* Manages audio instances in a world.
*
* @remarks
* The AudioManager is created internally as a singleton
* for each {@link World} instance in a game server.
* It allows retrieval of all loaded audio, entity
* attached audio, looped audio, and more.
*
* @example
* ```typescript
* // Stop all audio in the world
* const audioManager = world.audioManager;
* audioManager.getAllAudios().map(audio => audio.pause());
* ```
*
* @public
*/
export declare class AudioManager {
/** The world the audio manager is for. */
get world(): World;
/**
* Retrieves all loaded audio instances for the world.
*
* @returns An array of audio instances.
*/
getAllAudios(): Audio[];
/**
* Retrieves all loaded audio instances attached to a specific entity.
*
* @param entity - The entity to get attached audio instances for.
* @returns An array of audio instances.
*/
getAllEntityAttachedAudios(entity: Entity): Audio[];
/**
* Retrieves all looped audio instances for the world.
*
* @returns An array of audio instances.
*/
getAllLoopedAudios(): Audio[];
/**
* Retrieves all oneshot (non-looped) audio instances for the world.
*
* @returns An array of audio instances.
*/
getAllOneshotAudios(): Audio[];
/**
* Unregisters and stops an audio instance from the audio manager.
*
* @param audio - The audio instance to pause and unregister.
*/
unregisterAudio(audio: Audio): void;
/**
* Unregisters and stops all audio instances attached to a specific entity.
*
* @param entity - The entity to pause and unregister audio instances for.
*/
unregisterEntityAttachedAudios(entity: Entity): void;
}
/** Options for creating an Audio instance. @public */
export declare interface AudioOptions {
/** If set, audio playback will follow the entity's position. */
attachedToEntity?: Entity;
/** The cutoff distance between the audio source and the listener where the audio will be reduced to 0 volume. Must be greater than reference distance. Defaults to reference distance + 10. */
cutoffDistance?: number;
/** The duration of the audio in seconds. Defaults to full duration. */
duration?: number;
/** The detuning of the audio in cents. */
detune?: number;
/** The amount of distortion to apply to the audio. */
distortion?: number;
/** Whether the audio should loop when it reaches the end. Defaults to false. */
loop?: boolean;
/** The offset time in seconds from which the audio should start playing. */
offset?: number;
/** The position in the world where the audio is played. */
position?: Vector3Like;
/** The playback speed of the audio. Defaults to 1. */
playbackRate?: number;
/** The maximum reference distance between the audio source and the listener where the audio will still be max volume. Defaults to 10. */
referenceDistance?: number;
/** The URI or path to the audio asset to be played. */
uri: string;
/** The volume level of the audio. Defaults to 0.5. */
volume?: number;
}
/** The options for a ball collider. @public */
export declare interface BallColliderOptions extends BaseColliderOptions {
shape: ColliderShape.BALL;
/** The radius of the ball collider. */
radius?: number;
}
/** The base options for a collider. @public */
export declare interface BaseColliderOptions {
/** The shape of the collider. */
shape: ColliderShape;
/** The bounciness of the collider. */
bounciness?: number;
/** The bounciness combine rule of the collider. */
bouncinessCombineRule?: CoefficientCombineRule;
/** The collision groups the collider belongs to. */
collisionGroups?: CollisionGroups;
/** Whether the collider is enabled. */
enabled?: boolean;
/** The flags of the collider if the shape is a trimesh */
flags?: number;
/** The friction of the collider. */
friction?: number;
/** The friction combine rule of the collider. */
frictionCombineRule?: CoefficientCombineRule;
/** Whether the collider is a sensor. */
isSensor?: boolean;
/** The mass of the collider. */
mass?: number;
/** The on collision callback for the collider. */
onCollision?: CollisionCallback;
/** The parent rigid body of the collider. */
parentRigidBody?: RigidBody;
/** The relative position of the collider. Relative to parent rigid body. */
relativePosition?: Vector3Like;
/** The relative rotation of the collider. Relative to parent rigid body. */
relativeRotation?: QuaternionLike;
/** The simulation the collider is in, if provided the collider will automatically be added to the simulation. */
simulation?: Simulation;
/** An arbitrary identifier tag of the collider. Useful for your own logic. */
tag?: string;
}
/**
* A base class for entity controller implementations.
*
* @remarks
* The BaseEntityController should be extended
* by a more specific entity controller that you or a
* plugin implements. Entity controllers are intended to
* be used as one controller instance per entity, but
* are flexible enough for edge cases such as if you want to create
* niche behavior of one controller for many entities that
* behave in unison.
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link BaseEntityControllerEventPayloads}
*
* @public
*/
export declare abstract class BaseEntityController extends EventRouter {
/**
* Override this method to handle the attachment of an entity
* to your entity controller.
* @param entity - The entity to attach the controller to.
*/
attach(entity: Entity): void;
/**
* Override this method to handle the despawn of an entity
* from your entity controller.
* @param entity - The entity to despawn.
*/
despawn(entity: Entity): void;
/**
* Override this method to handle the detachment of an entity
* from your entity controller.
* @param entity - The entity to detach.
*/
detach(entity: Entity): void;
/**
* Override this method to handle the spawning of an entity
* to your entity controller.
* @param entity - The entity to spawn.
*/
spawn(entity: Entity): void;
/**
* Override this method to handle entity movements
* based on player input for your entity controller.
* This is called every tick by a PlayerEntity with a
* entity controller.
* @param entity - The entity to tick.
* @param input - The current input state of the player.
* @param cameraOrientation - The current camera orientation state of the player.
* @param deltaTimeMs - The delta time in milliseconds since the last tick.
*/
tickWithPlayerInput(entity: PlayerEntity, input: PlayerInput, cameraOrientation: PlayerCameraOrientation, deltaTimeMs: number): void;
/**
* Override this method to handle entity movements
* based on your entity controller.
* @param deltaTimeMs - The delta time in milliseconds since the last tick.
*/
tick(entity: Entity, deltaTimeMs: number): void;
}
/** Event types a BaseEntityController instance can emit. See {@link BaseEntityControllerEventPayloads} for the payloads. @public */
export declare enum BaseEntityControllerEvent {
ATTACH = "BASE_ENTITY_CONTROLLER.ATTACH",
DESPAWN = "BASE_ENTITY_CONTROLLER.DESPAWN",
DETACH = "BASE_ENTITY_CONTROLLER.DETACH",
SPAWN = "BASE_ENTITY_CONTROLLER.SPAWN",
TICK = "BASE_ENTITY_CONTROLLER.TICK",
TICK_WITH_PLAYER_INPUT = "BASE_ENTITY_CONTROLLER.TICK_WITH_PLAYER_INPUT"
}
/** Event payloads for BaseEntityController emitted events. @public */
export declare interface BaseEntityControllerEventPayloads {
/** Emitted when an entity is attached to the controller. */
[BaseEntityControllerEvent.ATTACH]: {
entity: Entity;
};
/** Emitted when an entity is despawned. */
[BaseEntityControllerEvent.DESPAWN]: {
entity: Entity;
};
/** Emitted when an entity is detached from the controller. */
[BaseEntityControllerEvent.DETACH]: {
entity: Entity;
};
/** Emitted when an entity is spawned. */
[BaseEntityControllerEvent.SPAWN]: {
entity: Entity;
};
/** Emitted when an entity is ticked. */
[BaseEntityControllerEvent.TICK]: {
entity: Entity;
deltaTimeMs: number;
};
/** Emitted when an entity is ticked with player input. */
[BaseEntityControllerEvent.TICK_WITH_PLAYER_INPUT]: {
entity: PlayerEntity;
input: PlayerInput;
cameraOrientation: PlayerCameraOrientation;
deltaTimeMs: number;
};
}
/** The base options for an entity. @public */
export declare interface BaseEntityOptions {
/** The entity controller to use for the entity. */
controller?: BaseEntityController;
/** The opacity of the entity between 0 and 1. 0 is fully transparent, 1 is fully opaque. */
opacity?: number;
/** Whether the entity is environmental, if true it will not invoke its tick function or change position. Defaults to false. */
isEnvironmental?: boolean;
/** The parent entity of the entity, entities with a parent will ignore creating their own colliders. */
parent?: Entity;
/** The name of the parent's node (if parent is a model entity) to attach the entity to. */
parentNodeName?: string;
/** The rigid body options for the entity. */
rigidBodyOptions?: RigidBodyOptions;
/** An arbitrary identifier tag of the entity. Useful for your own logic. */
tag?: string;
/** The tint color of the entity as a hex code. */
tintColor?: RgbColor;
/** The name of the entity. */
name?: string;
}
/** The base options for a rigid body. @public */
export declare interface BaseRigidBodyOptions {
/** The type of the rigid body, defaults to {@link RigidBodyType.DYNAMIC}. */
type?: RigidBodyType;
/** The colliders of the rigid body, provided as {@link ColliderOptions}. */
colliders?: ColliderOptions[];
/** Whether the rigid body is enabled. */
enabled?: boolean;
/** The position of the rigid body. */
position?: Vector3Like;
/** The rotation of the rigid body. */
rotation?: QuaternionLike;
/** The simulation the rigid body is in. If provided, the rigid body will be automatically added to the simulation. */
simulation?: Simulation;
}
/**
* Represents a block in a world.
*
* @remarks
* Instances of this class are created internally but made
* publicly available through various public facing API
* methods.
*
* @public
*/
export declare class Block {
/** The global coordinate of the block. */
readonly globalCoordinate: Vector3Like;
/** The block type of the block. */
readonly blockType: BlockType;
/**
* Gets the most adjacent neighbor global coordinate of this block
* based on a relative hit point, typically from a raycast.
*
* @param hitPoint - The hit point on this block to get the neighbor coordinate from.
* @returns A neighbor global coordinate of this block based on the hit point.
*/
getNeighborGlobalCoordinateFromHitPoint(hitPoint: Vector3Like): Vector3Like;
}
/** The options for a block collider. @public */
export declare interface BlockColliderOptions extends BaseColliderOptions {
shape: ColliderShape.BLOCK;
/** The half extents of the block collider. */
halfExtents?: Vector3Like;
}
/** The options for creating a block entity. @public */
export declare interface BlockEntityOptions extends BaseEntityOptions {
/** The half extents of the visual size of the block entity when blockTextureUri is set. If no rigidBodyOptions.colliders are provided, a block collider with the size of the half extents will be created. */
blockHalfExtents?: Vector3Like;
/** The texture uri of a entity if the entity is a block entity, if set rigidBodyOptions collider shape [0] must be a block */
blockTextureUri?: string;
}
/**
* Represents a block type.
*
* @remarks
* Block types are created directly as instances.
* They support a variety of configuration options through
* the {@link BlockTypeOptions} constructor argument.
* Block types are registered with a {@link BlockTypeRegistry} instance,
* allowing you to create custom blocks with unique visual representations
* and behaviors.
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link BlockTypeEventPayloads}
*
* @example
* ```typescript
* const stoneBlockTypeId = 10;
* world.blockTypeRegistry.registerBlockType(stoneBlockTypeId, new BlockType({
* id: stoneBlockTypeId,
* textureUri: 'textures/stone.png',
* name: 'Stone',
* }));
*
* // Create a stone block at coordinate 0, 1, 0
* world.chunkLattice.setBlock({ x: 0, y: 1, z: 0 }, stoneBlockTypeId);
* ```
*
* @public
*/
export declare class BlockType extends EventRouter implements protocol.Serializable {
/**
* Creates a new block type instance.
* @param world - The world the block type is for.
* @param options - The options for the block type.
*/
constructor(options?: BlockTypeOptions);
/** The unique identifier for the block type. */
get id(): number;
/** The collider options for the block type. */
get colliderOptions(): TrimeshColliderOptions;
/** Whether the block type is a liquid. */
get isLiquid(): boolean;
/** Whether the block type is meshable. */
get isMeshable(): boolean;
/** The name of the block type. */
get name(): string;
/** The URI of the texture for the block type. */
get textureUri(): string;
}
/** Event types a BlockType instance can emit. See {@link BlockTypeEventPayloads} for the payloads. @public */
export declare enum BlockTypeEvent {
ENTITY_COLLISION = "BLOCK_TYPE.ENTITY_COLLISION",
ENTITY_CONTACT_FORCE = "BLOCK_TYPE.ENTITY_CONTACT_FORCE"
}
/** Event payloads for BlockType emitted events. @public */
export declare interface BlockTypeEventPayloads {
/** Emitted when an entity collides with a block type. */
[BlockTypeEvent.ENTITY_COLLISION]: {
blockType: BlockType;
entity: Entity;
started: boolean;
colliderHandleA: number;
colliderHandleB: number;
};
/** Emitted when an entity's contact force is applied to a block type. */
[BlockTypeEvent.ENTITY_CONTACT_FORCE]: {
blockType: BlockType;
entity: Entity;
contactForceData: ContactForceData;
};
}
/** Options for creating a block type instance. @public */
export declare interface BlockTypeOptions {
/** The unique numeric identifier for the block type. */
id: number;
/** The custom collider options for the block type. */
customColliderOptions?: TrimeshColliderOptions;
/** Whether the block type is a liquid. */
isLiquid?: boolean;
/** The name of the block type. */
name: string;
/** The URI of the texture asset for the block type. */
textureUri: string;
}
/**
* Manages known block types in a world.
*
* @remarks
* Block type registries are created internally as a singleton
* for each {@link World} instance in a game server. A block
* type registry allows you to register and retrieve block
* types by their unique id for a world.
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link BlockTypeRegistryEventPayloads}
*
* @example
* ```typescript
* world.blockTypeRegistry.registerGenericBlockType({
* id: 15,
* textureUri: 'textures/dirt.png',
* name: 'Dirt',
* });
* ```
*
* @public
*/
export declare class BlockTypeRegistry extends EventRouter implements protocol.Serializable {
/** The world the block type registry is for. */
get world(): World;
/**
* Get all registered block types.
* @returns An array of all registered block types.
*/
getAllBlockTypes(): BlockType[];
/**
* Get a registered block type by its id.
* @param id - The id of the block type to get.
* @returns The block type with the given id.
*/
getBlockType(id: number): BlockType;
/**
* Register a generic block type.
* @param blockTypeOptions - The options for the block type.
* @returns The registered block type.
*/
registerGenericBlockType(blockTypeOptions: BlockTypeOptions): BlockType;
/**
* Register a block type.
* @param blockType - The block type to register.
*/
registerBlockType(blockType: BlockType): void;
}
/** Event types a BlockTypeRegistry instance can emit. See {@link BlockTypeRegistryEventPayloads} for the payloads. @public */
export declare enum BlockTypeRegistryEvent {
REGISTER_BLOCK_TYPE = "BLOCK_TYPE_REGISTRY.REGISTER_BLOCK_TYPE"
}
/** Event payloads for BlockTypeRegistry emitted events. @public */
export declare interface BlockTypeRegistryEventPayloads {
/** Emitted when a block type is registered. */
[BlockTypeRegistryEvent.REGISTER_BLOCK_TYPE]: {
blockTypeRegistry: BlockTypeRegistry;
id: number;
blockType: BlockType;
};
}
/** The options for a capsule collider. @public */
export declare interface CapsuleColliderOptions extends BaseColliderOptions {
shape: ColliderShape.CAPSULE;
/** The half height of the capsule collider. */
halfHeight?: number;
/** The radius of the capsule collider. */
radius?: number;
}
/** Event types a ChatManager instance can emit. See {@link ChatEventPayloads} for the payloads. @public */
export declare enum ChatEvent {
BROADCAST_MESSAGE = "CHAT.BROADCAST_MESSAGE",
PLAYER_MESSAGE = "CHAT.PLAYER_MESSAGE"
}
/** Event payloads for ChatManager emitted events. @public */
export declare interface ChatEventPayloads {
/** Emitted when a broadcast message is sent. */
[ChatEvent.BROADCAST_MESSAGE]: {
player: Player | undefined;
message: string;
color?: string;
};
/** Emitted when a message is sent to a specific player. */
[ChatEvent.PLAYER_MESSAGE]: {
player: Player;
message: string;
color?: string;
};
}
/**
* Manages chat and commands in a world.
*
* @remarks
* The ChatManager is created internally as a singleton
* for each {@link World} instance in a game server.
* The ChatManager allows you to broadcast messages,
* send messages to specific players, and register
* commands that can be used in chat to execute game
* logic.
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link ChatEventPayloads}
*
* @example
* ```typescript
* world.chatManager.registerCommand('/kick', (player, args, message) => {
* const admins = [ 'arkdev', 'testuser123' ];
* if (admins.includes(player.username)) {
* const targetUsername = args[0];
* const targetPlayer = world.playerManager.getConnectedPlayerByUsername(targetUsername);
*
* if (targetPlayer) {
* targetPlayer.disconnect();
* }
* }
* });
* ```
*
* @public
*/
export declare class ChatManager extends EventRouter {
/**
* Register a command and its callback.
* @param command - The command to register.
* @param callback - The callback function to execute when the command is used.
*/
registerCommand(command: string, callback: CommandCallback): void;
/**
* Unregister a command.
* @param command - The command to unregister.
*/
unregisterCommand(command: string): void;
/**
* Send a system broadcast message to all players in the world.
* @param message - The message to send.
* @param color - The color of the message as a hex color code, excluding #.
*
* @example
* ```typescript
* chatManager.sendBroadcastMessage('Hello, world!', 'FF00AA');
* ```
*/
sendBroadcastMessage(message: string, color?: string): void;
/**
* Send a system message to a specific player, only visible to them.
* @param player - The player to send the message to.
* @param message - The message to send.
* @param color - The color of the message as a hex color code, excluding #.
*
* @example
* ```typescript
* chatManager.sendPlayerMessage(player, 'Hello, player!', 'FF00AA');
* ```
*/
sendPlayerMessage(player: Player, message: string, color?: string): void;
}
/**
* A 16^3 chunk of blocks. Used to represent a world's terrain.
*
* @remarks
* Chunks make up the bulk of the terrain in a world. Chunks are
* fixed size, each containing 16^3 possible blocks as
* a 16x16x16 cube. Chunks can be spawned, despawned, have their
* unique blocks set or removed, and more. Chunks represent their
* internal block coordinates in local space, meaning only coordinates
* x: 0...15, y: 0...15, z: 0...15 are valid.
*
* The Chunk follows a spawn and despawn lifecycle pattern.
* When you create a chunk, when you're ready to load it in your
* world you use .spawn(). To remove it, you use .despawn().
*
* Use .setBlock() to set the block type id at a specific local cooridnate.
* Block type ids are ones that have been registered in the {@link BlockTypeRegistry}
* associated with the {@link World} the chunk belongs to. A block type id of 0
* is used to represent no block. Removing a block is done by .setBlock(localCoordinate, 0).
*
* <h2>Events</h2>
*
* This class is an EventRouter, and instances of it emit
* events with payloads listed under {@link ChunkEventPayloads}
*
* @example
* ```typescript
* // Assume we previously registered a stone block with type id of 10..
*
* const chunk = new Chunk();
*
* chunk.setBlock({ x: 0, y: 0, z: 0 }, 10); // Set the block at 0, 0, 0 to stone
* chunk.spawn(world, { x: 16, y: 0, z: 16 }); // Spawn the chunk at global coordinate 16, 0, 16
* ```
*
* @public
*/
export declare class Chunk extends EventRouter implements protocol.Serializable {
/**
* Creates a new chunk instance.
*/
constructor();
/** The blocks in the chunk as a flat Uint8Array[4096], each index as 0 or a block type id. */
get blocks(): Readonly<Uint8Array>;
/** Whether the chunk is actively simulated in the internal physics engine. */
get isSimulated(): boolean;
/** Whether the chunk has been spawned. */
get isSpawned(): boolean;
/** The origin coordinate of the chunk. */
get originCoordinate(): Vector3Like | undefined;
/** The world the chunk belongs to. */
get world(): World | undefined;
/**
* Convert a block index to a local coordinate.
* @param index - The index of the block to convert.
* @returns The local coordinate of the block.
*/
static blockIndexToLocalCoordinate(index: number): Vector3Like;
/**
* Convert a global coordinate to a local coordinate.
* @param globalCoordinate - The global coordinate to convert.
* @returns The local coordinate.
*/
static globalCoordinateToLocalCoordinate(globalCoordinate: Vector3Like): Vector3Like;
/**
* Convert a global coordinate to an origin coordinate.
* @param globalCoordinate - The global coordinate to convert.
* @returns The origin coordinate.
*/
static globalCoordinateToOriginCoordinate(globalCoordinate: Vector3Like): Vector3Like;
/**
* Check if an origin coordinate is valid.
* @param coordinate - The coordinate to check.
* @returns Whether the coordinate is valid.
*/
static isValidOriginCoordinate(coordinate: Vector3Like): boolean;
/**
* Spawn the chunk in the world.
* @param world - The world to spawn the chunk in.
* @param originCoordinate - The origin coordinate of the chunk.
*/
spawn(world: World, originCoordinate: Vector3Like): void;
/**
* Despawn the chunk from the world.
*/
despawn(): void;
/**
* Get the block type id at a specific local coordinate.
* @param localCoordinate - The local coordinate of the block to get.
* @returns The block type id.
*/
getBlockId(localCoordinate: Vector3Like): number;
/**
* Check if a block exists at a specific local coordinate.
* @param localCoordinate - The local coordinate of the block to check.
* @returns Whether a block exists.
*/
hasBlock(localCoordinate: Vector3Like): boolean;
/**
* Set the block at a specific local coordinate by block type id.
* @param localCoordinate - The local coordinate of the block to set.
* @param blockTypeId - The block type id to set.
*/
setBlock(localCoordinate: Vector3Like, blockTypeId: number): void;
private _meshColliders;
}
/** Event types a Chunk instance can emit. See {@link ChunkEventPayloads} for the payloads. @public */
export declare enum ChunkEvent {
DESPAWN = "CHUNK.DESPAWN",
SET_BLOCK = "CHUNK.SET_BLOCK",
SPAWN = "CHUNK.SPAWN"
}
/** Event payloads for Chunk emitted events. @public */
export declare interface ChunkEventPayloads {
/** Emitted when a chunk is despawned. */
[ChunkEvent.DESPAWN]: {
chunk: Chunk;
};
/** Emitted when a block is set in a chunk. */
[ChunkEvent.SET_BLOCK]: {
chunk: Chunk;
globalCoordinate: Vector3Like;
localCoordinate: Vector3Like;
blockTypeId: number;
};
/** Emitted when a chunk is spawned. */
[ChunkEvent.SPAWN]: {
chunk: Chunk;
};
}
/**
* A lattice of chunks that represent a world's terrain.
*
* @remarks
* The ChunkLattice lattice tracks the current terrain of a world,
* comprised of {@link Chunk} instances.
*
* @public
*/
export declare class ChunkLattice {
/**
* Creates a new chunk lattice instance.
* @param world - The world the chunk lattice is for.
*/
constructor(world: World);
/** The number of chunks in the lattice. */
get chunkCount(): number;
/**
* Despawns and clears all chunks in the lattice.
*/
clear(): void;
/**
* Get the block type id at a specific global coordinate.
* @param globalCoordinate - The global coordinate of the block to get.
* @returns The block type id, 0 if no block is set.
*/
getBlockId(globalCoordinate: Vector3Like): number;
/**
* Get the block type at a specific global coordinate.
* @param globalCoordinate - The global coordinate of the block to get.
* @returns The block type, null if no block is set.
*/
getBlockType(globalCoordinate: Vector3Like): BlockType | null;
/**
* Get a chunk by its origin coordinate.
* @param originCoordinate - The origin coordinate of the chunk to get.
* @returns The chunk at the given origin coordinate or undefined if not found.
*/
getChunk(originCoordinate: Vector3Like): Chunk | undefined;
/**
* Get all chunks in the lattice.
* @returns An array of all chunks in the lattice.
*/
getAllChunks(): Chunk[];
/**
* Check if a block exists at a specific global coordinate.
* @param globalCoordinate - The global coordinate of the block to check.
* @returns Whether a block exists.
*/
hasBlock(globalCoordinate: Vector3Like): boolean;
/**
* Check if a chunk exists by its origin coordinate.
* @param originCoordinate - The origin coordinate of the chunk to check.
* @returns Whether the chunk exists.
*/
hasChunk(originCoordinate: Vector3Like): boolean;
/**
* Set the block at a global coordinate by block type id, automatically
* creating a chunk if it doesn't exist. Use block type id 0 for air.
* @param globalCoordinate - The global coordinate of the block to set.
* @param blockTypeId - The block type id to set. Use 0 to remove the block and replace with air.
*/
setBlock(globalCoordinate: Vector3Like, blockTypeId: number): void;
}
/** The coefficient for friction or bounciness combine rule. @public */
export declare enum CoefficientCombineRule {
Average = 0,
Min = 1,
Multiply = 2,
Max = 3
}
/**
* Represents a collider in a world's physics simulation.
*
* @remarks
* Colliders make up the foundation of the physical interactions
* in a world. They are highly configurable and have many
* aspects that can be adjusted both before simulation and
* while simulated. Colliders will most often be used through
* passing {@link ColliderOptions} to a {@link RigidBody} or
* an entity's {@link EntityOptions}.
*
* @public
*/
export declare class Collider extends EventRouter {
/**
* @param colliderOptions - The options for the collider instance.
*/
constructor(colliderOptions: ColliderOptions);
/**
* Creates a collider options object from a block's half extents.
* @param halfExtents - The half extents of the block.
* @returns The collider options object.
*/
static optionsFromBlockHalfExtents(halfExtents: Vector3Like): ColliderOptions;
/**
* Creates a collider options object from a modelUri with best approximate shape and size.
* @param modelUri - The URI of the model.
* @param scale - The scale of the model.
* @param preferredShape - The preferred shape to use for the collider.
* @returns The collider options object.
*/
static optionsFromModelUri(modelUri: string, scale?: number, preferredShape?: ColliderShape): ColliderOptions;
/** The bounciness of the collider. */
get bounciness(): number;
/** The bounciness combine rule of the collider. */
get bouncinessCombineRule(): CoefficientCombineRule;
/** The collision groups the collider belongs to. */
get collisionGroups(): CollisionGroups;
/** The friction of the collider. */
get friction(): number;
/** The friction combine rule of the collider. */
get frictionCombineRule(): CoefficientCombineRule;
/** Whether the collider is enabled. */
get isEnabled(): boolean;
/** Whether the collider has been removed from the simulation. */
get isRemoved(): boolean;
/** Whether the collider is a sensor. */
get isSensor(): boolean;
/** Whether the collider is simulated. */
get isSimulated(): boolean;
/** The parent rigid body of the collider. */
get parentRigidBody(): RigidBody | undefined;
/** The raw collider object from the Rapier physics engine. */
get rawCollider(): RawCollider | undefined;
/** The raw shape object from the Rapier physics engine. */
get rawShape(): RawShape | undefined;
/** The relative position of the collider to its parent rigid body. */
get relativePosition(): Vector3Like;
/** The relative rotation of the collider. */
get relativeRotation(): QuaternionLike;
/** The shape of the collider. */
get shape(): ColliderShape;
/** An arbitrary identifier tag of the collider. Useful for your own logic. */
get tag(): string | undefined;
/**
* Sets the bounciness of the collider.
* @param bounciness - The bounciness of the collider.
*/
setBounciness(bounciness: number): void;
/**
* Sets the bounciness combine rule of the collider.
* @param bouncinessCombineRule - The bounciness combine rule of the collider.
*/
setBouncinessCombineRule(bouncinessCombineRule: CoefficientCombineRule): void;
/**
* Sets the collision groups of the collider.
* @param collisionGroups - The collision groups of the collider.
*/
setCollisionGroups(collisionGroups: CollisionGroups): void;
/**
* Sets whether the collider is enabled.
* @param enabled - Whether the collider is enabled.
*/
setEnabled(enabled: boolean): void;
/**
* Sets the friction of the collider.
* @param friction - The friction of the collider.
*/
setFriction(friction: number): void;
/**
* Sets the friction combine rule of the collider.
* @param frictionCombineRule - The friction combine rule of the collider.
*/
setFrictionCombineRule(frictionCombineRule: CoefficientCombineRule): void;
/**
* Sets the mass of the collider.
* @param mass - The mass of the collider.
*/
setMass(mass: number): void;
/**
* Sets the on collision callback for the collider.
* @param callback - The on collision callback for the collider.
*/
setOnCollision(callback: CollisionCallback | undefined): void;
/**
* Sets the relative rotation of the collider to its parent rigid body or the world origin.
*
* @remarks
* Colliders can be added as a child of a rigid body, or to the world directly. This rotation
* is relative to the parent rigid body or the world origin.
*
* @param rotation - The relative rotation of the collider.
*/
setRelativeRotation(rotation: QuaternionLike): void;
/**
* Sets the position of the collider relative to its parent rigid body or the world origin.
*
* @remarks
* Colliders can be added as a child of a rigid body, or to the world directly. This position
* is relative to the parent rigid body or the world origin.
*
* @param position - The relative position of the collider.
*/
setRelativePosition(position: Vector3Like): void;
/**
* Sets whether the collider is a sensor.
* @param sensor - Whether the collider is a sensor.
*/
setSensor(sensor: boolean): void;
/**
* Sets the tag of the collider.
* @param tag - The tag of the collider.
*/
setTag(tag: string): void;
/**
* Adds the collider to the simulation.
* @param simulation - The simulation to add the collider to.
* @param parentRigidBody - The parent rigid body of the collider.
*/
addToSimulation(simulation: Simulation, parentRigidBody?: RigidBody): void;
/**
* Enables or disables collision events for the collider.
* This is automatically enabled if an on collision callback is set.
* @param enabled - Whether collision events are enabled.
*/
enableCollisionEvents(enabled: boolean): void;
/**
* Enables or disables contact force events for the collider.
* This is automatically enabled if an on contact force callback is set.
* @param enabled - Whether contact force events are enabled.
*/
enableContactForceEvents(enabled: boolean): void;
/**
* Removes the collider from the simulation.
*/
removeFromSimulation(): void;
private _buildWedgeConvexHullVertices;
}
/** The options for a collider. @public */
export declare type ColliderOptions = BallColliderOptions | BlockColliderOptions | CapsuleColliderOptions | ConeColliderOptions | CylinderColliderOptions | RoundCylinderColliderOptions | TrimeshColliderOptions | WedgeColliderOptions | NoneColliderOptions;
/** The shapes a collider can be. @public */
export declare enum ColliderShape {
NONE = "none",
BALL = "ball",
BLOCK = "block",
CAPSULE = "capsule",
CONE = "cone",
CYLINDER = "cylinder",
ROUND_CYLINDER = "round-cylinder",
TRIMESH = "trimesh",
WEDGE = "wedge"
}
/**
* A callback function that is called when a collision occurs.
* @param other - The other object involved in the collision, a block or entity.
* @param started - Whether the collision has started or ended.
* @public
*/
export declare type CollisionCallback = ((other: BlockType | Entity, started: boolean) => void) | ((other: BlockType | Entity, started: boolean, colliderHandleA: number, colliderHandleB: number) => void);
/**
* The default collision groups.
*
* @remarks
* The collision groups are used to determine which objects collide and
* generate collision and contact force events. The default collision groups
* can be used for most entity and block interactions, but you may want to
* create your own for more complex scenarios. Up to 15 collision groups can be
* registered. Collision groups use pairwise filtering using bit masks.
*
* This filtering method is based on two 16-bit values:
* - The belongsTo groups (the 16 left-most bits of `self.0`).
* - The collidesWith mask (the 16 right-most bits of `self.0`).
*
* An interaction is allowed between two filters `a` and `b` two conditions
* are met simultaneously:
* - The belongsTo groups of `a` has at least one bit set to `1` in common with the collidesWith mask of `b`.
* - The belongsTo groups of `b` has at least one bit set to `1` in common with the collidesWith mask of `a`.
* In other words, interactions are allowed between two filter if the following condition is met:
*
* ```
* ((a >> 16) & b) != 0 && ((b >> 16) & a) != 0
* ```
*
* @public
*/
export declare enum CollisionGroup {
BLOCK = 1,
ENTITY = 2,
ENTITY_SENSOR = 4,
ENVIRONMENT_ENTITY = 8,
PLAYER = 16,
GROUP_1 = 32,
GROUP_2 = 64,
GROUP_3 = 128,
GROUP_4 = 256,
GROUP_5 = 512,
GROUP_6 = 1024,
GROUP_7 = 2048,
GROUP_8 = 4096,
GROUP_9 = 8192,
GROUP_10 = 16384,
GROUP_11 = 32768,
ALL = 65535
}
/** A set of collision groups. @public */
export declare type CollisionGroups = {
belongsTo: CollisionGroup[];
collidesWith: CollisionGroup[];
};
/**
* A helper class for building and decoding collision groups.
*
* @remarks
* This class should be used directly with its static methods.
* You can assign collision groups to colliders of entities and
* blocks to control optimized collision interactions and filterings
* between blocks and entities, and entities and other entities.
*
* @public
*/
export declare class CollisionGroupsBuilder {
private static readonly BELONGS_TO_SHIFT;
private static readonly COLLIDES_WITH_MASK;
/**
* Builds a raw set of collision groups from a set of collision groups.
* @param collisionGroups - The set of collision groups to build.
* @returns A raw set of collision groups represented as a 32-bit number.
*/
static buildRawCollisionGroups(collisionGroups: CollisionGroups): RawCollisionGroups;
/**
* Decodes a raw set of collision groups into a set of collision groups.
* @param groups - The raw set of collision groups to decode.
* @returns A set of collision groups.
*/
static decodeRawCollisionGroups(groups: RawCollisionGroups): CollisionGroups;
/**
* Decodes a set of collision groups into a set of their string equivalents.
* @param collisionGroups - The set of collision groups to decode.
* @returns A set of collision groups represented as their string equivalents.
*/
static decodeCollisionGroups(collisionGroups: CollisionGroups): DecodedCollisionGroups;
/**
* Checks if the collision groups are the default collision groups.
* @param collisionGroups - The set of collision groups to check.
* @returns Whether the collision groups are the default collision groups.
*/
static isDefaultCollisionGroups(collisionGroups: CollisionGroups): boolean;
/**
* Combines an array of collision groups into a raw set of collision groups.
* @param groups - The array of collision groups to combine.
* @returns A raw set of collision groups represented as a 32-bit number.
*/
private static combineGroups;
}
/**
* A callback function for a chat command.
* @param player - The player that sent the command.
* @param args - An array of arguments, comprised of all space separated text after the command.
* @param message - The full message of the command.
* @public
*/
export declare type CommandCallback = (player: Player, args: string[], message: string) => void;
/** The options for a cone collider. @public */
export declare interface ConeColliderOptions extends BaseColliderOptions {
shape: ColliderShape.CONE;
/** The half height of the cone collider. */
halfHeight?: number;
/** The radius of the cone collider. */
radius?: number;
}
/** Data for contact forces. @public */
export declare type ContactForceData = {
/** The total force vector. */
totalForce: RAPIER.Vector;
/** The magnitude of the total force. */
totalForceMagnitude: number;
/** The direction of the maximum force. */
maxForceDirection: RAPIER.Vector;
/** The magnitude of the maximum force. */
maxForceMagnitude: number;
};
/** A contact manifold. @public */
export declare type ContactManifold = {
/** The contact points as global coordinates. */
contactPoints: Vector3Like[];
/** The local normal vector of the first collider. */
localNormalA: Vector3Like;
/** The local normal vector of the second collider. */
localNormalB: Vector3Like;
/** The normal vector of the contact. */
normal: Vector3Like;
};
/** The options for a cylinder collider. @public */
export declare interface CylinderColliderOptions extends BaseColliderOptions {
shape: ColliderShape.CYLINDER;
/** The half height of the cylinder collider. */
halfHeight?: number;
/** The radius of the cylinder collider. */
radius?: number;
}
/** A decoded set of collision groups represented as their string equivalents. @public */
export declare type DecodedCollisionGroups = {
belongsTo: string[];
collidesWith: string[];
};
/** The default rigid body options for a model entity when EntityOptions.rigidBodyOptions is not provided. @public */
export declare const DEFAULT_ENTITY_RIGID_BODY_OPTIONS: RigidBodyOptions;
/**
* Represents the default player model entity.
*
* @remarks
* The default player entity extends the {@link PlayerEntity} class,
*