Skip to content

widgrensit/asobi_lua

Repository files navigation

asobi

asobi_lua

Open-source game backend. Write it in Lua. Hot-reload without restart. Apache-2.

Docker Release CI License

DocsLive demoDiscordIssues

asobi_lua hot-reload: edit a Lua file, save, live match updates — no restart
Edit a Lua file. Save. Live match updates. No restart. Try it.


What is asobi_lua?

A batteries-included multiplayer game backend you write in Lua, packaged as a single Docker image. You get auth, matchmaking, rooms, leaderboards, economy, chat, tournaments, voting, parties, phases and seasons, reconnection, and WebSocket + REST out of the box — and SDKs for Godot, Defold, Unity, Unreal, JS/TS, and Flutter.

No Erlang knowledge required. Your match logic is a .lua file. Save it and connected clients see the change — no restart, no redeploy.

-- lua/match.lua
match_size = 2

function init(config)
  return { players = {}, tick_count = 0 }
end

function join(player_id, state)
  state.players[player_id] = { x = 400, y = 300, hp = 100 }
  return state
end

function handle_input(player_id, input, state)
  local p = state.players[player_id]
  if input.right then p.x = p.x + 5 end
  if input.left  then p.x = p.x - 5 end
  if input.shoot then
    game.broadcast("shot", { by = player_id, at = input.aim })
  end
  return state
end

function tick(state)
  state.tick_count = state.tick_count + 1
  return state
end

That's a full playable room. Save the file, the match reloads in place.

Quick Start

1. Create the project layout

mkdir my_game && cd my_game
mkdir -p lua
# paste the match.lua above into lua/match.lua

2. Bring up Postgres + asobi_lua

# docker-compose.yml
services:
  postgres:
    image: postgres:17
    environment: { POSTGRES_USER: postgres, POSTGRES_PASSWORD: postgres, POSTGRES_DB: my_game }
    healthcheck: { test: ["CMD-SHELL", "pg_isready -U postgres"], interval: 5s }

  asobi:
    image: ghcr.io/widgrensit/asobi_lua:latest
    depends_on: { postgres: { condition: service_healthy } }
    ports: ["8080:8080"]
    volumes: ["./lua:/app/game:ro"]
    environment: { ASOBI_DB_HOST: postgres, ASOBI_DB_NAME: my_game }
docker compose up -d

3. Register a player and join a match

# Register
curl -s localhost:8080/api/v1/auth/register \
  -H 'content-type: application/json' \
  -d '{"username":"alice","password":"hunter2"}'
# → { "token": "eyJ...", "player_id": "01HX..." }

# Queue for matchmaking
curl -s localhost:8080/api/v1/matchmaker/tickets \
  -H 'authorization: Bearer eyJ...' \
  -d '{"mode":"default"}'
# → { "ticket_id": "...", "status": "searching" }

Connect the WebSocket from any SDK below and the client is live. Edit lua/match.lua, save, and the running match picks up the change — players stay connected, state is preserved.

Why asobi

  • Hot-reload Lua — push a fix at 11pm, your live match keeps playing. No restart, no dropped sockets.
  • 🎮 Every engine — first-class SDKs for Godot, Defold, Unity, Unreal, plus JS/TS and Flutter.
  • 🧠 Batteries included — matchmaker (fill + skill), rooms, economy, inventory, leaderboards, tournaments, chat, social, notifications, IAP, voting with 4 methods (plurality, ranked, approval, weighted), phases, seasons, reconnection.
  • 🗺️ Large-world ready — spatial zones, lazy zone loading, terrain chunks, adaptive tick rates. Single-node by design; shard at the app level.
  • 🚀 83,000 msg/sec sustained at 3,500 concurrent WebSockets, 4.4ms p50 RTT — see benchmarks.
  • 🛡️ Apache-2, self-host — use commercially, fork it, run it yourself. We will never relicense. Exit guaranteed →
  • 🇪🇺 Made in the EU — GDPR-ready, NIS2-aware, no US cloud lock-in.
  • 🔒 OTP fault tolerance — one match crashing never touches any other match. No GC pauses during gameplay.

Client SDKs

Engine Install Docs Sample
Godot 4.x widgrensit/asobi-godot guide asobi-godot-demo
Defold widgrensit/asobi-defold guide asobi-defold-demo
Unity 2021.3+ com.asobi.sdk (UPM via git URL) guide asobi-unity-demo
Unreal 5 widgrensit/asobi-unreal guide
JS / TS widgrensit/asobi-js guide
Flutter dart pub add asobi guide asobi-flame-demo
Flame (Flutter) widgrensit/flame_asobi guide asobi-flame-demo

How it works

  your Lua scripts (mounted at /app/game)
        │
        ▼
  asobi_lua          ── Luerl VM + bridge modules + bot runtime
        │
        ▼
  asobi (library)    ── OTP supervision, pg groups, rate limits, sessions
        │
        ▼
  Nova + Kura + PostgreSQL

Every match and world runs as its own BEAM process under a supervisor. Luerl executes your Lua inside the BEAM — no sub-process, no sandbox escape, no GC pauses. Hot reload swaps the Luerl module while match state stays in the process heap.

Note

asobi_lua is pre-1.0. The API is stabilising; expect minor breaking changes until 1.0. We ship in lockstep with the asobi library (Hex.pm) and version SDKs against server tags.

Self-host, today

Run the image wherever you like — Hetzner, Scaleway, Fly, Clever, a Raspberry Pi, your laptop. The image is ~120MB, cold starts in <3s, and holds thousands of WebSockets on a single vCPU. Full deployment guide at asobi.dev/docs/deploy.

A managed cloud at asobi.dev is opening later in 2026 — same binary, flat per-container pricing, never CCU-based. Learn more →.

Migrating?

  • from Hathora — rooms → matches, serverless processes → container. Hathora shuts down 2026-05-05.
  • from PlayFab — Titles, CloudScript, Virtual Currency mapped.
  • from Nakama self-host — keep your Lua runtime, lose CockroachDB.

Documentation

Community

  • 💬 Discord — chat with the team and other devs
  • 🗣️ GitHub Discussions — Q&A, show-and-tell, RFCs
  • 🐛 Issues — bug reports and feature requests
  • 📦 Releases — changelog and release notes

Using asobi_lua as an Erlang library

If you're already writing Erlang/OTP and want Lua scripting as a dep:

%% rebar.config
{deps, [
    {asobi_lua, {git, "https://github.com/widgrensit/asobi_lua.git", {tag, "v0.1.0"}}}
]}.

Configure game modes in your sys.config — see guides/lua-scripting.md.

Game-server authors writing Erlang directly should depend on the core library at widgrensit/asobi instead.

License

Apache-2.0. See LICENSE.

About

Lua scripting runtime for Asobi — game logic in Lua, powered by Luerl on BEAM

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors