vertecs
Version:
A typescript entity-component-system framework
1,337 lines (1,336 loc) • 43.7 kB
text/typescript
/// <reference types="OimoComponent.ts" />
/// <reference types="oimo.d.ts" />
/// <reference types="OimoSystem.ts" />
import { Camera, Object3D, Scene, WebGLRenderer, AnimationAction, AnimationClip, AnimationMixer, Light, InstancedMesh } from "three";
import { Vec3, Mat4, Mat4Like, Quat, QuatLike, Vec3Like } from "ts-gl-matrix";
import { WebSocket } from "ws";
// @ts-ignore
import { CSS3DObject } from "three/addons/renderers/CSS3DRenderer.js";
// @ts-ignore
import { BodyOptions, Body } from "oimo";
type SystemConstructor<T extends Component[]> = new (...args: any[]) => System<T>;
/**
* A system loops over all entities and uses the components of the entities to perform logic.
*/
declare abstract class System<T extends Component[] = [
]> {
#private;
protected ecsManager?: EcsManager;
readonly filter: ComponentClass<T[number]>[];
$dependencies: SystemConstructor<Component[]>[];
/**
* Create a new system with the given component group filter and the given tps
*/
protected constructor(filter: ComponentClass<T[number]>[], tps?: number, dependencies?: SystemConstructor<Component[]>[]);
/**
* Called every frame, you should not call this method directly but instead use the {@see onLoop} method
*/
loop(components: T[], entities: Entity[]): void;
start(ecsManager: EcsManager): Promise<void>;
stop(): Promise<void>;
sleep(milliseconds: number): void;
/**
* Called when the system is added to an ecs manager
* @param ecsManager
*/
onAddedToEcsManager(ecsManager: EcsManager): void;
/**
* Called when the system is added to an ecs manager
*/
initialize(): Promise<void>;
/**
* Called when the system is ready to start
*/
onStart(): Promise<void>;
/**
* Called when the system is stopped
*/
onStop(): Promise<void>;
/**
* Called whenever an entity becomes eligible to a system
* An entity becomes eligible when a component is added to an entity making it eligible to a group,
* or when a new system is added and an entity was already eligible to the new system's group
*/
onEntityEligible(entity: Entity, components: T): void;
/**
* Called when an entity becomes ineligible to a system, and before it is removed from the system
*/
onEntityNoLongerEligible(entity: Entity, components: T): void;
/**
* Called every frame
* @param components
* @param entities
* @param deltaTime The time since the last loop
*/
protected abstract onLoop(components: T[], entities: Entity[], deltaTime: number): void;
/**
* Return the time since the last update
* @private
*/
private getDeltaTime;
/**
* Return true if enough time has passed since the last update, false otherwise
*/
hasEnoughTimePassed(): boolean;
get dependencies(): SystemConstructor<Component[]>[];
get lastUpdateTime(): number;
set lastUpdateTime(value: number);
get loopTime(): number;
get tps(): number;
set tps(value: number);
get hasStarted(): boolean;
set hasStarted(value: boolean);
}
type EcsGroup = {
entities: Entity[];
components: Component[][];
systems: System<any>[];
};
type SystemConstructor$0<T extends System> = new (...args: any[]) => T;
/**
* The system manager is responsible for managing all the systems
*/
declare class EcsManager {
#private;
readonly ecsGroups: Map<ComponentClass[], EcsGroup>;
isStarted: boolean;
constructor();
/**
* Create a new entity and add it to this ecs manager
* @param options
*/
createEntity(options?: EntityOptions): Entity;
/**
* Add a system to the system manager
*/
addSystem(system: System<any>): Promise<void>;
removeSystem(SystemConstructor: SystemConstructor$0<any>): void;
/**
* The entry point of the ECS engine
*/
start(): Promise<void>;
stop(): Promise<void>;
/**
* Add multiple entities to the system manager
*/
addEntities(entities: Entity[]): void;
/**
* Add an entity to the system manager
*/
addEntity(newEntity: Entity): void;
removeEntity(entity: Entity): void;
destroyEntity(entityId: string): void;
/**
* Loop through all the systems and call their loop method, this method should not be called manually,
* see {@link start}
*/
loop(): void;
/**
* Check if an entity components is eligible to a group filter
*/
isEntityEligibleToGroup(group: ComponentClass[], entity: Entity): boolean;
/**
* Called after a component is added to an entity
* @param entity
* @param component
*/
onComponentAddedToEntity(entity: Entity, component: Component): void;
findSystem<T extends System<any>>(SystemConstructor: SystemConstructor$0<T>): T | undefined;
/**
* Called after a component is removed from an entity
* This method will check if the entity is still eligible to the groups and flag it for deletion if not
* @param entity
* @param component
*/
onComponentRemovedFromEntity(entity: Entity, component: Component): void;
get entities(): Entity[];
get loopTime(): number;
}
interface EntityOptions {
id?: string;
name?: string;
components?: Component[];
children?: Entity[];
ecsManager?: EcsManager;
parent?: Entity;
}
/**
* An entity is a general purpose object which contains components
*/
declare class Entity {
#private;
constructor(options?: EntityOptions);
/**
* Find an entity by it's id
* @param ecsManager
* @param id The entity id to find
*/
static findById(ecsManager: EcsManager, id: string): Entity | undefined;
/**
* Find an entity by a component
* @param ecsManager
* @param component The component class
*/
static findByComponent(ecsManager: EcsManager, component: ComponentClass): Entity | undefined;
/**
* Find an entity by a component
* @param ecsManager The ecs manager
* @param component The component class
*/
static findAllByComponent(ecsManager: EcsManager, component: ComponentClass): Entity[];
/**
* Find an entity by a tag
* @param ecsManager
* @param tag The tag
*/
static findAllByTag(ecsManager: EcsManager, tag: string): Entity[];
/**
* Return the first child found with the specified name
* @param name The child name
*/
findChildByName(name: string): Entity | undefined;
/**
* Find the first entity in the entity hierarchy with the specified component
* @param component
*/
findWithComponent(component: ComponentClass): Entity | undefined;
/**
* Return a component by its class
* @param componentClass The component's class or subclass constructor
*/
getComponent<T extends Component>(componentClass: ComponentClass<T>): T | undefined;
/**
* Return the first component found in an entity hierarchy
* @param componentConstructor The component's class or subclass constructor
*/
findComponent<T extends Component>(componentConstructor: ComponentClass<T>): T | undefined;
/**
* Return all components present in the entity
* @param filter
*/
getComponents<T extends Component>(filter?: ComponentClass<T>[]): (T | undefined)[];
/**
* Add a component to this entity
* @param newComponent The component to add
*/
addComponent(newComponent: Component): void;
addComponents(...newComponents: Component[]): void;
/**
* Add a child to this entity
* @param entity The child
*/
addChild(entity: Entity): void;
/**
* Add a tag to an entity
* @param tag The tag to add
*/
addTag(tag: string): void;
/**
* Remove a components from this entity
* @param componentClass The component's class to remove
*/
removeComponent<T extends Component>(componentClass: ComponentClass<T>): T | undefined;
/**
* Clone an entity's name, components, recursively
*/
clone(id?: string): Entity;
/**
* Destroy this entity, remove and destroy all added components
*/
destroy(): void;
get ecsManager(): EcsManager | undefined;
set ecsManager(value: EcsManager | undefined);
get tags(): string[];
get root(): Entity;
set root(value: Entity);
get components(): Component[];
get parent(): Entity | undefined;
set parent(entity: Entity | undefined);
get name(): string | undefined;
set name(value: string | undefined);
get children(): Entity[];
get id(): string;
}
type ComponentClass<T extends Component = any> = Function & {
prototype: T;
};
/**
* A component is a piece of data that is attached to an entity
*/
declare abstract class Component {
#private;
/**
* The entity this component is attached to
* @protected
*/
protected $entity?: Entity;
/**
* Create a new component
*/
protected constructor(id?: string);
/**
* Called when the component is added to the entity
*/
onAddedToEntity(entity: Entity): void;
/**
* Called when the component is removed from the entity
*/
onRemovedFromEntity(entity: Entity): void;
/**
* Called when the attached entity has a new parent
* This method is called before the parent is updated
* @param entity The new parent entity
*/
onEntityNewParent(entity?: Entity): void;
/**
* Called when another component is added to the attached entity
* @param component
*/
onComponentAddedToAttachedEntity(component: Component): void;
/**
* This method is called when the {@see destroy} method is called
*/
onDestroyed(): void;
/**
* Return a new clone of this component, by default, it returns the same component
*/
clone(): Component;
get id(): string;
get entity(): Entity | undefined;
set entity(value: Entity | undefined);
}
declare class PrefabManager {
#private;
private constructor();
static add(name: string, prefab: Entity): void;
static get(name: string, id?: string): Entity | undefined;
}
/**
* The json representation of a serialized component
*/
interface SerializedComponent<T> {
id?: string;
data: T;
className: string;
}
/**
* A serializable component is a component that can be serialized and deserialized,
* it is used to send components over network or to save them to a file for example
*/
declare abstract class SerializableComponent<T> extends Component {
protected constructor(options?: {
id?: string;
});
serialize(addMetadata?: boolean): SerializedComponent<T>;
deserialize(serializedComponent: SerializedComponent<T>): void;
/**
* Serialize the component's data into a json object that can be sent over the networking
*/
abstract write(): T;
/**
* Deserialize the json object, the data should come from a trusted source
* @param data
*/
abstract read(data: T): void;
}
type NetworkData = {
parent: string;
};
type NetworkScope = "public" | "private";
/**
* This component is used to mark an entity as networked, it is used by the network systems to determine which entities to send to which clients.
*/
declare class IsNetworked extends NetworkComponent<NetworkData> {
#private;
constructor(ownerId?: string, scope?: NetworkScope);
accept(data: NetworkData): boolean;
read(data: NetworkData): void;
write(): NetworkData;
isDirty(): boolean;
}
type SerializedNetworkComponent<T> = SerializedComponent<T> & {
updateTimestamp: number;
ownerId?: string;
scope?: NetworkScope;
};
/**
* A network component is a component that is used to synchronize data over the network.
* Components that inherit from this class will be synchronized over the network if they are attached to a networked entity.
*/
declare abstract class NetworkComponent<T> extends SerializableComponent<T> {
#private;
protected $updateTimestamp: number;
$forceUpdate: boolean;
protected constructor(ownerId?: string, scope?: NetworkScope);
serialize(addNetworkMetadata?: boolean): SerializedNetworkComponent<T>;
deserialize(serializedComponent: SerializedNetworkComponent<T>): void;
/**
* Server-side only. Return true if the component can be updated from the client.
* @param data
*/
abstract accept(data: T): boolean;
/**
* Check for data synchronization, return true if the data is dirty and need to be sent over the networking
*/
abstract isDirty(lastData: T): boolean;
get scope(): NetworkScope;
set scope(value: NetworkScope);
get ownerId(): string;
set ownerId(value: string);
get forceUpdate(): boolean;
set forceUpdate(value: boolean);
get lastData(): T | undefined;
get updateTimestamp(): number | undefined;
set updateTimestamp(value: number | undefined);
}
/**
* The json representation of an entity
*/
declare class SerializedEntity {
protected $id: string;
protected $components: Map<string, SerializedComponent<any>>;
protected $name?: string;
protected $destroyed?: boolean;
protected $parent?: string;
protected $prefabName?: string;
constructor(id: string, components: Map<string, SerializedNetworkComponent<any>>, name?: string, destroyed?: boolean, parent?: string, prefabName?: string);
toJSON(): any;
static reviver(key: string, value: any): any;
// TODO: Move to network entity
get destroyed(): boolean | undefined;
set destroyed(value: boolean | undefined);
get parent(): string | undefined;
set parent(value: string | undefined);
get prefabName(): string | undefined;
get id(): string;
get name(): string | undefined;
get components(): Map<string, SerializedComponent<any>>;
}
declare class IoUtils {
/**
* Imports an entity from a json string
* @param ComponentClasses The list of component classes to import
* @param serializedEntityJson
*/
static import(ComponentClasses: ComponentClass[], serializedEntityJson: string): Entity;
/**
* Exports an entity to a json string
* @param entity
*/
static export(entity: Entity): string;
}
declare class ThreeCamera extends Component {
#private;
constructor(camera: Camera, lookAt?: Entity, lookAtOffset?: Vec3, id?: string, update?: boolean);
get orbitControls(): boolean;
get lookAtOffset(): Vec3;
set lookAtOffset(value: Vec3);
get lookAt(): Entity | undefined;
set lookAt(value: Entity | undefined);
get camera(): Camera;
set camera(value: Camera);
}
declare class ThreeObject3D extends Component {
#private;
constructor(object3D: Object3D, id?: string);
get object3D(): Object3D;
set object3D(value: Object3D);
get isVisible(): boolean;
set isVisible(value: boolean);
clone(): ThreeObject3D;
}
declare class Transform extends Component {
#private;
/**
* The result of the post-multiplication of all the parents of this transform
* This matrix is only updated when queried and dirty
* @private
*/
readonly modelToWorldMatrix: Mat4;
/**
* The inverse of {@see modelToWorldMatrix}
* This matrix is only updated when queried and dirty
* @private
*/
readonly worldToModelMatrix: Mat4;
/**
* The result of Translation * Rotation * Scale
* This matrix is only updated when queried and dirty
* @private
*/
readonly modelMatrix: Mat4;
/**
* The current position
* @private
*/
readonly position: Vec3;
/**
* The current rotation
* @private
*/
readonly rotation: Quat;
/**
* The current scale
* @private
*/
readonly scaling: Vec3;
dirty: boolean;
forward: Vec3;
/**
* The parent transform
* @private
*/
parent?: Transform;
/**
* Creates a new transform
* @param translation Specifies the translation, will be copied using {@link Vec3.copy}
* @param rotation Specifies the rotation, will be copied using {@link Quat.copy}
* @param scaling Specifies the scale, will be copied using {@link Vec3.copy}
* @param forward Specifies the forward vector, will be copied using {@link Vec3.copy}
*/
constructor(translation?: Vec3Like, rotation?: QuatLike, scaling?: Vec3Like, forward?: Vec3);
/**
* Set this transform's parent to the entity's parent
* @param entity The entity this transform is attached to
*/
onAddedToEntity(entity: Entity): void;
/**
* Remove this transform's parent
* @param entity The entity this transform was attached to
*/
onRemovedFromEntity(entity: Entity): void;
/**
* Called whenever the attached entity parent change
* @param parent The new parent entity
*/
onEntityNewParent(parent: Entity): void;
private setNewParent;
onDestroyed(): void;
static fromMat4(matrix: Mat4): Transform;
/**
* Copy the translation, rotation and scaling of the transform
* @param transform The transform to copy from
*/
copy(transform: Mat4): void;
/**
* Translate this transform using a translation vector
* @param translation The translation vector
*/
translate(translation: Vec3Like): void;
setWorldRotation(rotation: QuatLike): void;
/**
* Reset the position, rotation, and scale to the default values
*/
reset(): void;
/**
* Reset the rotation to the default values
*/
resetRotation(): void;
/**
* Rotate this transform in the x axis
* @param x An angle in radians
*/
rotateX(x: number): void;
/**
* Rotate this transform in the y axis
* @param y An angle in radians
*/
rotateY(y: number): void;
/**
* Rotate this transform in the y axis
* @param z An angle in radians
*/
rotateZ(z: number): void;
rotate(rotation: QuatLike): void;
setWorldScale(scale: Vec3Like): void;
scale(scale: Vec3Like): void;
setScale(scale: Vec3Like): void;
setRotationQuat(rotation: QuatLike): void;
/**
* Updates the model to world matrix of this transform and returns it
* It update all the parents until no one is dirty
*/
updateModelToWorldMatrix(): Mat4;
getWorldToModelMatrix(): Mat4Like;
getWorldPosition(): Vec3;
/**
* Get the world scale of this transform
*/
getWorldScale(): Vec3;
/**
* Get the world rotation of this transform
*/
getWorldRotation(): Quat;
getWorldForwardVector(out: Vec3): Vec3;
getVectorInModelSpace(out: Vec3, vector: Vec3Like): Vec3;
getVectorInWorldSpace(out: Vec3, vector: Vec3): Vec3;
toWorldScale(out: Vec3, scale: Vec3Like): Vec3;
/**
* Make this transform look at the specified position
* @param x
* @param y
* @param z
*/
lookAtXyz(x: number, y: number, z: number): void;
lookAt(position: Vec3): void;
setWorldUnitScale(): void;
setWorldPosition(position: Vec3Like): void;
/**
* Set the current position
* @param position Specifies the new position, will be copied using {@link Vec3.copy}
*/
setPosition(position: Vec3Like): void;
setForward(forward: Vec3Like): void;
/**
* Return a new Transform with the same position, rotation, scaling, but no parent
*/
clone(): Component;
}
declare class MathUtils {
static getEulerToDegrees(radians: number): number;
/**
* Convert a quaternion to euler angles.
* Missing function from gl-matrix
* @param quat
* @param out
*/
static getEulerFromQuat(out: Vec3Like, quat: QuatLike): Vec3Like;
}
declare class ThreeSystem extends System<[
Transform,
ThreeObject3D
]> {
#private;
constructor(tps?: number);
onAddedToEcsManager(ecsManager: EcsManager): void;
onEntityEligible(entity: Entity, components: [
Transform,
ThreeObject3D
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
Transform,
ThreeObject3D
]): void;
onStart(): Promise<void>;
protected onLoop(components: [
Transform,
ThreeObject3D
][], entities: Entity[], deltaTime: number): void;
get camera(): Camera;
get renderer(): WebGLRenderer;
get scene(): Scene;
}
declare class ThreeAnimation extends Component {
#private;
constructor();
onAddedToEntity(entity: Entity): void;
onComponentAddedToAttachedEntity(component: Component): void;
private createMixer;
playAnimation(animationName?: string): void;
stopAnimation(): void;
get currentAnimation(): AnimationAction | undefined;
get mixer(): AnimationMixer | undefined;
get clips(): AnimationClip[] | undefined;
}
/**
* Represents an animation being played on an entity
*/
declare class Animation extends Component {
#private;
constructor(name: string, duration: number, repeat: number, startTime: number);
get name(): string;
set name(name: string);
get duration(): number;
set duration(duration: number);
get startTime(): number;
set startTime(startTime: number);
get repeat(): number;
set repeat(repeat: number);
clone(): Component;
}
declare class IsPrefab extends Component {
#private;
constructor(prefabName: string);
get prefabName(): string;
set prefabName(prefabName: string);
}
declare abstract class State extends Component {
protected constructor(id?: string);
}
declare class FiniteStateMachine extends Component {
protected $inialStateName: string;
protected $currentStateName?: string;
protected $states: Map<string, State>;
protected $transitions: Map<string, Map<string, State>>;
constructor(initialStateName: string, states?: {
name: string;
state: State;
}[], transitions?: {
stateName: string;
nextStateNames: string[];
}[]);
addState(name: string, state: State): void;
addStates(states: {
name: string;
state: State;
}[]): void;
addTransition(stateName: string, nextStateNames: string[]): void;
addTransitions(transitions: {
stateName: string;
nextStateNames: string[];
}[]): void;
setNextState(nextStateName: string): void;
getCurrentState(): State | undefined;
get initialStateName(): string;
set currentStateName(currentStateName: string);
get currentStateName(): string | undefined;
clone(): Component;
}
declare class FiniteStateMachineSystem extends System<[
FiniteStateMachine
]> {
constructor(tps?: number);
onEntityEligible(entity: Entity, components: [
FiniteStateMachine
]): void;
protected onLoop(components: [
FiniteStateMachine
][], entities: Entity[], deltaTime: number): void;
}
declare abstract class StateSystem<T extends State> extends System<[
T
]> {
protected constructor(StateClass: new (...args: any[]) => T, tps?: number, dependencies?: any[]);
}
/**
* JSON representation of an entity that is synchronized over the network.
*/
declare class NetworkEntity extends SerializedEntity {
constructor(id: string, components: Map<string, SerializedNetworkComponent<any>>, name?: string, prefabName?: string);
toJSON(): any;
static reviver(key: string, value: any): any;
get components(): Map<string, SerializedNetworkComponent<any>>;
}
type CustomData = {
[key: string]: any;
scope: string;
};
declare class GameState {
#private;
constructor();
clone(): GameState;
toJSON(): {
timestamp: number;
entities: [
string,
SerializedEntity
][];
customData: any[];
};
static reviver(key: string, value: any): any;
get timestamp(): number;
set timestamp(value: number);
get entities(): Map<string, NetworkEntity>;
set entities(value: Map<string, NetworkEntity>);
get customData(): CustomData[];
set customData(value: CustomData[]);
}
declare class ClientHandler {
#private;
protected ecsManager: EcsManager;
protected $webSocket: WebSocket;
readonly $clientEntity: Entity;
constructor(clientEntity: Entity, ecsManager: EcsManager, webSocket: WebSocket);
onConnect(): void;
onDisconnect(): void;
sendMessage(message: GameState): void;
sendCustomData(data: any): void;
onPrivateCustomData(data: any): void;
get webSocket(): WebSocket;
get forceUpdate(): boolean;
set forceUpdate(forceUpdate: boolean);
get clientSnapshot(): GameState | undefined;
set clientSnapshot(snapshot: GameState | undefined);
get clientEntity(): Entity;
get customData(): CustomData[];
}
/**
* The networking system is responsible for sending and receiving entities over the networking.
* This class is used by the server and the client to provide a common interface for formatting entities.
*/
declare class NetworkSystem extends System<[
IsNetworked
]> {
#private;
protected $currentSnapshot: GameState;
$allowedNetworkComponents: ComponentClass<Component>[];
constructor(allowedNetworkComponents: ComponentClass[], tps?: number);
protected onLoop(components: [
IsNetworked
][], entities: Entity[], deltaTime: number): void;
/**
* Deserialize the components of the serialized entity and add them to the target entity.
* @param serializedEntity
*/
protected deserializeEntity(serializedEntity: NetworkEntity): void;
protected deserializeComponent(serializedNetworkComponent: SerializedNetworkComponent<any>, targetEntity: Entity): void;
protected serializeEntity(entity: Entity): NetworkEntity | undefined;
protected serializeComponent(component: NetworkComponent<any>): SerializedNetworkComponent<any> | undefined;
/**
*
* @param snapshot
* @param entity
* @param component
*/
isOutOfSync(snapshot: GameState, entity: SerializedEntity, component: SerializedNetworkComponent<any>): boolean;
get allowedNetworkComponents(): ComponentClass[];
}
type ClientHandlerConstructor = new (playerEntity: Entity, ecsManager: EcsManager, webSocket: WebSocket) => ClientHandler;
/**
* This class is responsible for managing all the clients connected to the server.
*/
declare class ServerNetworkSystem extends NetworkSystem {
#private;
protected $clientHandlers: ClientHandler[];
constructor(allowedNetworkComponents: ComponentClass[], clientHandlerConstructor: ClientHandlerConstructor, tps?: number);
onStart(): Promise<void>;
onStop(): Promise<void>;
onEntityEligible(entity: Entity, components: [
IsNetworked
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
IsNetworked
]): void;
protected onLoop(components: [
IsNetworked
][], entities: Entity[], deltaTime: number): void;
deserializeComponent(networkComponent: SerializedNetworkComponent<any>, targetEntity: Entity): void;
/**
* Broadcasts custom data to all clients.
* @param data
*/
broadcastCustomData(data: any): void;
sendCustomDataToClient(clientId: string, data: any): void;
}
/**
* Entry point for the client-side networking.
* This system is responsible for sending and receiving entities over the networking.
* It must be extended to provide a custom listener for various events.
*/
declare abstract class ClientNetworkSystem extends NetworkSystem {
#private;
protected $serverSnapshot?: GameState;
protected constructor(allowedNetworkComponents: ComponentClass[], address: string, tps?: number);
onStart(): Promise<void>;
onStop(): Promise<void>;
onEntityEligible(entity: Entity): void;
protected onLoop(components: [
IsNetworked
][], entities: Entity[], deltaTime: number): void;
private setup;
deserializeEntity(networkEntity: NetworkEntity): void;
/**
* Serialize the entity only if it is networked and owned by the client.
* @param entity
*/
serializeEntity(entity: Entity): NetworkEntity | undefined;
sendCustomPrivateData(data: any): void;
/**
* Called when the client is connected to the server.
* @protected
*/
protected abstract onConnect(): void;
/**
* Called when the client is disconnected from the server.
* @protected
*/
protected abstract onDisconnect(): void;
/**
* Called when the client received a new entity from the server.
* @protected
*/
protected abstract onNewEntity(entity: Entity): void;
/**
* Called when an entity is deleted from the server.
* @protected
*/
protected abstract onDeletedEntity(entity: Entity): void;
protected onCustomData(customPrivateData: any): void;
get networkId(): string | undefined;
}
/**
* The component that is used to store the client metadata
*/
declare class ClientComponent extends Component {
constructor();
}
type TransformData = {
position: [
number,
number,
number
];
rotation: [
number,
number,
number,
number
];
scale: [
number,
number,
number
];
};
declare class NetworkTransform extends NetworkComponent<TransformData> {
constructor();
onAddedToEntity(entity: Entity): void;
accept(data: TransformData): boolean;
read(data: TransformData): void;
isDirty(lastData: TransformData): boolean;
write(): TransformData;
clone(): Component;
}
type AnimationData = {
name: string;
duration: number;
startTime: number;
repeat: number;
};
/**
* Represents an animation being played on an entity
*/
declare class NetworkAnimation extends NetworkComponent<AnimationData> {
constructor();
accept(data: AnimationData): boolean;
isDirty(lastData: AnimationData): boolean;
read(data: AnimationData): void;
write(): AnimationData;
clone(): Component;
}
declare class NetworkFiniteStateMachine extends NetworkComponent<string> {
constructor();
accept(stateName: string): boolean;
isDirty(lastStateName?: string): boolean;
write(): string;
read(stateName: string): void;
clone(): NetworkFiniteStateMachine;
}
declare class TimedState extends Component {
#private;
constructor(duration: number, repeat: number, nextStateName?: string);
get duration(): number;
get repeat(): number;
get startTime(): number;
set startTime(startTime: number);
get nextStateName(): string | undefined;
}
declare class TimedStateSystem extends System<[
FiniteStateMachine,
TimedState
]> {
constructor();
onEntityEligible(entity: Entity, components: [
FiniteStateMachine,
TimedState
]): void;
onLoop(components: [
FiniteStateMachine,
TimedState
][], entities: Entity[], deltaTime: number): void;
}
declare class ThreeAnimationSystem extends System<[
ThreeAnimation,
Animation
]> {
constructor(tps?: number);
onEntityEligible(entity: Entity, components: [
ThreeAnimation,
Animation
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
ThreeAnimation,
Animation
]): void;
onStart(): Promise<void>;
protected onLoop(components: [
ThreeAnimation,
Animation
][], entities: Entity[], deltaTime: number): void;
}
declare class ThreeCameraSystem extends System<[
ThreeCamera,
Transform
]> {
#private;
constructor(renderer: WebGLRenderer, tps?: number);
onStart(): Promise<void>;
onEntityEligible(entity: Entity, components: [
ThreeCamera,
Transform
]): void;
protected onLoop(components: [
ThreeCamera,
Transform
][], entities: Entity[], deltaTime: number): void;
get cameraEntity(): Entity | undefined;
}
declare class ThreeLightComponent extends Component {
#private;
constructor(light: Light, target?: Entity, castShadow?: boolean);
get target(): Entity | undefined;
get light(): Light;
}
declare class ThreeLightSystem extends System<[
ThreeLightComponent,
Transform
]> {
#private;
constructor(scene: Scene, tps?: number);
onEntityEligible(entity: Entity, components: [
ThreeLightComponent,
Transform
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
ThreeLightComponent,
Transform
]): void;
protected onLoop(components: [
ThreeLightComponent,
Transform
][], entities: Entity[], deltaTime: number): void;
}
declare class ThreeCss3dComponent extends Component {
#private;
constructor(htmlElement: HTMLElement, id?: string);
get css3dObject(): CSS3DObject;
}
declare class ThreeCss3dSystem extends System<[
ThreeCss3dComponent,
Transform
]> {
#private;
constructor(threeSystem: ThreeSystem, tps?: number);
onEntityEligible(entity: Entity, components: [
ThreeCss3dComponent,
Transform
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
ThreeCss3dComponent,
Transform
]): void;
protected onLoop(components: [
ThreeCss3dComponent,
Transform
][], entities: Entity[], deltaTime: number): void;
}
declare class ThreeComponentDebugger extends Component {
constructor();
onAddedToEntity(entity: Entity): void;
}
declare class ThreeInstancedMesh extends ThreeObject3D {
#private;
constructor(instancedMesh: InstancedMesh, id?: string);
onAddedToEntity(entity: Entity): void;
onRemovedFromEntity(entity: Entity): void;
getEntityIndex(entityId: string): number;
get entities(): string[];
clone(): ThreeInstancedMesh;
}
declare class AnimatedState extends TimedState {
#private;
constructor(animationName: string, duration: number, repeat: number, nextStateName?: string);
get name(): string;
}
/**
* System for handling animated states
*/
declare class AnimatedStateSystem extends System<[
AnimatedState
]> {
constructor();
onEntityEligible(entity: Entity, components: [
AnimatedState
]): void;
protected onLoop(components: [
AnimatedState
][], entities: Entity[], deltaTime: number): void;
onEntityNoLongerEligible(entity: Entity, components: [
AnimatedState
]): void;
}
declare abstract class KeyboardInputSystem extends System<[
Component
]> {
#private;
protected constructor(filter: ComponentClass[], canvasId: string, tps?: number);
initialize(): Promise<void>;
abstract onKeyDown(key: string): void;
abstract onKeyRepeat(key: string): void;
abstract onKeyUp(key: string): void;
onLoop(): void;
}
declare abstract class MouseInputSystem extends System<[
]> {
#private;
protected constructor(canvasId?: string, tps?: number);
initialize(): Promise<void>;
onLoop(components: [
], entities: Entity[]): void;
abstract onMouseMove(event: MouseEvent): void;
abstract onMouseDown(event: MouseEvent): void;
abstract onMouseUp(event: MouseEvent): void;
abstract onMouseWheel(event: WheelEvent): void;
}
type OimoComponentOptions = Exclude<BodyOptions, "rot" | "pos">;
declare class OimoComponent extends Component {
#private;
constructor(bodyOptions: OimoComponentOptions);
get bodyOptions(): BodyOptions;
get body(): Body | undefined;
set body(body: Body | undefined);
clone(): Component;
}
declare class OimoSystem extends System<[
OimoComponent,
Transform
]> {
#private;
constructor(tps?: number);
onStart(): Promise<void>;
onEntityEligible(entity: Entity, components: [
OimoComponent,
Transform
]): void;
protected onLoop(components: [
OimoComponent,
Transform
][], entities: Entity[], deltaTime: number): void;
}
declare class AxisAlignedBoundingBox {
#private;
constructor(min: Vec3Like, max: Vec3Like);
contains(point: Vec3Like): boolean;
intersects(other: AxisAlignedBoundingBox): boolean;
get minimum(): Vec3Like;
get maximum(): Vec3Like;
}
type PhysicsData = {
movable: boolean;
[key: string]: any;
};
type BodyOptions$0 = {
movable?: boolean;
mass?: number;
};
declare abstract class Body$0 extends SerializableComponent<PhysicsData> {
protected $movable: boolean;
protected $boundingBox: AxisAlignedBoundingBox;
protected $mass: number;
protected constructor(bodyOptions?: BodyOptions$0);
abstract getBoundingBox(): AxisAlignedBoundingBox;
abstract read(data: PhysicsData): void;
abstract write(): PhysicsData;
hasMoved(): boolean;
get mass(): number;
get movable(): boolean;
set movable(movable: boolean);
abstract clone(): Component;
}
declare class Ray {
#private;
constructor(origin: Vec3Like, direction: Vec3Like);
getSphereIntersection(sphereEntity: Entity): Vec3Like | undefined;
get origin(): Vec3Like;
get direction(): Vec3Like;
}
declare class PhysicsSystem extends System<[
Body$0,
Transform
]> {
#private;
constructor(tps?: number);
onEntityEligible(entity: Entity, components: [
Body$0,
Transform
]): void;
onEntityNoLongerEligible(entity: Entity, components: [
Body$0,
Transform
]): void;
protected onLoop(components: [
Body$0,
Transform
][], entities: Entity[], deltaTime: number): void;
findEntitiesFromRaycast(ray: Ray): Entity[];
private applyGravity;
}
type SphereBodyOptions = BodyOptions$0 & {
radius: number;
};
declare class SphereBody extends Body$0 {
#private;
constructor(sphereBodyOptions: SphereBodyOptions);
getBoundingBox(): AxisAlignedBoundingBox;
get radius(): number;
set radius(radius: number);
read(data: PhysicsData): void;
write(): PhysicsData;
clone(): SphereBody;
}
interface Narrowphase {
getSphereSphereCollision(sphere1Position: Vec3, sphere1Shape: SphereBody, sphere2Position: Vec3, sphere2Shape: SphereBody): Vec3 | undefined;
}
declare class DefaultNarrowphase implements Narrowphase {
constructor();
getSphereSphereCollision(sphere1Position: Vec3, sphere1Shape: SphereBody, sphere2Position: Vec3, sphere2Shape: SphereBody): Vec3 | undefined;
}
declare abstract class Broadphase {
constructor();
abstract onEntityAdded(entity: Entity, components: [
Body$0,
Transform
]): void;
abstract onEntityRemoved(entity: Entity, components: [
Body$0,
Transform
]): void;
abstract onEntityMoved(entity: Entity, components: [
Body$0,
Transform
]): void;
abstract getCollisionPairs(entities: Entity[]): [
Entity,
Entity
][];
}
/**
* A brute force approach to broadphase, it checks every entity with every other entity
*/
declare class BruteForceBroadphase extends Broadphase {
constructor();
onEntityAdded(entity: Entity): void;
getCollisionPairs(entities: Entity[]): [
Entity,
Entity
][];
onEntityRemoved(entity: Entity): void;
onEntityMoved(entity: Entity): void;
}
declare class Collision extends Component {
#private;
constructor(position: Vec3Like, collidingWith: Entity);
get position(): Vec3Like;
get collidingWith(): Entity;
}
/**
* Simple solver that pushes the bodies away from each other
*/
declare class DefaultSolver {
solve(entity1: Entity, entity2: Entity, contactNormal: Vec3Like): void;
clone(): DefaultSolver;
}
declare class BodyDebugger extends Component {
constructor();
onAddedToEntity(entity: Entity): void;
onRemovedFromEntity(entity: Entity): void;
}
type SphereBodyData = {
movable: boolean;
radius: number;
};
declare class NetworkSphereBody extends NetworkComponent<SphereBodyData> {
constructor();
onAddedToEntity(entity: Entity): void;
accept(data: SphereBodyData): boolean;
isDirty(): boolean;
read(data: SphereBodyData): void;
write(): SphereBodyData;
clone(): NetworkSphereBody;
}
type CubeBodyData = {
movable: boolean;
width: number;
height: number;
depth: number;
};
declare class NetworkSphereBody$0 extends NetworkComponent<CubeBodyData> {
constructor();
onAddedToEntity(entity: Entity): void;
accept(data: CubeBodyData): boolean;
isDirty(): boolean;
read(data: CubeBodyData): void;
write(): CubeBodyData;
clone(): NetworkSphereBody$0;
}
declare module NetworkSphereBodyWrapper {
export { NetworkSphereBody$0 as NetworkSphereBody };
}
import NetworkCubeBody = NetworkSphereBodyWrapper.NetworkSphereBody;
type ParticleOptions = {
getDirection: () => Vec3;
startScale: number;
endScale: number;
lifeTime: number;
timeAlive: number;
startColor: Vec3;
endColor: Vec3;
};
declare class Particle extends Component {
#private;
constructor(options: ParticleOptions);
get startColor(): Vec3;
get endColor(): Vec3;
get lifeTime(): number;
set lifeTime(lifeTime: number);
get timeAlive(): number;
set timeAlive(timeAlive: number);
get direction(): Vec3;
get startScale(): number;
get endScale(): number;
clone(): Particle;
}
declare class ParticleEmitter extends Component {
#private;
constructor(particlePrefab: Entity, maxParticleCount: number, startParticleCount: number);
get particlePrefab(): Entity;
get maxParticleCount(): number;
get startParticleCount(): number;
}
declare class ParticleSystem extends System<[
Particle,
Transform,
ThreeObject3D
]> {
constructor();
onAddedToEcsManager(ecsManager: EcsManager): void;
protected onLoop(components: [
Particle,
Transform,
ThreeObject3D
][], entities: Entity[], deltaTime: number): void;
}
declare class Sound extends Component {
#private;
constructor(soundPath: string, repeat?: boolean, volume?: number, spacialized?: boolean);
get spacialized(): boolean;
get soundPath(): string;
get sound(): HTMLAudioElement | undefined;
set sound(sound: HTMLAudioElement | undefined);
get repeat(): boolean;
}
declare class SoundSystem extends System<[
Sound
]> {
#private;
constructor();
start(ecsManager: EcsManager): Promise<void>;
onEntityEligible(entity: Entity, components: [
Sound
]): void;
protected onLoop(components: [
Sound
][], entities: Entity[], deltaTime: number): void;
}
export { Component, Entity, System, EcsManager, PrefabManager, SerializedEntity, SerializableComponent, IoUtils, ThreeCamera, ThreeObject3D, ThreeSystem, ThreeCameraSystem, ThreeAnimationSystem, ThreeAnimation, ThreeLightSystem, ThreeLightComponent, ThreeCss3dSystem, ThreeCss3dComponent, ThreeComponentDebugger, ThreeInstancedMesh, AnimatedState, AnimatedStateSystem, ServerNetworkSystem, ClientNetworkSystem, NetworkComponent, ClientHandler, ClientComponent, NetworkTransform, IsNetworked, NetworkAnimation, Transform, MathUtils, FiniteStateMachine, State, FiniteStateMachineSystem, StateSystem, NetworkFiniteStateMachine, TimedState, TimedStateSystem, Animation, IsPrefab, KeyboardInputSystem, MouseInputSystem, OimoComponent, OimoSystem, Body$0 as Body, SphereBody, PhysicsSystem, DefaultNarrowphase, Broadphase, BruteForceBroadphase, Collision, DefaultSolver, Ray, BodyDebugger, NetworkSphereBody, NetworkCubeBody, Particle, ParticleEmitter, ParticleSystem, Sound, SoundSystem };
export type { SerializedComponent, CustomData, NetworkScope };