Skip to content

events.on binds handlers by parse order, not by the annotation at the call site #2

Description

@nepinhum

events.on(fn) ignores the handler's annotation at runtime.

The AST pass collects every events.on(function(e: EventX)) annotation per file in source order into state.inferred_events and each runtime events.on call consumes the next entry (script.cpp:518, mods.cpp:149). That only holds while call order matches parse order.

A file is parsed in full before it executes, a module that subscribes while being require'd consumes entries belonging to the file that required it and every later binding shifts by one.

Repro:

-- mod/runtime.luau
    local combat = require("mymod/combat") -- parsed after this file
    events.on(function(e: EventPlayerJoin) ... end)

-- mod/combat.luau
    events.on(function(e: EventHit) ... end)
    events.on(function(e: EventTick) ... end)

Parsed order: player_join, hit, tick
Call order: combat's two first

Result: combat's hit handler runs on player_join, its tick handler runs on hit and the join handler runs on every tick.

In my case that surfaced as "attempt to index nil with 'control'" sixty times a second because the join handler was getting a tick event.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions