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_luaon your own host, plain HTTP/WS on port 8084 by default, e.g.localhost:8084in dev. See self-hosting and configuration for theASOBI_*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.zipgit submodule add -b v0.6.1 https://github.com/widgrensit/asobi-godot.git vendor/asobi-godot
ln -s ../vendor/asobi-godot/addons/asobi addons/asobihttps://github.com/widgrensit/asobi-unity.gitcd YourProject/Plugins
git clone https://github.com/widgrensit/asobi-unreal.git AsobiSDKdart pub add asobinpm install github:widgrensit/asobi-jsmy_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 = trueusing 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-
requireerror. - 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=...