on_actions
在开局、每月、殖民、开战等时刻自动触发你的事件
什么是 on_action
on_action 是游戏在某个时刻自动“广播”的钩子:开局、每月、每年、勘测行星、殖民完成、战争开始……每个 on_action 下挂着一串事件,时刻一到就逐个尝试触发。原版定义在 common/on_actions/ 下,99_README_ON_ACTIONS.txt 是官方说明。
按 README 的描述,每次 on_action 触发时:
events = { }里的每一个事件都会检查各自的trigger,成立的全部触发;random_events = { }里先排除条件不成立的,再按权重随机挑一个触发。
on_action_name = {
events = {
# 每次都可能触发
}
random_events = {
200 = 0 # 权重 200:什么都不触发
10 = event_name.01
10 = event_name.02
}
}给 on_action 挂上自己的事件
不要复制原版的 00_on_actions.txt(那会变成整文件覆盖,原版更新后你的模组就会吞掉新内容)。新建一个带自己前缀的文件,只写你要加的事件:
# common/on_actions/mymod_on_actions.txt
on_yearly_pulse_country = {
events = {
mymod.10
}
}同名 on_action 的内容会被合并,而不是覆盖:原版挂在 on_yearly_pulse_country 上的事件照常运行,你的 mymod.10 也会加进去。
对应的事件需要写 is_triggered_only = yes,并用 trigger 把范围缩小:
country_event = {
id = mymod.10
hide_window = yes
is_triggered_only = yes
trigger = {
is_ai = no
has_country_flag = mymod_enabled
}
immediate = {
add_resource = { unity = 50 }
}
}原版的 on_action 分布在 common/on_actions/ 的三个文件里:00_on_actions.txt(绝大多数)、01_planet_destruction.txt 和 02_component_on_actions.txt。想找某个时刻有没有现成的钩子,直接在这几个文件里搜关键词,再读它上方的注释。
提示 验证挂载是否成功的最快办法:在事件的
immediate里写一行log = "mymod.10 fired",跑一个月或一年后去game.log里找这行字(见调试)。没有输出时,先检查事件的trigger,再检查 on_action 的名字是否拼错——拼错的名字会被当成一个新的自定义 on_action,永远不会被游戏触发。
作用域:看原版注释
每个 on_action 的 root 和 from 是什么,原版在 common/on_actions/00_on_actions.txt 里用注释写明了。几个例子:
| on_action | 原版注释 |
|---|---|
on_game_start | 开局时触发,无作用域 |
on_monthly_pulse、on_yearly_pulse | No scope, like on_game_start |
on_monthly_pulse_country、on_yearly_pulse_country | this = country |
on_entering_system | Scope = Ship、From = System、FromFrom = Country |
on_planet_surveyed | Root = Planet、From = Country、FromFrom 为勘测舰队(如果有) |
on_colonized | Scope = Carrier |
on_war_beginning | Root = Country、From = War,对战争中的每个国家各执行一次 |
所以挂到 on_war_beginning 上的应该是 country_event,事件里可以用 from 取到这场战争;挂到无作用域的 on_monthly_pulse 上的则应是不带作用域的 event。
提示 原版注释还会提醒用法,例如
on_entering_system旁写着“通常更适合用on_entering_system_first_time或on_entering_system_fleet”。动手前先读注释。
性能
on_monthly_pulse_country 这类脉冲每月对每个国家都触发一次,挂在上面的事件条件会被频繁检查。几条原则:
trigger里把最便宜、最能排除的条件放前面,例如is_ai = no、has_country_flag。- 行星、星系、星港、领袖类事件用
pre_triggers做快速预筛,README 专门推荐了这一点,写法见原版events/000_added_pre_triggers_to_planet_events.txt:
pre_triggers = {
has_owner = yes
is_ai = no
}- 能挂年脉冲的就不挂月脉冲。
random_events 的权重修正
random_events 里的数字是固定权重,不支持条件修正。README 给出的办法是在事件本身写 weight_multiplier:
weight_multiplier = {
factor = 1
modifier = {
factor = 2
has_country_flag = mymod_lucky
}
}自定义 on_action
你也可以发明自己的 on_action,然后用 fire_on_action 效果手动触发,方便多个模组往同一个钩子里挂事件:
# common/on_actions/mymod_on_actions.txt
mymod_on_signal_decoded = {
events = {
mymod.20
}
}# 某个事件的 immediate 或 option 里
fire_on_action = {
on_action = mymod_on_signal_decoded
scopes = { from = root }
}scopes 用来指定被触发事件的 from、fromfrom 等,格式见 effects.log 中 fire_on_action 的说明(fire_on_action = { on_action = <string> scopes = { from = X fromfrom = Y } })。