feat: merge the asobi_lua runtime into asobi (wave 1a) - #339
Merged
Conversation
Moves the Lua runtime, bots and their tests out of widgrensit/asobi_lua and
into this repo as an in-tree subsystem. Module names are unchanged, so a
game's Lua scripts and any Erlang caller keep working against the same API.
- src/lua/ holds the runtime, src/lua/bots/ the bot processes, include/ the
bots header, test/fixtures/lua/ the script fixtures.
- luerl becomes a direct dep and an entry in asobi.app.src applications.
- asobi_lua_app is gone; asobi_sup now supervises the game-config load and
asobi_lua_sup as its last two children, which is exactly where they ran
when asobi_lua was a separate application started after asobi.
- asobi_lua_env keeps reading the legacy `{asobi_lua, ...}` app-env keys and
falls back to `{asobi, ...}`, so no existing sys.config silently goes dead
now that the asobi_lua application no longer exists.
- guides: the lua-scripting / lua-bots stubs are replaced by the real
content they pointed at; sandbox, trust-model and self-hosting move in;
asobi_lua's known-limitations lands as security-lua-known-limitations.md
so it does not overwrite the core page of the same name.
Taure
added a commit
that referenced
this pull request
Aug 4, 2026
… hits #337 wrapped the match-result write in asobi_repo:transaction/1 so the match record and the player_stats bump land together. #339 brought asobi_lua_SUITE across from the asobi_lua repo, where it mocks asobi_repo strictly and stubs only insert/1,2. Together, the finish path calls asobi_repo:transaction/1 on a strict mock that has no such function, the call is undef, the match server dies mid-finish, and the suite reports match_did_not_finish - naming the symptom and not the cause. Two tests, on main and on every branch cut from it. The suite runs without a repo pool, so transaction/1 runs the fun inline rather than passthrough reaching for a database that is not there. record_match/2 is stubbed too: stats persistence has its own tests and this suite is the Lua match lifecycle.
Taure
added a commit
that referenced
this pull request
Aug 4, 2026
* fix: register the Lua game-mode providers at application start #333 inverted mode resolution so asobi_game_modes resolves {lua, Script} through a provider registry instead of hardcoded asobi_lua_* atoms, and returns lua_runtime_unavailable when a kind has no provider. The writer was asobi_lua's own application-start callback. #339 then merged the Lua runtime into asobi and removed that application without moving the registration, so nothing ever populated the registry: every Lua mode resolved to lua_runtime_unavailable. Both PRs were green on their own base and red together, which is why main went red on merge. Register from asobi_app:start/2, ahead of the supervision tree so the matchmaker cannot observe an empty registry. The mapping itself lives in asobi_lua_sup next to the bridges, so asobi_game_modes still knows nothing about the scripting runtime, and tests that resolve a lua mode without booting the application call the same function. asobi_lua_config_tests now registers in its fixture and unregisters in teardown; asobi_game_modes_tests:lua_without_provider establishes the absence it asserts on rather than inheriting it from module order. * fix: stub the transaction path asobi_lua_SUITE's strict repo mock now hits #337 wrapped the match-result write in asobi_repo:transaction/1 so the match record and the player_stats bump land together. #339 brought asobi_lua_SUITE across from the asobi_lua repo, where it mocks asobi_repo strictly and stubs only insert/1,2. Together, the finish path calls asobi_repo:transaction/1 on a strict mock that has no such function, the call is undef, the match server dies mid-finish, and the suite reports match_did_not_finish - naming the symptom and not the cause. Two tests, on main and on every branch cut from it. The suite runs without a repo pool, so transaction/1 runs the fun inline rather than passthrough reaching for a database that is not there. record_match/2 is stubbed too: stats persistence has its own tests and this suite is the Lua match lifecycle.
Taure
added a commit
to widgrensit/asobi_lua
that referenced
this pull request
Aug 4, 2026
* chore: retire asobi_lua to a Docker alias for asobi The Lua runtime moved into asobi (widgrensit/asobi#339). asobi main now defines 16 of this repo's 17 modules, so any asobi pin at or past that merge makes the release unbuildable: ===> Error generating release: Duplicated modules: asobi_lua_game_error specified in asobi and asobi_lua asobi_lua_dev_errors specified in asobi and asobi_lua Urgent part: .github/workflows/bump-asobi-pin.yml ran daily and moved the pin to asobi main unattended. The next run would have hit exactly that error and left ghcr.io/widgrensit/asobi_lua unpublishable. It is deleted, not paused. The published image keeps building. It is now an alias: same name, same tags, same bin/asobi_lua entrypoint, same port, same environment, but the release is assembled from asobi alone, whose own supervision tree starts the Lua runtime. Nothing changes for anyone running it. - Delete src/, include/ and test/ - all duplicated by asobi. Only asobi_lua_app.erl was unique, and asobi_sup already does its job. - Pin asobi to the v0.51.4 tag rather than a branch, since nothing bumps it automatically any more. - Replace the erlang-ci delegation with a release build plus an assertion that no Lua module ships twice. Delete the nightly property soak; its suites moved. - Close the tracker to new issues via .github/ISSUE_TEMPLATE/config.yml redirecting to widgrensit/asobi. Existing issues stay open and readable. - Deprecation notice at the top of README, plus AGENTS.md and SECURITY.md. * chore(deps): pin asobi v0.53.0, the release carrying the ported fixes v0.51.4 predated widgrensit/asobi#353, which ported the four commits that landed in this repo after the merge snapshot was taken. Publishing the alias against v0.51.4 would have shipped an image missing asobi_lua#131, #132, #133 and #134 - exactly the regression this retirement was held back to avoid. Verified in the assembled prod release: asobi-0.53.0 is the only asobi lib, each shared module ships exactly once, and the three code fixes are present in the fetched dependency source.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wave 1a of the asobi_lua merge. One-way move of the Lua runtime, bots, tests
and guides out of
widgrensit/asobi_luaand into this repo. No module wasrenamed -
asobi_lua_*andasobi_bot_*keep their names, so game scriptsand Erlang callers are unaffected.
asobi_luathe repo is untouched,asobi_engineis untouched, nothing waspublished.
What was broken / what had to change
Three things could not survive a plain file copy.
1.
asobi_lua_app.erlwas an application callback for an application thatno longer exists.
asobi_lua_app.erl:8-19loaded the game config and thenstarted
asobi_lua_sup. Both had to move somewhere, and where matters:because
asobi_luadepended onasobi, it started second, so the config loadlanded after every
asobi_supchild was already up.That ordering is load-bearing in a bad way.
asobi_guest_reaper:start_link/0(
src/asobi_guest_reaper.erl:26) readsguest_authand returnsignorewhenit is false - and
asobi_lua_config:apply_guest_auth/1(
src/lua/asobi_lua_config.erl:126) is what sets it, always too late. That isexactly #327, filed today. This PR preserves that order rather than
accidentally fixing it:
asobi_sup:init/1gainslua_game_config_spec()andlua_sup()as the last two children, afterguest_reaper_spec(). Moving theload earlier would silently close #327 inside a 100-file move PR, which is the
wrong place for it. Flagging for the reviewer: if you would rather this PR
fix #327 too, say so and I will hoist the load and re-run.
Failure semantics: a bad game config still aborts the boot. It now surfaces as
a supervisor
failed_to_start_childinstead of a bare application-start error,so it also takes the already-started core children down with it. Still
fail-closed, but it is a change in shape -
src/asobi_sup.erl:60-72.2. Six documented operator knobs would have gone silently dead.
dev_errors,reload_mode,max_heap_words,terrain_providers,config_watch_intervalandrate_limitswere read withapplication:get_env(asobi_lua, ...).application:get_env/3against anapplication that is never loaded returns the default without complaint, so
after the merge every
{asobi_lua, [...]}block in a self-hoster's sys.configwould quietly stop having any effect. New
src/lua/asobi_lua_env.erlreadsasobi_luafirst and falls back toasobi, so existing deployments keeptheir exact behaviour and
{asobi, ...}is the home for new config.rate_limitsis the one key both halves read; the group names are disjoint(
log/log_globalvsauth/api/...), so one merged map carries both.3. Test fixture lookup pointed at the wrong application. 18 moved test
modules resolved fixtures via
code:lib_dir(asobi_lua), which now returns{error, bad_name}. Repointed atcode:lib_dir(asobi); the fixtures live attest/fixtures/lua/here, same relative layout.Everything else
src/lua/(runtime),src/lua/bots/(bot processes),include/asobi_lua_bots.hrl,test/*andtest/fixtures/lua/**.luerl ~> 1.5added torebar.configdeps and toapplicationsinsrc/asobi.app.src.vsnuntouched.rebar.lockpicked up luerl 1.5.1;cowlib was already at 2.19.0 so asobi_lua's explicit cowlib pin was not needed.
extrasgainedself-hosting,security-sandbox,security-trust-model,security-lua-known-limitations, plus newLua RuntimeandBotsmodule groups.nightly.ymlpicks upprop_lua_bridge_input_threadingandprop_lua_error_containmentat high numtests - asobi_lua's nightly ran them,so dropping them would have been a silent coverage loss.
Guide reconciliation
Three filenames collided.
guides/lua-scripting.mdandguides/lua-bots.mdhere were stubs whose onlycontent was "this lives in asobi_lua, go read it there". Replaced with the
real content, since the thing they pointed at is now in this repo.
guides/security-known-limitations.mdis a genuine collision: this repo's isabout core runtime limits, asobi_lua's is about the Lua sandbox. asobi_lua's
landed as
guides/security-lua-known-limitations.md, retitled"Known limitations (Lua sandbox)". Neither was overwritten.
security-sandbox.md,security-trust-model.md,self-hosting.mdare new.Fixed the cross-links: the core known-limitations page now links locally to
security-sandbox.mdinstead of to a github.com/widgrensit/asobi_lua URL, andself-hosting's
../README.md#quickstartanchor was repointed at this README's#try-it-in-60-seconds.What the tests assert
test/asobi_sup_lua_children_tests.erl- pins the fold.asobi_lua_configand
asobi_lua_supare both supervised; they are the last two children inthat order;
asobi_guest_reaperstarts strictly before the config load (theguest_reap_after never runs: reaper returns ignore before guest_auth is set #327 ordering, pinned so a later refactor cannot change it by accident); the
asobi_lua_supspec istype => supervisor; andasobi_lua_supstill has itsown four children in order.
test/asobi_lua_env_tests.erl- a legacy{asobi_lua, K}value is stillhonoured, an
{asobi, K}value is read when the legacy key is unset, thelegacy key wins when both are set, and the default /
undefinedcome backwhen neither is.
Verification
rebar3 fmt/rebar3 fmt --checkrebar3 xrefrebar3 eunitrebar3 dialyzerrebar3 ex_docNot verified, honestly:
rebar3 ctwas not run - it needs Postgres.test/asobi_lua_SUITE.erlcame across and compiles, but it has never executed in this repo. Note that
ci.yml:48records that anasobi_lua_SUITE.beam"removed in refactor: extract Lua scripting into asobi_lua #59" used toresurrect itself from a stale cache and crash CT on
luerl:init/0undef -that specific failure mode is gone now that luerl is a real dep, but CI is
the first place the suite will actually run.
asobiandasobi_luanow both defineasobi_lua_*modules. Any consumer depending onboth - the
asobi_luarepo itself, andasobi_engine- will get duplicatemodules on the next asobi pin bump.
asobi_lua'sbump-asobi-pin.ymlautomates that bump, so it will fire on merge. Wave 1b needs to land close
behind this.
application:set_env(asobi, ...)calls atsrc/lua/asobi_lua_config.erl:126and
:434are left exactly as they were - now internal writes rather thancross-application ones. Per the brief, the core-owned write path is S3.
asobi_lua'sdocs/adr/0001and0002were not moved - their numberscollide with this repo's existing
docs/adr/0001and0002and renumberingsomeone else's decision records is a maintainer call.
repo's
docs/adr/stops at 0005, so I did not want to guess the number.Code comments reference "the asobi_lua merge" in prose instead.
guides/comparison.md,guides/exit.md,guides/glossary.md, the threemigrate-from-*.md). Those statements are still true today - the repo andghcr.io/widgrensit/asobi_luaboth exist - so I left them for the wave thatactually retires them.
One deviation from the brief
The brief said to copy
asobi_lua/src/**intosrc/lua/"preserving itsinternal structure", which literally would have produced
src/lua/lua/*.erl.I collapsed that redundant level: the inner
src/lua/files sit directly insrc/lua/, andsrc/bots/is preserved assrc/lua/bots/. Trivial to undo ifyou want the literal layout.
Related: #327 (not closed by this PR - the ordering it describes is deliberately
preserved here).