DocumentationCore Protocol

Quick Start

Get PaindaProtocol running and build a "Hello World" chat in under 2 minutes.

Installation

npm install @painda/core

Hello World Chat

Create a minimal server and client that exchange a single binary-framed message.

Server

import { PPServer } from '@painda/core';

const server = new PPServer({ port: 3000 });

server.on('connection', (client) => {
  client.on('message', (msg) => {
    console.log('Received:', msg);
    // DX shorthand — same as send({ type, payload })
    client.emit('hello', 'World');
  });
});

Client

import { PPClient } from '@painda/client';

const client = new PPClient({
  url: 'ws://localhost:3000',
});

// once() — auto-removes after first call
client.once('open', () => {
  // emit() shorthand
  client.emit('greet', 'Hello');
});

client.on('message', (msg) => {
  console.log('Server says:', msg.payload);
});

Typed Contracts

Register schemas for binary-native serialization with full TypeScript inference. No more JSON overhead.

import {
  PPServer, PPSchemaRegistry,
  structSerializer,
} from '@painda/core';

const registry = new PPSchemaRegistry();

registry.register('player:move',
  structSerializer(1, [
    { name: 'x', type: 'float32' },
    { name: 'y', type: 'float32' },
    { name: 'z', type: 'float32' },
  ])
);

const server = new PPServer({
  port: 3000,
  mode: 'gaming',
  registry,
});

server.on('connection', (client) => {
  client.on('message', (msg) => {
    if (msg.type === 'player:move') {
      const { x, y, z } = msg.payload;
      console.log(x, y, z);
    }
  });

  // 12 bytes instead of ~50+ JSON bytes
  client.emit('player:move',
    { x: 1.5, y: 0, z: -3.2 }
  );
});

The schema registry maps player:move to a compact 12-byte struct (3 x float32) instead of a ~50-byte JSON string. Unregistered types fall back to JSON automatically.

Next, explore PP.Chat for rooms and history, or The PP Header for the binary wire format.