Quick start - Defold
Connect a Defold project to a running Asobi server in about five minutes. Don't have a server yet? Run the server quickstart first - it gives you a backend on localhost:8084 with a default match mode, which is what this page connects to.
1. Add the SDK as a library dependency
Open game.project → Project → Dependencies and add both the SDK (pinned to a release tag) and the WebSocket extension it needs:
https://github.com/widgrensit/asobi-defold/archive/refs/tags/v1.2.1.zip
https://github.com/defold/extension-websocket/archive/refs/tags/4.2.2.zipPin to a tag - main is unstable. Then Project → Fetch Libraries. The SDK shows up as asobi in your project tree.
2. Where this code lives
Put this on a .script attached to a game object that lives for the whole app - a script in your main.collection, not a gui_script. Defold invalidates the WebSocket callbacks when their owning script is unloaded, so a short-lived script drops your connection. Add main/boot.script and assign it to a game object in your main collection. It uses two Defold callbacks:
init(self)- runs once. Authenticate, wire up realtime handlers, and connect here.on_input(self, action_id, action)- runs when a bound input fires. Send match input here.
3. The complete boot.script
The whole flow - authenticate, connect, queue, join, receive state, send input - in one script. Note how everything after auth is nested inside the register callback: that is what keeps connect from racing ahead of your session.
local asobi = require("asobi.client")
function init(self)
-- Route input to this script's on_input (needs an input binding too).
msg.post(".", "acquire_input_focus")
-- Local engine: host, port. Use (host, 443, true) for a hosted env over SSL.
self.client = asobi.create("localhost", 8084)
-- Authenticate first. Everything else happens inside this callback,
-- once you actually have a session. The callback gets (data, err). A fresh
-- username each run - registering the same one twice returns 409 (below).
self.client.auth.register(self.client, "player_" .. math.random(100000, 999999),
"secret1234", nil, function(data, err)
if err then print("auth failed: " .. tostring(err.error)) return end
-- A match was formed. Join it before state starts flowing.
self.client.realtime:on("match_matched", function(payload)
self.client.realtime:join_match(payload.match_id)
end)
-- The server's authoritative tick. Update your game world here.
self.client.realtime:on("match_state", function(state)
-- e.g. move your player game objects from state
end)
-- connect() authenticates asynchronously; wait for "connected"
-- before queuing, or the queue races ahead of the session.
self.client.realtime:on("connected", function()
self.client.realtime:add_to_matchmaker("default")
end)
self.client.realtime:connect()
end)
end
function on_input(self, action_id, action)
-- Fires when a bound action changes. send_match_input is fire-and-forget.
if action_id == hash("right") and (action.pressed or action.repeated) then
self.client.realtime:send_match_input({action = "move", x = 1, y = 0})
end
end4. What each part does, and when
- Authenticate first (in init). The client is the first argument to every API call. Nest the rest inside the
registercallback so it only runs once you have a session. Registering a username that already exists returns409 username_taken- a real game registers once and callsloginon return (this quickstart uses a fresh random name each run). Auth is rate-limited to 5/sec per IP; production builds should use a platform provider (see Auth & rate limiting). - Queue only after "connected".
connect()authenticates asynchronously, so wait for theconnectedevent beforeadd_to_matchmaker("default"). The mode string must match a mode your server registers. - Join on match_matched. Queuing gets you matched; you then
join_match(payload.match_id). Without the join,match_statenever arrives. - Send input from on_input.
initcallsacquire_input_focusso this script receives input; bind therightaction in game.input_binding. The nextmatch_statereflects the server's authoritative response.
What's next
- Full SDK reference
- asobi-defold-demo - a working arena demo.
- game.* Lua API
- Live-edit your game