A WebRTC wrapper that simplifies peer-to-peer multiplayer game development by abstracting away connection handling and state synchronization.
PlayPeer eliminates the traditional complexity of WebRTC multiplayer implementations:
- Simplified Architecture: No need for separate server/client logic
- Automatic Host Migration: Seamless host switching if the current – or any future – host disconnects
- State Synchronization: Built-in storage system keeps game state synchronized across all peers
- Resilient Connections: Automatic reconnection handling and connection health monitoring
npm install playpeerjs
Note that in production, you should always try...catch these promises, such as peer.init(), to ensure your application continues to run if errors occur.
import PlayPeer from 'playpeerjs';
// Create a new instance
const peer = new PlayPeer('unique-peer-id', {{
// Provide stun and turn servers here
config: {
'iceServers': [
{ urls: "stun:your-stun-server.com" },
{ urls: "turn:your-turn-server.com" },
]
}
}});
// Set up event handlers
peer.onEvent('status', status => console.log('Status:', status));
peer.onEvent('storageUpdate', storage => console.log('Storage update received:', storage));
// Initialize the peer
await peer.init();
// Create a new room
const hostId = await peer.createRoom({
players: [],
});
// Or, join room
await peer.joinRoom('host-peer-id'); // Rejects if connection fails or times out
// Interact with the synced storage
const currentState = peer.getStorage;
peer.updateStorageArray('players', 'add-unique', { username: 'PeerEnjoyer4', level: 2 }); // Special method to enable simultaneous storage updates for arrays
peer.updateStorage('latestPlayer', 'PeerEnjoyer4'); // Regular synced storage update
// To leave the room, destroy the instance
peer.destroy();
new PlayPeer(id: string, options?: PeerJS.Options)
Creates a new PlayPeer instance with a specified peer ID and PeerJS options.
init()
: Initialize the peer connection (async)createRoom(initialStorage?: object, maxSize?: number)
: Create a new room and become host (async)joinRoom(hostId: string)
: Join an existing room. Returns promise, rejects after 2s timeout (async)destroy()
: Use this to leave a room. Destroys the peer instance
updateStorage(key: string, value: any)
: Update a value in the synchronized storageupdateStorageArray(key: string, operation: 'add' | 'add-unique' | 'remove-matching' | 'update-matching', value: any, updateValue?: any)
: Safely update arrays in storage by adding, removing, or updating items. This is necessary for when array updates might be happening simultanously to ensure changes are being applied and not overwritten. Using add-unique instead of add ensures that this value can only be in the array once.onEvent(event: string, callback: Function)
: Register an event callback
status
: Connection status updates (returns statusstring
)error
: Error events (returns errorstring
)instanceDestroyed
: Destruction event - triggered by manual .destroy() method invocation or by fatal errorsstorageUpdated
: Storage state changes (returns storageobject
)hostMigrated
: Host changes (returns host id / room codestring
)incomingPeerConnected
: New peer connected (returns peer-idstring
)incomingPeerDisconnected
: Peer disconnected (returns peer-idstring
)incomingPeerError
: Peer connection error (returns peer-idstring
)outgoingPeerConnected
: Connected to host (returns peer-idstring
)outgoingPeerDisconnected
: Disconnected from host (returns peer-idstring
)outgoingPeerError
: Host connection error (returns peer-idstring
)
The id
is used to distinguish the peer from other peers on the signalling server.
Using a uuid is recommended, but it is also fine to use any other random string. If you're using a public signalling server instance, including
your application's name in the id
can help to prevent overlap (e.g. your-app-012345abcdef).
id
: Peer's unique identifierisHost
: If this peer is currently hosting or notconnectionCount
: Number of active peer connections (without you)getStorage
: Retrieve storage object
MIT
Please feel free to fork the repository and submit a Pull Request.