Repository navigation
Lua hot reload: callbacks told apart by their order reload, @onHotReload hooks, smaller payloads - #1551
Conversation
…oad hooks, smaller payloads - Closures which share an identity are no longer frozen: editing their bodies and appending one reload; a move (a closure now with another's source) and a removal still need a restart. Identities name enclosing classes. - Functions annotated @onHotReload run after each payload installed everything else; static, no parameters. Entry points only in -luaHotReload builds. With -stacktraces the payload passes them a position. - A payload lists the initializer order only when an edit swaps the started map's initializers, and guards storage only for units with storage the started map lacks: a no-change Castle Fight payload went from 403,624 to 93 bytes.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b284fa204
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…trace depth as it was
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 960e10ab64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…apart by their order
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Three changes aimed at the edits a real map makes most: callbacks which share an identity reload, a map can run setup code again after a reload (
@onHotReload), and a payload no longer carries checks of the whole program. Design and limits:docs/LUA_HOT_RELOAD.md.Callbacks told apart by their order reload
Closures which share an identity (several anonymous closures of one interface in one function, such as two
doAftercallbacks) are told apart by their order. #1549 froze them: editing any of their bodies, adding one or removing one needed a restart. In Castle Fight, 1,050 of the 2,712 closures are in such groups (CallbackSingle490 of 1,310,EventListener74 of 222,ArgHandler49 of 50).Function.closureSource), since each one's Lua names its own class, against the baseline's and the one an earlier payload sent last (History.groupShapes).copiedCallbacksAreNoMove). One inserted before identical callbacks is still refused.A.N,B.N) shared the identityTest:N; allowing a group to grow exposed it (nestedClassFieldTypeChangesRequireARestart).Reload hooks
A package
initdoes not run again, so setup it did (UI frames, registered events, values copied from constants) stays as it was. A function annotated@onHotReloadruns after each payload installed everything else, with the code the payload has, in package initialisation order; one which fails does not stop the others and is reported in the payload's status. The validator requires it to be static and take no parameters. The annotation is declared in the standard library (wurstscript/WurstStdlib2#518).In a
-luaHotReloadbuild the hooks are entry points of the tree shaker, the call relations and the Lua garbage removal; in any other buildhotReloadHooks()is empty, so the output is unchanged and a hook nothing calls is not emitted (reloadHookIsNotEmittedOutsideHotReloadBuilds). With-stacktracesevery function takes the position of its call, a hook too, so the payload passes one: without it a trace taken in a hook showednil(reloadHookFrameNamesTheReloadInStackTraces).Payloads carry what an edit can have changed
A payload of Castle Fight with nothing changed was 403,624 bytes, past the 200,000 characters the delivery was measured with on the 3.0.1.24371 client. 379,578 of them were the initializer order check listing every one of the map's initializers, and 23,547 storage guards whose conditions were constant
true. It is now 93 bytes:swappedInitializersOfTheStartedMapWarnInTheMap); otherwise it lists those payloads added, as before (mapRemembersOrderOfPayloadAddedInitializers).payloadChecksNoUnchangedInitializers).Evidence
Measured on the 3.0.1.24371 client, single player, in a test map built with
-build ... -lua -luaHotReloadand a project's default run arguments (-runcompiletimefunctions -injectobjects -stacktraces), its session driven byLuaHotReloadSession start|send. Ten payloads in one game, 51 checks, all passed. Phases 1-9 as in #1550, plus:@onHotReloadfunction counts the payloads and copies a constant into a variable, as setup in aninitdoesEvery payload which applied printed nothing but "applied payload n". An earlier run with phase 10 but without the hook passed 47 of 47.
Unit tests, Windows, on the final code:
LuaHotReloadTests(103),DeterministicChecks(37),LuaBackendAuditTests(297),LuaTranslationTests(152),ClosureTests(68),TreeShakerTests(25),AnnotationTests(8),HotReloadPipelineTests(6),RunArgsTests(5). Each new test fails before its change; removing the move detection fails the swap and the middle-insertion tests.Real edits
Castle Fight's last 30 commits which change Wurst code, each built with this branch and its payload made against the commit before it: 8 accepted, 22 refused. The causes, ranked, are in the docs ("Edits of a real project"); the two largest are a constant array literal changing length (14 commits, the only cause in 4) and a constant starting or stopping being read (7, the only cause in 2), and fixing both would accept 17 of 30. Accepted payloads also ship functions which differ only in the flatten's temporary names, numbered across the program: one of 5 changed files shipped 621 functions, 550 of them for that. Both are left for the next changes.
Not covered