Repository navigation
Run event and event argument scripts on Luau - #135
Open
carrdylan52 wants to merge 6 commits into
Open
carrdylan52 wants to merge 6 commits into
carrdylan52 wants to merge 6 commits into
Conversation
An audit of the event handlers that read a slot's tag or write an output, against ps2/src: - tagged: GetRand, SetBgmVol, SndSetSeVol and EsmSetValue branch on an integer or float tag. - strings: MesMake, MapJump, EsmLoadBase, StreamOpen, LoadSkin and the other commands that take a number or a name by the slot's tag. - values: JoinPartyMember joins or leaves given a value and reports membership given a reference; GetMenuEtc's fish record and download step read a value where its other requests write. - by_arg: GetMenuEtc writes a float for the fish record. - deferred: GotoUseItem and GotoUseItem2 write the item used when their menu closes. - kept: the argument scripts' Data keeps each argument's tag. The outputs catalogued unknown get the type their handlers write. LoadSkin reads four slots, so the curation can now remove a signature the generator counted from two alternative reads. The declarations add ExtTyped, which passes each argument with the tag retail pushed and returns the outputs, and DeferredOutput, and the bindings mark deferred outputs.
- Event scripts also run skipped at their first, second, third, fifth and ninth wait and at every wait. - STATE models event story and local flags, quest fields and party membership; RANDOM draws event GetRand inside its range in the variant's type. - Integer-or-string, kept and valued arguments compare as tag and payload; a value passed for an output is read, not written, and an output's type may follow the request (by_arg). - A print records how retail formats each slot (%d, %f or the string), and the module's printed text must match it as well as the value. - The mutation sweep reads ExtTyped calls and samples an event and an event argument script. - A harness or mutation run copies only the libraries its module requires, which keeps the tool tests inside their timeout.
SkipEvent resumes an event script in skip mode: until the next SKIP_END it runs in layout order, jumps fall through and leave their conditions on the operand stack, native calls only pop their arguments, and stores, prints and script calls run. stb/cfg.py's skip_flow finds each function's sweeps, where they start and where normal execution resumes; the analyses interpret them; the lifter lifts each into straight-line statements; and the emitter puts them in a local skip(at), entered after a wait the engine skipped, after a call that returned in skip mode and at the start of a function a sweep calls. vm.wait returns whether the engine skipped, and vm.skipping and vm.skip_end follow the mode. The leaked conditions can overflow the 0x80-slot event stack where normal execution does not. A function where that may happen takes its frame's start, counts what its sweeps leave, and checks each push that may overflow with vm.stack after evaluating, in bytecode order, the calls and errors below it. What skip mode makes undefined, such as a store through a leaked condition, is refused. Also: - A discarded value still evaluates what may raise or call: a store's value and element index nothing reads, a dropped result, a popped expression. A value passed for an output that may raise is refused. - An expression of a store's result uses the value stored, as retail pushes it, rather than reading the element again. - A tag analysis settles on the least tags the calls pass, records the tags of printed values, and a float slot prints with %f. - A caller of a shared helper whose value another script uses takes the references after it. - A deferred output is reinterpreted as its variable holds it, and an ExtTyped call passes the tags retail pushes.
938 of the 974 event and event argument scripts transpile; the other 36 stay on the interpreter, each with its reason in fallback.json. The action, effect and monster modules change only where they print a float slot.
The event and event_arg kinds join the generated bindings, so their modules load where present. CRunScript::skip resumes a Luau script with true, which puts it in skip mode. ExtTyped passes each argument with the tag its letter names and returns the I and F outputs, and a deferred output points at a slot that outlives the call, which DeferredOutput reads after the following wait. The runtime tests cover skip mode and the event natives, and CTest checks the event modules against the corpus as Luau.TranspileEvent, a longer test of its own.
PORT_LUAU.md describes skip mode, the event handler flags, ExtTyped and DeferredOutput, the stack checks, the harness's event state and print text, and the Luau.TranspileEvent gate, which PC.md lists with the other corpus tests. tools/input/luau-m4-prologue.input plays from boot through the costume select and the prologue into Palm Brinks, with the command that compares its screenshot and log on both VMs. The handoff records the M4 results and what stays on the interpreter.
carrdylan52
force-pushed
the
pr/luau-m4-events
branch
from
October 24, 2026 11:44
f4b673f to
e72132c
Compare
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.
Event and event argument scripts currently run on the bytecode interpreter. This change runs 938 of the 974 published scripts of those kinds on Luau, including event skipping. The remaining 36 stay on the interpreter through the enforced fallback list.
The translator models skip execution in bytecode order, including ignored branches, retained conditions, calls, waits, SKIP_END and stack overflow. The event catalogue and bindings preserve the tags handlers inspect, distinguish input values from output references, and support outputs written after a menu closes. The harness adds skip scenarios, event flags and party state, native argument tag checks, and retail print formatting.
The series keeps handwritten changes separate from one generation from data v20: catalogue and declarations; harness; translation and regressions; generated modules; runtime enablement and tests; documentation and the prologue input. It adds no third-party dependency and changes no PS2 source. The generated map modules and shared event helpers occupy about 54.7 MB of source.
Validation at f4b673f:
Luau.TranspileEventgate passes 337,744 scenarios and has a 3600-second timeout.docs/PORT_LUAU.mdprovides the tracked input and checkout-relative commands for both VMs.The bytecode files, interpreter bridges and timing normalization remain necessary: 125 scripts across all kinds still use the interpreter. The harness does not certify every native handler or execution path.
Rebase validation (2026-10-24)
Rebased the six-commit series onto current upstream
master,f344ede3dbc5eac1e06d6a446c6acd036ae6ca73. The published head ise72132c9a403f86a0755acd884c2738b9c37d70b. Original authors, timestamps and messages are retained; committer identity was corrected for publication. The generated Luau corpus is unchanged from the original PR.The integration retains the upstream monster stun/resume regression and both event tests. Event modules bypass the bytecode loader, so the runtime now applies upstream's exact per-script Spanish jump-gate text corrections for
f04_5ands30_5before string interning. A regression test covers corrected, unrelated and custom text plus cache ordering.Local validation of the published tree: 355 Python tests OK with one optional timing skip; all 7,995 Luau modules pass strict checking with zero diagnostics; generated API declarations, Luau pruning and diff checks pass. A focused compiled probe of the exact string-interning body with real Windows CP932 conversion passes 18 cases; its lookup and instance registry are fixtures, so it is not the full native runtime suite. Game-data differential corpus gates and gameplay replays were not rerun for this rebase. The earlier validation above applies to the original head as labelled.
Exact-head GitHub CI:
The three native build jobs fail while linking
darkchronicle_tests(darkchronicle_tests.exeon Windows):CNameRegiMenu::CNameRegiMenu()is undefined, referenced by theNameEntryInputfixture inmenu_input_test.cpp. The same symbol and fixture fail on all three platforms in the exact upstream-base run atf344ede3dbc5eac1e06d6a446c6acd036ae6ca73. The related name-entry implementation, headers, fixture and test target definition are unchanged by this PR. No PR-specific regression was identified in these failure logs.The Luau runtime test source compiled, but the native test steps were skipped because the test executable could not link. In particular, the new Spanish text runtime regression has not executed in CI. Compiler integration and the Flatpak build/startup passed. Native runtime validation remains blocked by the verified upstream constructor-link issue; this rebase is not a green native-CI result.