Skip to main content

Low-level API

Under the hood, Paima Engine uses MQTT for its event system. MQTT was chosen because:

  1. It allows subscribing to realtime events based on a subset of filters (docs)
  2. It has websocket support for event streaming
  3. It allows QoS ("Quality of Service") level including guaranteed message delivery (docs - Paima sets a qos of 2 by default)
  4. It can scale with brokers optionally, but has an in-memory client for use-cases that don't need the scale (which Paima uses)

More concretely, when you define an event using Paima, indexed fields define the topic of the MQTT message and the non-indexed fields define the content

Example

For example, for the given event that defines quest completion in a game,

const QuestCompletionEvent = genEvent({
name: 'QuestCompletion',
fields: [
{
name: 'playerId',
type: Type.Integer(),
indexed: true,
},
{
name: 'questId',
type: Type.Integer(),
},
],
} as const);
  • The MQTT topic generated is game/playerId/{playerId} (ex: game/playerId/1)
  • The content of the MQTT messages is { questId: number }

Note that all events starts with a prefix depending on its origin (TopicPrefix):

  • app for events defined by the user
  • batcher for events coming from the batcher
  • node for events that come from the Paima Engine node

Manually writing MQTT

If you prefer to have more fine-grained controlled over the MQTT syntax (notably the way topics are generated), you can write events using the following direct form (internally, the event syntax gets converted down to this form)

export const Events = {
QuestCompletion: {
path: ["foo", "bar", { name: 'playerId', type: Type.Integer() }],
type: Type.Object({
questId: Type.Integer(),
}),
},
} as const satisfies Record<string, Omit<EventPathAndDef, 'broker'>>;

This example generates the topic app/foo/bar/{playerId}

Debugging

To debug MQTT calls to see if they work correctly, you can use the following tools

mqtt-client-cli

npm i -g mqtt-client-cli; # only need to install once

mqtt-client-cli ws://localhost:8883
# example subscription
sub node/block/#

mqtt.js

# subscribe to topic
mqtt sub -t 'node/block/#' -h 'ws://localhost:8883' -v
# public to topic
mqtt pub -t 'node/block/#' -h 'ws://localhost:8883' -m '{ msg: "test message" }'

See docs for the command line tool here