Docs / Learn / Install the SDK

Install the client SDK

Add the Asobi SDK for your engine, learn when it speaks REST versus WebSocket, and point it at your server - the app builds and imports the SDK.

In step 1 you booted the server bundle. Now you fit the other half: the client SDK your game talks to it with. This step installs the SDK and aims it at a server. You do not connect yet - that is step 3.

How and when the client talks

The SDK uses two transports, and it picks the right one for you.

  • REST (HTTP request/response). One-shot calls where you ask and wait for an answer: register, login, guest sign-in, read a leaderboard, load a cloud save. Used for anything that is not a live game frame.
  • WebSocket (realtime push). One long-lived connection for the game loop: you send intent (a move), the server decides, and the server pushes state back to every client. Match and world frames only arrive over the WebSocket.

The rule underneath both: the client sends intent, the server decides, the server broadcasts state. The client never mutates authoritative state directly.

REST comes first in every flow (you authenticate over REST to get a token), then you open the WebSocket. Step 3 covers the handshake; the full frame surface is in the WebSocket protocol guide.

Point the client at your server

This is the only place the client differs between managed cloud and self-hosting. Every SDK call after this - auth, match, world, input, state - is byte-for-byte identical on both. Only the base server URL changes.

  • Cloud (console.asobi.dev / asobi deploy): your environment gets a TLS hostname of the form {game}-{env}.{tenant}.asobi.dev, e.g. pong-prod.acme.asobi.dev, served over HTTPS/WSS on port 443. Copy it from the environment page in the console.
  • Self-hosted: your own release of asobi + asobi_lua on your own host, plain HTTP/WS on port 8084 by default, e.g. localhost:8084 in dev. See self-hosting and configuration for the ASOBI_* knobs.

Cloud means TLS on (use_ssl / useSsl / https/wss); self-host in dev means TLS off. Nothing else moves.

The tabs below are in this order: Defold, Godot, Unity, Unreal, Dart/Flame, JavaScript, LOVE.

Defold. Add both dependencies to game.project, then Project -> Fetch Libraries. Pin to a tag; main is unstable. Register realtime callbacks from a .script in main.collection - Defold invalidates the WS callback when its owning script unloads.

Godot. Copy addons/asobi/ into your project (or add as a submodule at a tag), then tick Asobi under Project Settings -> Plugins and reload. The plugin registers an Asobi autoload singleton. Point the autoload at your server; host, port, use_ssl are exported on the client.

Unity. Install via Window -> Package Manager -> + -> Add package from git URL. Create the client with new AsobiClient(host, port, useSsl). Realtime events fire on a background thread - marshal to the main thread before touching UnityEngine.Object. WebGL is not supported (the SDK uses ClientWebSocket).

Unreal. Clone into your project's Plugins/ directory, regenerate project files, then enable Asobi SDK under Edit -> Plugins -> Networking. Create the client and set the base URL (a full URL, scheme included).

Dart/Flame. Add the package (pure Dart, works with Flutter, Flame, and standalone Dart). Create the client with AsobiClient(host, {port, useSsl}).

JavaScript. Install from GitHub (builds via the package's prepare script). Node 22+ for the global WebSocket/fetch. asobi-js is a thin transport client: the REST/auth surface and the WebSocket take full URLs, so cloud versus self-host is just the scheme and host.

LOVE. Drop the asobi/ directory into your LÖVE project root, alongside main.lua. Pure Lua, no LuaRocks. For wss:// (cloud TLS) you need luasec on the path - LÖVE does not bundle it. Create the client with asobi.new({host, port, use_ssl}). client.realtime:update() must be called every frame from love.update(dt) once you reach the realtime steps, or no callbacks fire.

Add the dependency or package for your engine:

[project]
dependencies#0 = https://github.com/widgrensit/asobi-defold/archive/refs/tags/v1.2.1.zip
dependencies#1 = https://github.com/defold/extension-websocket/archive/refs/tags/4.2.2.zip
git submodule add -b v0.6.1 https://github.com/widgrensit/asobi-godot.git vendor/asobi-godot
ln -s ../vendor/asobi-godot/addons/asobi addons/asobi
https://github.com/widgrensit/asobi-unity.git
cd YourProject/Plugins
git clone https://github.com/widgrensit/asobi-unreal.git AsobiSDK
dart pub add asobi
npm install github:widgrensit/asobi-js
my_game/
├── main.lua
├── conf.lua
└── asobi/

Then create the client and point it at your server. Only the base URL changes:

local asobi = require("asobi.client")

local client = asobi.create("localhost", 8084)                       -- self-hosted
-- local client = asobi.create("pong-prod.acme.asobi.dev", 443, true)  -- cloud (TLS)
func _ready() -> void:
    Asobi.host = "localhost"     # self-hosted
    Asobi.port = 8084
    # Asobi.host = "pong-prod.acme.asobi.dev"  # cloud (TLS)
    # Asobi.port = 443
    # Asobi.use_ssl = true
using Asobi;

var client = new AsobiClient("localhost", port: 8084);                            // self-hosted
// var client = new AsobiClient("pong-prod.acme.asobi.dev", port: 443, useSsl: true); // cloud (TLS)
#include "AsobiClient.h"

UAsobiClient* Client = NewObject<UAsobiClient>();
Client->SetBaseUrl(TEXT("http://localhost:8084"));                 // self-hosted
// Client->SetBaseUrl(TEXT("https://pong-prod.acme.asobi.dev"));   // cloud (TLS)
import 'package:asobi/asobi.dart';

final client = AsobiClient('localhost', port: 8084);                             // self-hosted
// final client = AsobiClient('pong-prod.acme.asobi.dev', port: 443, useSsl: true); // cloud (TLS)
import { Asobi, AsobiWebSocket } from "@widgrensit/asobi";

const sdk = new Asobi({ baseUrl: "http://localhost:8084" });                      // self-hosted REST
const ws = new AsobiWebSocket({ url: "ws://localhost:8084/ws", token });          // self-hosted WS

// Cloud (TLS):
// const sdk = new Asobi({ baseUrl: "https://pong-prod.acme.asobi.dev" });
// const ws = new AsobiWebSocket({ url: "wss://pong-prod.acme.asobi.dev/ws", token });
local asobi = require("asobi")

local client = asobi.new({host = "localhost", port = 8084})                                  -- self-hosted
-- local client = asobi.new({host = "pong-prod.acme.asobi.dev", port = 443, use_ssl = true})  -- cloud (TLS)

Checkpoint

Build and run your project (or the editor) with the SDK added and the client created:

  • The SDK import resolves - no missing-package or missing-require error.
  • Constructing the client with your base URL compiles/runs and does not throw.

You should reach your first frame (or, for a console target, your first line) with the SDK linked in. If the import fails, re-check the install step for your engine above. No network call happens yet - creating the client does not open a connection.

Next: Step 3 - Connect, and prove it talks

Fire session.connect, wait for session.connected, and log connected, player_id=...