@onmuga/sdk

SDK for the Onmuga multi-player game platform

Usage no npm install needed!

<script type="module">
  import onmugaSdk from 'https://cdn.skypack.dev/@onmuga/sdk';
</script>

README

@onmuga/sdk

Onmuga client SDK

Quick Start

Installation

Using script tag

<script src="https://unpkg.com/@onmuga/sdk@0.0.7"></script>

The SdkClient will be available as window.onmuga.SdkClient

Using npm

Install the npm package

npm install --save @onmuga/sdk

Load into your project

// Using ES6 imports
import SdkClient from '@onmuga/sdk';

// Or, using require
var SdkClient = require('@onmuga/sdk');

Getting Started

// Initialize the SDK client for your game
const sdk = new SdkClient({
  apiKey: 'YOUR_API_KEY_HERE',
  game: 'yourgame',
});

sdk.on('gameStateChanged', (stateKey, state) => {
  // Re-render your app with new game state
});

sdk.on('usersChanged', (users) => {
  // You may want to re-render your user list here
  users.forEach(user => {
    // user == {
    //   connected: true,
    //   id: "ly3YHy5GZ9Pw",
    //   username: "foo"
    // }
  });
});

// Check if a username exists already from a previous sesssion
let username = sdk.getUsername();

if (!username) {
  username = window.prompt('Select a username');
  sdk.setUsername(username);
}

// Up to you to decide on how room IDs are stored in URL, then extract them appropriately
let roomId = getRoomFromUrl(window.location);
if (!roomId) {
  roomId = window.prompt('Enter a room ID or leave blank to create a new room');
}

if (!roomId) {
  sdk.createRoom(username).then(onJoinRoom);
} else {
  sdk.joinRoom(roomId, username).then(onJoinRoom);
}

function onJoinRoom(response) {
    console.log(`Joined room ${response.roomId}`);

    // We'll update game state here for illustrative purposes
    sdk.updateGameState('default', {
        ...sdk.getGameState('default'),
        newestUser: username,
    });
}

API Reference

new SdkClient(options)

Constructs a new SDK client. Your game should likely just contain one global instance of this.

options

  • apiKey - Onmuga platform public API key provided to you (string, required)
  • game - Lowercase idenitifer for your game e.g. "battle-snake" (string, required)

sdk.getRoom(): string|null

Return the room ID that the user is currently connected to

sdk.getUsername(): string|null

Return the current user's username (set via joinRoom or setUsername)

sdk.setUsername(username: string): Promise

Update the current user's username.

Returns a promise that will be rejected with an Error if the username was rejected for any reason.

sdk.getUserId(): string|null

Return the user ID associated with the user when they joined the room

sdk.getUsers(): User[]

Return the users in the current room. Each User has the following properties:

  • id - string
  • username - string
  • connected - boolean, whether the user is currently connected

sdk.getUserById(id: string): User|undefined

Return the specified User if they exist in the room. See getUsers for User shape.

sdk.createRoom(username?: string): Promise

Creates a new room, and adds the current user.

If username is not provided, the sdk will try using (1) any username from a previous setUsername(...) call, (2) username from a previous session, or (3) an auto-generated username like "RedSloth4".

Returns a promise that will be rejected in case of an error.

sdk.checkRoom(roomId: string): Promise<{success: boolean}>

Checks if a room with the given ID exists

Returns a promise that resolves to an object with the following properties:

  • success - boolean, true if room exists, false otherwise

sdk.joinRoom(roomId: string, username?: string): Promise

Joins the specified room.

If username is not provided, the sdk will try using (1) any username from a previous setUsername(...) call, (2) username from a previous session, or (3) an auto-generated username like "RedSloth4".

Returns a promise that will be rejected in case of an error joining the room.

sdk.getAllGameStates(): Object

Your game can have multiple states associated with it, each keyed by a unique string. This allows you to surgically update certain aspects of your game, without constantly re-rendering the whole game when the game state changes.

The schema of each state object is fully controlled by the developer.

sdk.getGameState(stateKey: string): Object

Return a specific game state object. The schema of these state objects is fully controlled by the developer.

stateKey - The game state object to retrieve

sdk.updateGameState(stateKey: string, state: Object): Promise

Update the game state for the specific key. State is a plain javascript object that the developer has full control over.

The server will then emit a gameStateChanged event for all users in the room.

Returns a promise that will be rejected in case of an error.

sdk.joinRoom(roomId: string, username?: string): Promise

Joins the specified room.

If username is not provided, it will use any username set in a previous session, or by an earlier setUsername call.

Returns a promise that will be rejected in case of an error joining the room.

sdk.on(eventName: string, callback: fn)

Listen to events emitted by the SDK, see event reference below

Callback may be passed data associated with the event

sdk.once(eventName: string, callback: fn)

Listen to an event one time – immediately removing the listener afterwards.

sdk.off(eventName: string, callback: fn)

Remove the specified listener for the specified event

sdk.broadcast(eventName: string, data?: JsonSerializable): Promise

Broadcast an arbitrary event (i.e. playerCheated) to every other user in the game. You can use sdk.on to listen for these messages.

Returns a promise that will be rejected in case of an error.

sdk.message(userId: string, eventName: string, data?: JsonSerializable): Promise

Broadcast an arbitrary event (i.e. playerCheated) to a specific user in the game.

Returns a promise that will be rejected in case of an error.

sdk.now(): number

Sometimes in games you may need to compare timestamps generated on different players devices (for example, to figure out which player took an action first). This can be problematic because the system clock on some player's devices is occasionally a couple minutes fast or slow.

Instead of using a native JS Date, you should use the now() method. This returns a unix epoch timestamp that is roughly synchronized to server time and will help achieve consistency across clients.

sdk.serverToClientTime(serverTime): number

Converts a timestamp returned by now() back into a timestamp that can be compared with the clients system time.

Event Reference

You can listen to these events using sdk.on/off(...)

gameStateChanged

The game state was updated by some user in the room (possibly the current user!)

Listeners are invoked with the following arguments:

  • stateKey: string - The state key associated with this game state (e.g. 'default')
  • gameState: object - The updated game state object
  • prevState: object - The previous game state object held by the client, useful for comparison
  • sourceUserId: string - ID of the user who triggered this state update

usersChanged

The list of users in the room has changed, either users joined or left or their metadata changed.

Listeners are passed an array of User objects (see getUsers() above for shape)

invalidApiKey

Will be emitted if the API key you used to construct SdkClient is invalid, or if the current hostname is unsupported.