CTRLLR

API Reference

Complete API documentation for @ctrllr/core.


CtrllrManager

Main manager class for handling controller connections.

Constructor

const ctrllr = new CtrllrManager(options: CtrllrManagerOptions);

Options

| Property | Type | Description | | --------------- | -------- | ------------------------------------- | | signalingUrl | string | WebSocket URL of the signaling server | | socketOptions | object | Optional socket.io client options |

Properties

| Property | Type | Description | | ------------- | ------------------------- | ------------------------------------- | | controllers | Map<number, Controller> | All currently connected controllers | | socketId | string \| null | Socket ID used for QR code generation |

Methods

connect()

Connect to the signaling server.

await ctrllr.connect(): Promise<void>

disconnect()

Disconnect from the signaling server and clean up all connections.

ctrllr.disconnect(): void

getController(index)

Get a specific controller by its index.

ctrllr.getController(index: number): Controller | undefined

getQRCodeDataURL(options?)

Generate a QR code as a data URL (base64 image).

await ctrllr.getQRCodeDataURL(options?: QRCodeOptions): Promise<string>

getQRCodeSVG(options?)

Generate a QR code as an SVG string.

await ctrllr.getQRCodeSVG(options?: QRCodeOptions): Promise<string>

setAdapter(adapter)

Set a custom signaling adapter.

ctrllr.setAdapter(adapter: SignalingAdapter): void

Events

Subscribe to events using ctrllr.on(event, handler) and unsubscribe with ctrllr.off(event, handler).

| Event | Payload | Description | | ------------------------ | -------------------------------------------------------------------- | ------------------------------------- | | controllerconnected | { controller: Controller } | A new controller has connected | | controllerdisconnected | { controller: Controller } | A controller has disconnected | | statechange | { controller: Controller, state: ControllerState } | Any controller's state changed | | buttondown | { controller: Controller, input: InputName, x: number, y: number } | Any button pressed on any controller | | buttonup | { controller: Controller, input: InputName, x: number, y: number } | Any button released on any controller |


Controller

Represents a single connected controller.

Properties

| Property | Type | Description | | ----------- | ----------------- | ------------------------------- | | index | number | Controller index (0, 1, 2, ...) | | userId | string \| null | User ID from the mobile app | | username | string \| null | Username from the mobile app | | state | ControllerState | Current input state | | connected | boolean | Connection status |

Methods

getInput(name)

Get the state of a specific input.

controller.getInput(name: InputName): InputState

isAnyButtonPressed()

Check if any button is currently pressed.

controller.isAnyButtonPressed(): boolean

Events

Subscribe to events using controller.on(event, handler) and unsubscribe with controller.off(event, handler).

| Event | Payload | Description | | ------------- | -------------------------------------------- | ---------------------------------------- | | statechange | { state: ControllerState } | Input state changed | | buttondown | { input: InputName, x: number, y: number } | Button pressed (edge: falsetrue) | | buttonup | { input: InputName, x: number, y: number } | Button released (edge: truefalse) |


Types

ControllerState

The complete state of a controller's inputs.

interface ControllerState {
  joystick: InputState; // Left analog stick
  a: InputState; // Aimable button A
  x: InputState; // Aimable button X
  y: InputState; // Aimable button Y
  z: InputState; // Aimable button Z
}

InputState

The state of a single input (joystick or button).

interface InputState {
  pressed: boolean; // Is the input active
  x: number; // Horizontal axis (-1 to 1)
  y: number; // Vertical axis (-1 to 1)
}

InputName

Valid input names.

type InputName = 'joystick' | 'a' | 'x' | 'y' | 'z';

QRCodeOptions

Options for QR code generation.

interface QRCodeOptions {
  width?: number; // Size in pixels (default: 256)
  margin?: number; // Margin in modules (default: 2)
  darkColor?: string; // Foreground color (default: '#000000')
  lightColor?: string; // Background color (default: '#ffffff')
}

CtrllrManagerOptions

Options for the CtrllrManager constructor.

interface CtrllrManagerOptions {
  signalingUrl: string; // WebSocket URL of signaling server
  socketOptions?: object; // Optional socket.io options
}

SignalingAdapter

Interface for implementing custom signaling adapters.

interface SignalingAdapter {
  readonly socketId: string | null;
  connect(): Promise<void>;
  disconnect(): void;
  onPeerConnected(
    cb: (peerId: string, peer: SimplePeer.Instance) => void
  ): void;
  onPeerDisconnected(cb: (peerId: string) => void): void;
}

Example Custom Adapter

import { SignalingAdapter, CtrllrManager } from '@ctrllr/core';
import SimplePeer from 'simple-peer';

class MyAdapter implements SignalingAdapter {
  get socketId(): string | null {
    // Return your socket/session ID
  }

  async connect(): Promise<void> {
    // Connect to your signaling server
  }

  disconnect(): void {
    // Disconnect and clean up
  }

  onPeerConnected(
    cb: (peerId: string, peer: SimplePeer.Instance) => void
  ): void {
    // Call cb when a new peer connects
  }

  onPeerDisconnected(cb: (peerId: string) => void): void {
    // Call cb when a peer disconnects
  }
}

// Usage
const ctrllr = new CtrllrManager({ signalingUrl: '' });
ctrllr.setAdapter(new MyAdapter());
await ctrllr.connect();

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  Game App       │     │ Signaling Server │     │ Mobile App      │
│  (@ctrllr/core) │     │ (socket.io)      │     │ (Controller)    │
└────────┬────────┘     └────────┬─────────┘     └────────┬────────┘
         │                       │                        │
         │◄──── 1. Connect ─────►│◄──── 2. Connect ──────►│
         │                       │                        │
         │ 3. Get socket ID      │                        │
         │ 4. Show QR code ──────┼───────► 5. Scan QR     │
         │                       │                        │
         │◄─────────────── 6. WebRTC Signaling ──────────►│
         │                       │                        │
         │◄═══════════════ 7. WebRTC DataChannel ════════►│
         │                       │                        │
         │◄─────────── 8. Controller Input ──────────────│

The SDK uses WebRTC DataChannels for low-latency peer-to-peer communication between the game and mobile controllers. The signaling server is only used for initial connection setup.