event
事件订阅。脚本卸载时订阅自动撤销,无需手写 event.off。
event.on(name, fn) → handle
参数
name : string— 事件名,下表之一fn : function— 回调
事件名 + 回调签名
| 事件名 | 回调签名 | 字段 |
|---|---|---|
"frame_update" | fn(e) | e.delta_time : number — z-order 在 ESP 之下 |
"render_post" | fn(e) | e.delta_time : number — z-order 在 ESP / FOV / menu 之上 |
"config_changed" | fn(e) | e.module_name : string — 配置 modify 时触发 |
"script_loaded" | fn(e) | e.script_path : string, e.is_reload : bool |
"script_unloaded" | fn(e) | e.script_path : string |
"menu_toggled" | fn(e) | e.visible : bool — MenuOpen 热键切换边沿触发 |
"weapon_changed" | fn(e) | e.prev_weapon : int, e.curr_weapon : int — local 手持武器边沿变化 (sdk::ItemId) |
"map_changed" | fn(e) | e.prev_map : string, e.curr_map : string — 地图切换 (level_name 边沿) |
"player_knocked" | fn(e) | 倒地 (is_down false→true)。共用 player 生命周期字段 (见下) |
"player_revived" | fn(e) | 扶起复活 (is_down true→false 且未死亡) |
"player_died" | fn(e) | 死亡 (is_dead false→true) |
"player_respawned" | fn(e) | 重生 (is_dead true→false) |
所有事件共用基类字段:e.timestamp : int(毫秒 unix ts,懒计算), e.source : string。
player 生命周期事件共用字段 (e.player_index : int, e.name : string, e.team_num : int, e.is_local : bool, e.is_teammate : bool)。
拆 4 个 player 事件名(不是单一 state 字段)的原因:
- handler 不必写
if state == "knocked"分支 - 只关心某一类型时只订一个,不接其它事件,EventBus 按 type_index 分发零浪费
每帧渲染线程扫所有玩家对比上帧状态,边沿变化才 publish — 不会每帧 spam。首次见到的玩家不发事件(避免初始化时全员误报)。weapon_changed / map_changed 同款边沿语义。
frame_updatevsrender_postz-order:frame_update写入的 vtx 落在 ESP / FOV / menu 之前;render_post写入的 vtx 落在它们之后。两者都用屏幕相对坐标(系统统一做 viewport offset 修正)。HUD 类 mod 用render_post浮于 ESP 之上;底层信息显示用frame_update。每渲染帧触发(绑定屏幕渲染节奏,144Hz / 240Hz 时也是 144/240 次每秒)。
draw.*必须挂在frame_update或render_post每帧 call —— 前景 draw list 每帧重置,漏一帧就是空白闪烁。重活(数据计算、网络等)由脚本自己累计
e.delta_time节流,见 入门指南。
返回:handle : number —— 用于 event.off
event.off(handle)
显式取消订阅(一般无需手动)。
自定义事件 — 脚本间通信
除上述内置事件外,任何其他事件名都进 Lua 自定义事件通道。
event.on(name, fn) → handle
任何不在内置事件名清单的 name 自动走自定义通道。fn 签名是 function(...) —— 收到 event.emit(name, ...) 透传的全部参数。
event.emit(name, ...)
触发自定义事件,同步派发到该 name 下所有 handler。不允许 emit 到内置事件名(防止脚本伪造系统事件),尝试 emit "frame_update" 等会被拒绝。
handler 异常被捕获不会中断后续派发。脚本卸载时该脚本注册的所有自定义事件订阅自动撤销。
-- 脚本 A:监听
event.on("hp_changed", function(player_name, new_hp, old_hp)
print(player_name, "blood:", old_hp, "→", new_hp)
end)
-- 脚本 B:广播
event.emit("hp_changed", "alice", 30, 100)示例
event.on("frame_update", function(e)
-- 每渲染帧调,dt 与 time.delta() 等价
do_something(e.delta_time)
end)
event.on("script_unloaded", function(ue)
if ue.script_path ~= _SCRIPT_PATH then return end
-- 只对自己被卸载做处理(极少数场景:缓冲区 flush)
end)
-- 菜单显隐:toast 跟随显示
event.on("menu_toggled", function(e)
if e.visible then gui.notify:info("menu opened") end
end)
-- 玩家生命周期:队友倒地告警
event.on("player_knocked", function(e)
if e.is_teammate then gui.notify:warn(e.name .. " 倒地了!", 3) end
end)
event.on("player_died", function(e)
if e.is_local then gui.notify:error("你死了", 2) end
end)
-- HUD 浮于 ESP 之上:用 render_post 而不是 frame_update
event.on("render_post", function(e)
draw.text(draw.font("default"), 24, 100, 100, 0xFFFFFFFF, "On top of ESP")
end)
-- 武器切换时刷一次:换枪自动切配置/重置弹道学
event.on("weapon_changed", function(e)
print(string.format("weapon: %d → %d", e.prev_weapon, e.curr_weapon))
end)
-- 地图切换时重置本局统计
event.on("map_changed", function(e)
print("map:", e.prev_map, "→", e.curr_map)
-- reset local round stats
end)