Open-source game backend platform built on Erlang/OTP and the Nova ecosystem.
Asobi provides everything you need to build and run multiplayer games: authentication, player management, real-time multiplayer, matchmaking, leaderboards, virtual economy, social features, and background jobs -- all in a single BEAM release.
- Authentication -- register, login, session tokens via nova_auth
- Player Management -- profiles, stats, metadata
- Real-Time Multiplayer -- WebSocket transport, server-authoritative game loop with configurable tick rate
- Matchmaking -- query-based matching with skill windows and party support
- Leaderboards -- ETS-backed for microsecond reads, PostgreSQL for persistence
- Virtual Economy -- wallets, transactions, item definitions, store, inventory
- Social -- friends, groups/guilds, chat channels, presence, notifications
- Tournaments -- scheduled competitions with entry fees and rewards
- Cloud Saves -- per-slot save data with optimistic concurrency
- Generic Storage -- key-value storage with permissions (public/owner/none)
- Background Jobs -- powered by Shigoto
- Admin Dashboard -- real-time LiveView console via Arizona
No Erlang needed. Just Lua scripts and Docker.
mkdir my_game && cd my_game
mkdir -p lua/botsWrite your game logic in Lua:
-- lua/match.lua
match_size = 2
max_players = 4
strategy = "fill"
function init(config)
return { players = {} }
end
function join(player_id, state)
state.players[player_id] = { x = 400, y = 300, hp = 100 }
return state
end
function leave(player_id, state)
state.players[player_id] = nil
return state
end
function handle_input(player_id, input, state)
local p = state.players[player_id]
if not p then return state end
if input.right then p.x = p.x + 5 end
if input.left then p.x = p.x - 5 end
return state
end
function tick(state)
return state
end
function get_state(player_id, state)
return { players = state.players }
endAdd a docker-compose.yml:
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: my_game_dev
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
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_devdocker compose up -dThat's it. Your game backend is running with authentication, matchmaking, WebSocket transport, and everything else handled by Asobi.
For Erlang/OTP developers who want full control, add asobi as a dependency:
{deps, [
{asobi, "~> 0.1"}
]}.Implement the asobi_match behaviour:
-module(my_arena_game).
-behaviour(asobi_match).
-export([init/1, join/2, leave/2, handle_input/3, tick/1, get_state/2]).
init(_Config) ->
{ok, #{players => #{}}}.
join(PlayerId, #{players := Players} = State) ->
{ok, State#{players => Players#{PlayerId => #{x => 0, y => 0}}}}.
leave(PlayerId, #{players := Players} = State) ->
{ok, State#{players => maps:remove(PlayerId, Players)}}.
handle_input(_PlayerId, _Input, State) ->
{ok, State}.
tick(State) ->
{ok, State}.
get_state(_PlayerId, #{players := Players}) ->
Players.Register it in sys.config and start with rebar3 shell.
See the Getting Started guide for the full walkthrough.
| Layer | Technology |
|---|---|
| HTTP / REST | Nova (Cowboy) |
| WebSocket | Nova WebSocket (Cowboy) |
| Database / ORM | Kura (PostgreSQL via pgo) |
| Real-time UI | Arizona |
| Authentication | nova_auth |
| Background Jobs | Shigoto |
| Pub/Sub | OTP pg module |
The BEAM VM is uniquely suited for game backends:
- Per-process GC -- no global pauses; one match collecting garbage never affects another
- Fault tolerance -- OTP supervision restarts crashed matches without affecting others
- Hot code upgrade -- deploy game logic changes without disconnecting players
- Native clustering -- distributed Erlang handles cross-node messaging with no external coordination
- 500K+ connections per node -- dramatically lower infrastructure costs
- No external state stores -- ETS replaces Redis,
pgreplaces pub/sub services
Full documentation is available on HexDocs.
- Getting Started -- Lua (Docker) or Erlang setup
- Lua Scripting -- write game logic in Lua
- Bots -- add AI-controlled players
- Configuration -- all configuration options
- REST API -- full API reference
- WebSocket Protocol -- real-time message types
- Matchmaking -- query-based player matching
- Economy -- wallets, items, and store
- Architecture -- system design
Apache-2.0