事件(Events)
事件文件的结构、命名空间、事件类型、触发方式与选项
事件是什么
事件是群星脚本里最常用的“执行单元”:弹窗剧情、异常点结果、隐藏的后台逻辑,几乎都是事件。事件文件放在模组的 events\ 文件夹,扩展名 .txt。原版的 events\ 下有约 170 个文件,可以随时打开参考。
一个完整的例子
下面是一个仿照原版 events/country_events_1.txt 写的国家事件:
namespace = mymod
# 来自深空的信号
country_event = {
id = mymod.1
title = mymod.1.name
desc = mymod.1.desc
picture = GFX_evt_satellite_in_orbit
show_sound = event_sensor_ping
is_triggered_only = yes
trigger = {
is_ai = no
NOT = { has_country_flag = mymod_signal_seen }
}
immediate = {
set_country_flag = mymod_signal_seen
}
option = {
name = mymod.1.a
add_resource = { energy = 100 }
}
option = {
name = mymod.1.b
add_resource = { minerals = 100 }
}
}对应的本地化(见本地化):
l_simp_chinese:
mymod.1.name: "来自深空的信号"
mymod.1.desc: "传感器捕捉到了一段规律的信号。"
mymod.1.a: "把它卖给能源公司。"
mymod.1.b: "拆了接收器换矿物。"命名空间与 ID
文件开头的 namespace = mymod 声明命名空间,之后的事件 ID 写成 命名空间.数字,如 mymod.1、mymod.100。原版就是这么做的:events/country_events_1.txt 开头是 namespace = country,事件 ID 为 country.1、country.50。
- 命名空间请用模组专属的前缀,避免和原版或其他模组撞 ID。
- 本地化键习惯用
<ID>.name、<ID>.desc、<ID>.a、<ID>.b。 - 实测 4.5.2 中
events是 FIOS:两个文件定义同一个 ID 时,按文件名排序先读的生效,后读的报an event with id [xxx] already exists!。想覆盖原版事件,要么让你的文件名排在原版文件前面,要么整文件覆盖。详见加载顺序与覆盖规则。
事件类型
事件块的名字决定事件的作用域(root 是什么)。按原版 4.5 的使用次数,常见的有:
| 类型 | root | 原版中的用量 |
|---|---|---|
country_event | 国家 | 约 5200 个 |
carrier_event | 承载殖民地的行星(4.5 行星类事件的主力) | 约 1100 个 |
ship_event | 舰船 | 约 1000 个 |
fleet_event | 舰队 | 约 900 个 |
situation_event | 局势 | 约 700 个 |
event | 无作用域(全局) | 约 140 个 |
observer_event | 观察者 | 约 90 个 |
leader_event | 领袖 | 约 70 个 |
system_event | 星系 | 约 70 个 |
planet_event、colony_event、starbase_event、pop_group_event | 对应对象 | 各十几个 |
此外还有 first_contact_event、espionage_operation_event、astral_rift_event、agreement_event 等专用类型。
常用字段
| 字段 | 说明 |
|---|---|
id | 事件 ID |
title / desc / picture | 弹窗的标题、正文、配图。desc 也可以写成带 trigger 的块,按条件显示不同文字(原版 country.50 就这么做) |
show_sound | 弹出时的音效 |
location | 点击事件可跳转到的位置,如 ROOT、FROM.fleet |
hide_window = yes | 不弹窗,只执行效果。原版有约 2800 个隐藏事件,多用于后台逻辑 |
is_triggered_only = yes | 只在被调用时触发,不会自己发生 |
trigger | 触发条件(触发器块)。被调用时也会检查 |
pre_triggers | 更快的预筛条件,用于行星、星系、领袖等事件,见 events/000_added_pre_triggers_to_planet_events.txt |
mean_time_to_happen | 让事件按平均间隔自行发生,如 months = 40 |
fire_only_once = yes | 一局游戏只触发一次 |
immediate | 事件一触发就执行的效果,在玩家看到弹窗之前 |
option | 选项,至少写一个 name |
after | 玩家选完任一选项之后执行的效果 |
事件怎样被触发
1. 由效果调用(最常用)。 原版约 9500 处 is_triggered_only = yes,绝大多数事件都是被别的脚本调用的:
country_event = { id = mymod.1 }
country_event = { id = mymod.2 days = 30 random = 10 }days 是延迟天数,random 是额外的随机延迟上限。country_event、ship_event 等效果还支持 scopes = { from = ... },用来指定被调用事件的 FROM(以 effects.log 中各效果的说明为准)。
2. 由 on_action 触发。 游戏在特定时刻(开局、每月、殖民完成、战争开始……)会触发 on_action,把你的事件挂上去即可,见 on_actions。
3. 按 MTTH 自行发生。 写 mean_time_to_happen 而不写 is_triggered_only。原版只有约 140 个这样的事件;能用 on_action 解决的,优先用 on_action。
4. 控制台调试。 event mymod.1 直接触发,见调试。
选项
option = {
name = country.50.b
add_monthly_resource_mult = {
resource = unity
value = @tier1unityreward
min = @tier1unitymin
max = @tier1unitymax
}
hidden_effect = {
end_event_chain = "survey_habitable_worlds_chain"
}
}(摘自原版 country.50。)选项里直接写效果;不想让玩家在提示框里看到的部分放进 hidden_effect,只想展示说明而不执行时可以用 tooltip = { ... }。
提示 隐藏事件也常写一个
option,不过真正的逻辑通常放在immediate里——它在事件触发的瞬间执行,不依赖玩家点击。
写事件时的检查清单
- 文件开头有
namespace,ID 前缀与之一致。 - 被调用的事件写了
is_triggered_only = yes。 - 所有
title、desc、name都有对应的本地化键,且.yml带 BOM。 - 用
event <ID>在控制台测一遍,再看error.log。