{"id":47732890,"url":"https://github.com/widgrensit/asobi","last_synced_at":"2026-04-26T11:01:51.074Z","repository":{"id":347549056,"uuid":"1194419542","full_name":"widgrensit/asobi","owner":"widgrensit","description":"Game backend platform built on Nova/OTP","archived":false,"fork":false,"pushed_at":"2026-04-20T17:50:36.000Z","size":659,"stargazers_count":10,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-20T19:38:07.740Z","etag":null,"topics":["asobi","beam","erlang","game-backend","gamedev","leaderboards","lua","luerl","matchmaking","multiplayer","nova","otp","realtime","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/widgrensit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T10:31:53.000Z","updated_at":"2026-04-20T17:50:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"2adfd6a2-1041-4bac-9d53-d40a661a17e0","html_url":"https://github.com/widgrensit/asobi","commit_stats":null,"previous_names":["widgrensit/asobi"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/widgrensit/asobi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/widgrensit%2Fasobi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/widgrensit%2Fasobi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/widgrensit%2Fasobi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/widgrensit%2Fasobi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/widgrensit","download_url":"https://codeload.github.com/widgrensit/asobi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/widgrensit%2Fasobi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32294591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T09:34:17.070Z","status":"ssl_error","status_checked_at":"2026-04-26T09:34:00.993Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asobi","beam","erlang","game-backend","gamedev","leaderboards","lua","luerl","matchmaking","multiplayer","nova","otp","realtime","websocket"],"created_at":"2026-04-02T21:58:21.127Z","updated_at":"2026-04-26T11:01:51.068Z","avatar_url":"https://github.com/widgrensit.png","language":"Erlang","readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/media/logo-dark.png\"\u003e\n    \u003cimg src=\"docs/media/logo.png\" alt=\"asobi\" height=\"120\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003easobi\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eMultiplayer game backend on Erlang/OTP. Hot-reloadable, Apache-2.\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://hex.pm/packages/asobi\"\u003e\u003cimg alt=\"Hex.pm\" src=\"https://img.shields.io/hexpm/v/asobi.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://hexdocs.pm/asobi\"\u003e\u003cimg alt=\"Hexdocs\" src=\"https://img.shields.io/badge/hex-docs-green\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/widgrensit/asobi/actions/workflows/ci.yml\"\u003e\u003cimg alt=\"CI\" src=\"https://github.com/widgrensit/asobi/actions/workflows/ci.yml/badge.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-Apache--2.0-blue.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://asobi.dev/docs\"\u003eDocs\u003c/a\u003e •\n  \u003ca href=\"https://asobi.dev/demo\"\u003eLive demo\u003c/a\u003e •\n  \u003ca href=\"https://discord.gg/vYSfYYyXpu\"\u003eDiscord\u003c/a\u003e •\n  \u003ca href=\"https://github.com/widgrensit/asobi/issues\"\u003eIssues\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/media/hotreload-demo.gif\" alt=\"asobi hot-reload: edit a Lua file, save, live match updates — no restart\" width=\"800\"\u003e\n  \u003cbr\u003e\n  \u003cem\u003eEdit a Lua file. Save. Live match updates. No restart. \u003ca href=\"examples/hotreload-demo/\"\u003eTry it.\u003c/a\u003e\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n## Who it's for\n\nSolo devs and small teams building **indie 2D multiplayer**. If you're on\nGodot, Defold, LÖVE, Phaser, or Flame+Flutter, asobi ships the backend\npieces you'd otherwise rebuild from scratch: matches, matchmaker, chat,\nleaderboards, economy, voting, phases, worlds, presence, inventory.\n\nNot the right fit for twitch-latency AAA shooters — WebSocket/TCP has a\nfloor around 4ms. Great for turn-based, casual, MMO zone, roguelike,\nco-op, party, and social games.\n\n## Try it in 60 seconds\n\n```bash\ngit clone https://github.com/widgrensit/asobi\ncd asobi/examples/hotreload-demo \u0026\u0026 docker compose up\n```\n\nOpen \u003chttp://localhost:3000\u003e, then edit `lua/match.lua` and save — the\nrunning match updates live. No restart, no reconnect, no kicked players.\n\n## Two ways to use asobi\n\n**Write your game in Lua** — use the [**asobi_lua**](https://github.com/widgrensit/asobi_lua)\nDocker runtime. One container, hot-reloadable Lua match scripts, batteries\nincluded. No Erlang required. **This is what most people want.**\n\n**Write your game in Erlang** — depend on this library directly. You get the\nsame match supervisor, matchmaker, leaderboards, economy, world server, and\nvoting primitives, implemented as OTP behaviours you compose with the rest of\nyour release.\n\n```erlang\n%% rebar.config\n{deps, [\n    {asobi, \"~\u003e 0.1\"}\n]}.\n```\n\n## Features\n\n- **`asobi_match`** — behaviour for per-match logic, backed by a supervised `gen_server` with ETS state backup on crash.\n- **`asobi_matchmaker`** — pluggable strategies (`fill`, `skill_based`); your own via the `asobi_matchmaker_strategy` behaviour.\n- **`asobi_world_server`** — persistent worlds with lazy zones, spatial grid indexing, terrain chunk serving, adaptive tick rates.\n- **`asobi_vote_server`** — plurality, ranked choice, approval, weighted. Fixed / ready-up / hybrid / adaptive windows. Spectator voting, veto tokens, majority-tyranny mitigations.\n- **`asobi_phase`, `asobi_season_manager`, `asobi_timer`** — phase engine, season lifecycles, five timer primitives.\n- **Rate limiting** via `seki` (sliding window, per route group), **sessions** cached in ETS, **presence** via `pg`, **chat / social / economy / inventory / storage / tournaments / notifications** as Nova controllers.\n- **Client SDKs** for Godot, Defold, Unity, Unreal, JS/TS, Dart, Flame — [see below](#client-sdks).\n\n## Benchmarks\n\nSingle node, 8 cores, same-machine client. See [guides/benchmarks.md](guides/benchmarks.md) for full numbers.\n\n| | Peak |\n|---|---|\n| WebSocket throughput | **83,000 msg/sec** @ 3,500 concurrent connections |\n| RTT p50 / p99 | 4.4 ms / 6.5 ms |\n| REST reads (matches / friends / wallets) | 7–14 ms p50 |\n| Memory per connection | ~15 KB |\n\nNot a twitch-FPS backend — WebSocket/TCP has a latency floor. Excellent for\nturn-based, casual, MMO zone, roguelike, co-op, and party games. Pair with a\nUDP relay if you need sub-3ms physics.\n\n## Client SDKs\n\n| Engine | Package | Docs | Example |\n|---|---|---|---|\n| **Godot 4.x** (GDScript) | [asobi-godot](https://github.com/widgrensit/asobi-godot) | [Guide](https://asobi.dev/godot) | [Demo](https://github.com/widgrensit/asobi-godot-demo) |\n| **Defold** (Lua) | [asobi-defold](https://github.com/widgrensit/asobi-defold) | [Guide](https://asobi.dev/defold) | [Demo](https://github.com/widgrensit/asobi-defold-demo) |\n| **LÖVE** (Lua) | _asobi-love — ships May 2026_ | — | — |\n| **Phaser** (TypeScript) | _asobi-phaser — ships May 2026_ | — | — |\n| **Unity 2021.3+** (C#) | [asobi-unity](https://github.com/widgrensit/asobi-unity) | [Guide](https://asobi.dev/unity) | [Demo](https://github.com/widgrensit/asobi-unity-demo) |\n| **Unreal Engine 5** (C++) | [asobi-unreal](https://github.com/widgrensit/asobi-unreal) | — | — |\n| **TypeScript / JS** (Browser + Node) | [asobi-js](https://github.com/widgrensit/asobi-js) | — | — |\n| **Dart / Flutter** | [asobi-dart](https://github.com/widgrensit/asobi-dart) | [Guide](https://asobi.dev/dart) | — |\n| **Flame** (Flutter) | [flame_asobi](https://github.com/widgrensit/flame_asobi) | — | [Demo](https://github.com/widgrensit/asobi-flame-demo) |\n\n## Documentation\n\n- [**Getting started**](guides/getting-started.md) — stand up a local asobi node from Erlang\n- [**Architecture**](guides/architecture.md) — supervision tree, modules, design\n- [**REST API**](guides/rest-api.md) · [**WebSocket protocol**](guides/websocket-protocol.md)\n- [**Matchmaking**](guides/matchmaking.md) · [**Voting**](guides/voting.md) · [**World server**](guides/world-server.md) · [**Large worlds**](guides/large-worlds.md)\n- [**Economy**](guides/economy.md) · [**Authentication**](guides/authentication.md) · [**IAP**](guides/iap.md)\n- [**Lua scripting**](guides/lua-scripting.md) · [**Lua bots**](guides/lua-bots.md)\n- [**Configuration**](guides/configuration.md) · [**Clustering**](guides/clustering.md) · [**Performance tuning**](guides/performance-tuning.md)\n- [**Benchmarks**](guides/benchmarks.md) · [**Comparison vs Nakama / Colyseus / SpacetimeDB**](guides/comparison.md)\n- [**HexDocs**](https://hexdocs.pm/asobi) — full API reference\n\n## Migrating?\n\n- [**from Hathora**](guides/migrate-from-hathora.md) — Hathora shuts down 2026-05-05.\n- [**from PlayFab**](guides/migrate-from-playfab.md)\n- [**from Nakama self-host**](guides/migrate-from-nakama.md)\n\n## Related projects\n\n- [**asobi_lua**](https://github.com/widgrensit/asobi_lua) — Lua scripting runtime + Docker image (`ghcr.io/widgrensit/asobi_lua`)\n- [**asobi-cli**](https://github.com/widgrensit/asobi-cli) — deploy, manage, and scaffold games\n- [**asobi_admin**](https://github.com/widgrensit/asobi_admin) — admin dashboard\n- Client SDKs: [asobi-godot](https://github.com/widgrensit/asobi-godot) · [asobi-defold](https://github.com/widgrensit/asobi-defold) · [asobi-unity](https://github.com/widgrensit/asobi-unity) · [asobi-unreal](https://github.com/widgrensit/asobi-unreal) · [asobi-js](https://github.com/widgrensit/asobi-js) · [asobi-dart](https://github.com/widgrensit/asobi-dart) · [flame_asobi](https://github.com/widgrensit/flame_asobi)\n\n## Stability\n\n\u003e [!NOTE]\n\u003e asobi is pre-1.0. The API is stabilising; expect minor breaking changes\n\u003e until 1.0. We will never relicense — see [guides/exit.md](guides/exit.md)\n\u003e for the \"if asobi disappears tomorrow\" runbook.\n\n## Run it yourself, or use the cloud\n\nasobi is Apache-2 and self-hostable. One Docker container runs the full\nstack — see [`docker-compose.example.yml`](docker-compose.example.yml) for\na production-shaped setup with Postgres.\n\nDon't want to operate it? [**asobi.dev/cloud**](https://asobi.dev/cloud)\nis the managed version — €9/mo Indie tier, EU-sovereign, same open-source\ncore. If we ever pivot, you still have the code — see\n[guides/exit.md](guides/exit.md).\n\n## FAQ\n\n**Does asobi replace Nakama / Colyseus / PlayFab?**\nFor the indie-2D multiplayer slot, yes. For AAA shooters needing\nper-match dedicated UDP servers, no — pair asobi with a UDP relay.\n\n**Can I write my game logic in something other than Lua?**\nYes. Depend on asobi as an Erlang library and write match code in Erlang,\nor call the REST/WebSocket API from any language. Lua is the easy mode.\n\n**Does it scale across machines?**\nasobi is single-node by design — one BEAM node handles tens of thousands\nof connections. Shard at the app level (game-per-node, region-per-node),\ndon't try to cluster a single match across hosts.\n\n**What happens if asobi disappears?**\nApache-2, single-binary deploy, Postgres backing store. Nothing in your\nstack is load-bearing on us. See [guides/exit.md](guides/exit.md).\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the build setup, pre-push\nchecklist, and test matrix. Security issues: see [SECURITY.md](SECURITY.md).\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwidgrensit%2Fasobi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwidgrensit%2Fasobi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwidgrensit%2Fasobi/lists"}