Skip to content

proofnetworks/netlib

Repository files navigation

The Poki Networking Library   

The Poki Networking Library is a peer-to-peer networking library for web games, leveraging WebRTC datachannels to enable direct UDP connections between players. Think of it as the Steam Networking Library for the web, designed to make WebRTC as simple to use as WebSockets for game development.

It now also ships zero-config automatic binary serialization, area-of-interest broadcasting, and supports flexible topologies — from pure peer-to-peer full mesh to a star arrangement with an optional dedicated authoritative host for games that need server-held state, secrets, or a reliable always-on peer.

Warning

This library is still under development and considered a beta. While it's being actively used in production by some games, the API can change. Make sure to get in touch if you want to go live with this so we can keep you up-to-date about changes.

Note

This build is ProofNetworks (@Proofnetworks) aligned — extended for the ProofNetworks ecosystem with zero-config binary serialization, area-of-interest broadcasting, and support for dedicated authoritative (host) peers. See Efficient messaging and Topologies.

Features

  • True Peer-to-Peer (P2P) Networking

    • Direct client-to-client connections without a central game server
    • Lower latency for geographically close players
    • Reduced server costs and infrastructure complexity
    • No need to duplicate game logic between client and server
    • Three main advantages:
      1. No server costs - there is no server running the game
      2. No double implementation - you don't need to write your game logic twice (for the client and the server)
      3. Lower latency - when players are living close by, the latency is often much lower than when connected via a server
  • UDP Performance

    • Choice between reliable (TCP) and unreliable (UDP) channels
    • Optimized for real-time gaming with minimal latency
    • Perfect for fast-paced multiplayer games
    • Unlike WebSockets or HTTP (which use TCP), UDP doesn't pause new packets when one packet is slow or dropped
    • Includes reliable data channels for critical events like chat messages or NPC spawns
  • Efficient Messaging

    • Send raw bytes/strings, or pass plain objects and let netlib handle the wire format
    • Zero-config automatic binary serialization (sendAuto / broadcastAuto) — object key shapes are interned and synced in-band, so repeated messages drop their field names (typically 40–65% smaller than JSON for steady-state game state, no schema declarations required)
    • Loss-tolerant by design: schemas ride the first message and are acknowledged on the reliable channel, so compaction never corrupts data even under packet loss
    • Pluggable serializer (sendJSON / broadcastJSON) — drop in @msgpack/msgpack or your own
    • Area-of-interest broadcasting (interestBroadcast / interestBroadcastAuto) — send only to the peers that care (spatially near, same team/region), the main lever for scaling player counts on a mesh
  • Easy to Use

    • Simple WebSocket-like API
    • Built-in lobby system with filtering
    • Automatic connection management
    • Comprehensive TypeScript support
    • Ships as an ES module, a TypeScript-typed build, and a plain-JS browser global (dist/legacy.js, window.netlib) usable directly via a <script> tag
  • Production Ready

    • Fallback to TURN servers when direct P2P fails
    • Built-in connection quality monitoring
    • Automatic reconnection handling
    • Secure by default

Quick Start

  1. Install the package:
yarn add @poki/netlib
# or
npm install @poki/netlib
  1. Create a network instance:
import { Network } from '@poki/netlib'
const network = new Network('<your-game-id>')
  1. Create or join a lobby:
// Create a new lobby
network.on('ready', () => {
  network.create()
})

// Or join an existing one
network.on('ready', () => {
  network.join('ed84')
})
  1. Start communicating:
// Send raw bytes/strings to every peer (you serialize)
network.broadcast('unreliable', 'hello')

// Or send a plain object and let netlib encode/decode it automatically
network.broadcastAuto('unreliable', { x: 100, y: 200 })

// Receive messages (auto-encoded messages arrive already decoded)
network.on('message', (peer, channel, data) => {
  console.log(`Received from ${peer.id}:`, data)
})

For more detailed examples and API documentation:

Efficient messaging

broadcast/send take raw bytes or strings — you handle serialization. For game state, prefer the automatic binary codec, which needs no schema setup:

// object in → compact binary on the wire → decoded object out
network.broadcastAuto('unreliable', { type: 'move', x: 100, y: 200 })

// area-of-interest: send only to relevant peers (e.g. spatially near)
network.interestBroadcastAuto('unreliable', state, peer => isNear(peer.id))

Interest filtering cuts the number of recipients while the binary codec cuts the bytes per recipient — and those savings compound. See the API Reference for sendJSON/sendAuto, custom serializers, and the interest predicate.

Roadmap

  • Basic P2P connectivity
  • Lobby system
  • Lobby discovery and filtering
  • Compact wire format — zero-config automatic binary serialization (sendAuto/broadcastAuto) with pluggable serializers
  • Area-of-interest broadcasting (interestBroadcast) to reduce mesh fan-out
  • Connection statistics and debugging tools
  • More extensive documentation
  • Dedicated authoritative host peers (pinned leader) — see Topologies
  • Interest-driven connection management (partial mesh) for large sessions
  • API stability

Architecture

Network Stack

Your Game
    ↓
Netlib API
    ↓
WebRTC DataChannels
    ↓
(STUN/TURN if needed)
    ↓
UDP Transport

Infrastructure Components

1. Signaling Server

  • Handles initial peer discovery
  • Manages lobby creation and joining
  • Facilitates WebRTC connection establishment

2. STUN/TURN Servers

  • STUN: Helps peers discover their public IP (by default Google STUN servers)
  • TURN: Provides fallback relay when direct P2P fails (when using the Poki hosted version, Cloudflare TURN servers are used)

Topologies

netlib connects players with WebRTC datachannels. Because WebRTC is point-to-point and symmetric, the same library can be arranged in different shapes depending on your game's needs.

Full mesh (default)

Every player holds a direct connection to every other player. The signaling server establishes a connection for each pair when a peer joins.

  • Pros: no central game server, lowest latency between nearby players, no single point of failure, any peer can talk to any peer instantly.
  • Cons: connections grow as N·(N-1)/2, and each peer's upload scales with N. Comfortable up to ~16 players, workable toward ~32 with compact packets (broadcastAuto) and interest filtering (interestBroadcast). Not intended for large lobbies.

This is the right choice for most fast-paced, small-session games (the default maxPlayers is 4).

Star topology with an optional dedicated server peer

For games that need authoritative state, sensitive/secret information, or a reliable always-on host, you can run a dedicated node that joins the lobby as a peer and acts as the authority. Because the library runs headless under Node (the test suite uses @roamhq/wrtc), this "server" is just another netlib peer — on hardware you control, with a reliable connection.

        ┌─────────┐
        │  Host    │  ← dedicated server peer: owns authoritative
        │ (server) │    state, validates input, holds secrets
        └────┬─────┘
     ┌───────┼───────┐
   client  client  client   ← each client connects to the host
  • Authoritative state: the host owns canonical data (room membership, positions, scores) and is the source of truth.
  • Sensitive information: keep secret state only on the host (your server) and send each client just the slice it is allowed to see via per-peer send — never broadcast. Client browsers are untrusted; anything shipped to them is visible to the player. Datachannels are DTLS-encrypted end-to-end, so even a TURN relay or the signaling server never sees payloads.
  • Reliability: a dedicated host has a stable connection rather than a random player's home uplink.
  • Scaling: each client holds a single connection (to the host) instead of N-1, which sidesteps the mesh's connection growth — at the cost of the host's bandwidth becoming the bottleneck and being a single point of failure.

Note

The host is designated using the lobby leader. Today the leader is chosen by election; until pinned-leader support lands (see Roadmap), designate your dedicated host by convention — clients send authoritative actions to a known server peer id (available via network.currentLeader once the server is the leader). A hybrid is also possible: keep the player mesh for fast, non-sensitive traffic (e.g. position interpolation) while the host arbitrates anything authoritative or secret.

Self-Hosting

While Poki provides hosted STUN/TURN and signaling services for free, you can also self-host these components:

  1. Set up your own signaling server

    Using the provided Docker image:

    $ docker build -t netlib .
    $ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 -e ENV=local netlib

    Or by running the signaling server binary directly:

    $ go build -o signaling cmd/signaling/main.go
    $ ENV=local ./signaling
  2. For persistent storage remove ENV=local and set DATABASE_URL to your PostgreSQL database URL.

  3. Configure your own STUN/TURN servers.

  4. Initialize the network with custom endpoints:

const network = new Network('<game-id>', {
  signalingServer: 'wss://your-server.com',
  stunServer: 'stun:your-stun.com:3478',
  turnServer: 'turn:your-turn.com:3478'
})

Engine Integrations

Defold integration by IndieSoft.

Contributing

We welcome contributions! Please see our Contributing Guide for details. This project adheres to the Poki Vulnerability Disclosure Policy.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Main Contributors

About

Peer-to-peer WebRTC networking for web games — ProofNetworks-aligned: zero-config binary serialization, area-of-interest broadcasting, and flexible mesh/star topologies.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors