npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lobstar/core

v0.1.0

Published

A simple network and lobby manager for multiplayer web games

Readme

[!WARNING] This is an early prototype and the API is subject to change and bugs are expected.

A lightweight peer-to-peer multiplayer game session and lobby manager for web games.

npm version license bundlephobia minzipped size

Features

  • Simple peer-to-peer networking with WebRTC (via PeerJS)
  • Host/client architecture with configurable lobby settings
  • Player management (joining, leaving, kicking, ready states)
  • Game state lifecycle (lobby, playing, game over)
  • Event-based messaging system
  • Robust error handling and state management

Installation

npm install @lobstar/core

Basic Usage

Creating a Game Session

import { GameSessionManager } from '@lobstar/core';

// Create a session manager with default options
const gameSession = new GameSessionManager({
  maxPlayers: 4,                // Maximum number of players allowed (default: 8)
  requireReadyBeforeStart: true, // Require all players to be ready before starting (default: true)
  debug: true                   // Enable debug logging (default: false)
});

// Listen for state changes
gameSession.on('stateChange', ({ state, previousState }) => {
  console.log(`Game state changed from ${previousState} to ${state}`);
});

// Host a new game
async function hostGame() {
  try {
    const lobbyId = await gameSession.host('HostPlayer');
    console.log(`Game hosted with lobby ID: ${lobbyId}`);
    
    // Share this lobby ID with other players so they can join
  } catch (error) {
    console.error('Failed to host game:', error);
  }
}

// Join an existing game
async function joinGame(lobbyId) {
  try {
    await gameSession.join(lobbyId, 'GuestPlayer');
    console.log('Successfully joined the game!');
  } catch (error) {
    console.error('Failed to join game:', error);
  }
}

Managing Players and Game State

// Set player ready state
gameSession.setReady(true);

// Start the game (host only)
if (gameSession.isHost()) {
  gameSession.startGame();
}

// Get current players
const players = gameSession.getPlayers();
console.log('Current players:', players);

// Kick a player (host only)
if (gameSession.isHost()) {
  gameSession.kickPlayer('player-id-to-kick');
}

// End the game (host only)
if (gameSession.isHost()) {
  gameSession.endGame();
}

// Leave the game
gameSession.leave();

Custom Communication

The session manager provides a custom message system that allows you to send and receive messages between players.

This allows you to

  • Extend the lobby experience with chat, character selection, etc.
  • Send and receive game-specific messages between players on game start

[!NOTE] The host will operate like a server, they can send messages to all players and receive messages from all players.

The clients can only send messages and receive messages from the host.

// Send a custom message to the host
gameSession.sendMessageToHost({
  type: 'move', 
  x: 100, 
  y: 200 
});

// Broadcast a message to all players
gameSession.broadcastMessage({
  type: 'itemCollected',
  playerId: 'player-id-123',
  itemId: 'power-up-22'
});

// Send a custom message to a specific player from the host
gameSession.sendMessage('player-id-123', {
  type: 'secretObjective',
  objective: 'Find the hidden gold necklace'
});

// Listen for custom messages
gameSession.on('customMessage', ({ data, peerId }) => {
  console.log(`Received message from ${peerId}:`, data);
});

API Reference

Constructor

new GameSessionManager(options?: GameSessionOptions)

Options:

  • maxPlayers: Maximum number of players allowed (default: 8)
  • requireReadyBeforeStart: Require all players to be ready before starting (default: true)
  • debug: Enable debug logging (default: false)
  • peerOptions: Options to pass to the underlying PeerJS instance
  • playerJoinTimeoutMs: Timeout for player join (default: 10000)

Methods

Session Management

  • host(playerName: string, lobbyId?: string): Promise<string> - Host a new game session
  • join(lobbyId: string, playerName: string): Promise<void> - Join an existing game session
  • leave(): void - Leave the current session

Game Flow

  • setReady(isReady: boolean): void - Set player ready state
  • startGame(): void - Start the game (host only)
  • endGame(): void - End the game (host only)

Player Management

  • kickPlayer(playerId: string): void - Kick a player (host only)
  • getPlayers(): PlayerMap - Get all players
  • getPlayer(id: string): Player | null - Get a specific player
  • getSelf(): Player | null - Get the current player
  • getHost(): Player | null - Get the host player

Communication

  • sendMessage(peerId: string, data: unknown): void - Send a message to a specific player. Only the host can send messages to other players. Clients can only send messages to the host's peerId.
  • sendMessageToHost(data: unknown): void - Send a message to the host.
  • broadcastMessage(data: unknown, excludeSelf: boolean = true): void - Broadcast a message to all players. Only the host can broadcast messages.

Status

  • isHost(): boolean - Check if the current player is the host
  • getState(): SessionState - Get the current session state
  • getMaxPlayers(): number - Get the maximum allowed players

Events

Listen to events using the on method:

gameSession.on('eventName', (eventData) => {
  // Handle the event
});

Available events:

  • stateChange: Fired when the session state changes
  • playersUpdate: Fired when the players list is updated
  • customMessage: Fired when a custom message is received
  • error: Fired when an error occurs
  • kicked: Fired when the player is kicked from the session

Error Handling

The session manager provides detailed error information through the error event:

gameSession.on('error', ({ code, message, context, originalError }) => {
  console.error(`Error [${code}]: ${message} (${context})`);
  if (originalError) {
    console.error('Original error:', originalError);
  }
});

Error codes are available in the ERROR_CODES constant.

License

MIT