@lobstar/core
Version:
A simple network and lobby manager for multiplayer web games
171 lines (170 loc) • 5.53 kB
TypeScript
export interface Player {
id: string;
name: string;
isReady: boolean;
isHost: boolean;
}
export type PlayerMap = {
[peerId: string]: Player;
};
export declare const SESSION_STATES: {
readonly DISCONNECTED: "DISCONNECTED";
readonly CONNECTING: "CONNECTING";
readonly LOBBY: "LOBBY";
readonly PLAYING: "PLAYING";
readonly GAME_OVER: "GAME_OVER";
readonly ERROR: "ERROR";
};
export type SessionState = (typeof SESSION_STATES)[keyof typeof SESSION_STATES];
export declare const ERROR_CODES: {
readonly CONNECTION_FAILED: "CONNECTION_FAILED";
readonly HOST_DISCONNECTED: "HOST_DISCONNECTED";
readonly PEER_DISCONNECTED: "PEER_DISCONNECTED";
readonly NOT_HOST: "NOT_HOST";
readonly ALREADY_HOST: "ALREADY_HOST";
readonly INVALID_STATE: "INVALID_STATE";
readonly SESSION_FULL: "SESSION_FULL";
readonly INVALID_MESSAGE: "INVALID_MESSAGE";
readonly MESSAGE_SEND_FAILED: "MESSAGE_SEND_FAILED";
readonly PLAYER_NOT_FOUND: "PLAYER_NOT_FOUND";
readonly SELF_ACTION_INVALID: "SELF_ACTION_INVALID";
readonly NOT_ALL_PLAYERS_READY: "NOT_ALL_PLAYERS_READY";
readonly NOT_ENOUGH_PLAYERS: "NOT_ENOUGH_PLAYERS";
readonly UNKNOWN: "UNKNOWN";
};
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
export type GameSessionEvents = {
stateChange: {
state: SessionState;
previousState: SessionState;
};
playersUpdate: {
players: PlayerMap;
};
customMessage: {
data: unknown;
peerId: string;
};
error: {
code: ErrorCode;
message: string;
context?: string;
originalError?: unknown;
};
kicked: void;
};
export interface GameSessionOptions {
maxPlayers?: number;
requireReadyBeforeStart?: boolean;
debug?: boolean;
peerOptions?: any;
playerJoinTimeoutMs?: number;
}
export declare class GameSessionManager {
private networkManager;
private emitter;
private currentState;
private players;
private selfId;
private hostId;
private maxPlayers;
private requireReadyBeforeStart;
private debug;
private pendingPlayers;
private playerJoinTimeoutMs;
constructor(options?: GameSessionOptions);
private log;
private setState;
private emitError;
private setupNetworkListeners;
private handleMessage;
private handlePlayerInfo;
private handleLobbyUpdate;
private handleLobbyFull;
private handlePlayerReady;
private handleGameStart;
private handleGameOver;
private handleKickPlayer;
private handleCustomMessage;
private addPlayer;
private broadcastLobbyUpdate;
/**
* Host a new game session
* @param playerName Display name for the host
* @param lobbyId Optional specific ID to request for the lobby
* @returns The actual lobby ID assigned
*/
host(playerName: string, lobbyId?: string): Promise<string>;
/**
* Join an existing game session
* @param lobbyId The ID of the lobby host to connect to
* @param playerName Display name for the joining player
*/
join(lobbyId: string, playerName: string): Promise<void>;
/**
* Connect to a peer with a timeout
* @param peerId ID of the peer to connect to
* @param timeoutMs Timeout in milliseconds (default: 10000)
* @returns Promise that resolves when connection is established or rejects on timeout/error
*/
private connectWithTimeout;
leave(): void;
/**
* Set the ready state for the current player
* @param isReady True if ready, false otherwise
*/
setReady(isReady: boolean): void;
/**
* Start the game (host only)
*/
startGame(): void;
/**
* End the game (host only)
*/
endGame(): void;
/**
* Kick a player from the game (host only)
* @param playerId ID of the player to kick
*/
kickPlayer(playerId: string): void;
/**
* Send a custom message to a specific player
* Only the host can send messages to other players.
* Clients can only send messages to the host with this.
* @param peerId ID of the recipient
* @param data Custom data to send
*/
sendMessage(peerId: string, data: unknown): void;
/**
* Send a custom message directly to the host. Does nothing if called by the host.
* @param data Custom data to send to the host
*/
sendMessageToHost(data: unknown): void;
/**
* Broadcast a custom message to all players (optionally excluding self).
* @param data Custom data to send
* @param excludeSelf Whether to exclude the sender (default: true)
*/
broadcastMessage(data: unknown, excludeSelf?: boolean): void;
/**
* Register an event listener
* @param event Event to listen for
* @param callback Event handler function
* @returns Unsubscribe function
*/
on<K extends keyof GameSessionEvents>(event: K, callback: (data: GameSessionEvents[K]) => void): () => void;
/**
* Remove an event listener
* @param event Event to remove listener from
* @param callback Event handler to remove
*/
off<K extends keyof GameSessionEvents>(event: K, callback: (data: GameSessionEvents[K]) => void): void;
areAllPlayersReady(): boolean;
isHost(): boolean;
getState(): SessionState;
getPlayers(): PlayerMap;
getPlayer(id: string): Player | null;
getSelf(): Player | null;
getHost(): Player | null;
getMaxPlayers(): number;
}