Anomalies are special events that have a chance of triggering whenever your science ship surveys a stellar body. Anomalies consist of two parts:
- Anomaly Categories
- Anomaly Events
Which are stored in the following directories, respectively:
Stellaris\common\anomalies\
Stellaris\events\
An important distinction between the two is that anomaly categories define anomalies that are initially discovered by science ships after surveying a celestial body. These appear in the 'Anomalies' tab of the situation log. On the other hand, anomaly events are fired once a science ship finishes investigating an anomaly.
Anomaly spawn mechanics[编辑 | 编辑源代码]
The Stellaris anomaly spawning system is hardcoded into the game, and therefore there are no script files from which to reverse-engineer the system. Nonetheless, it is possible to gain insight into how it works at a higher level through experimentation in-game. The following is an attempt to characterize the anomaly spawning system based on what information is available in the game files, player experiences, and some speculation.
Every time a celestial body is surveyed for the first time, the game rolls to determine if an anomaly will be spawned. This can only happen the first time said body is surveyed by any empire, either player or AI. The base chance of this check passing is 5%, and each time it fails, the chance increases an additional 0.5%. This is set and can be modified in Stellaris\common\defines\defines00.txt
:
ANOMALY_SPAWN_CHANCE = 0.050 # Percent chance that a planet gets a discovery when surveyed ANOMALY_SPAWN_CHANCE_INCREMENT = 0.005 # Percentage increase towards next chance when failing
If this check succeeds, then the game will randomly pick an anomaly category to spawn from the weighted list of anomaly categories. Only anomaly categories for which all of the following is true can be selected:
- Does not currently exist elsewhere (i.e. if it has been spawned before it has been investigated and it has triggered an anomaly event).
- Can be spawned for the empire type: player or AI. Determined by the
should_ai_use
andshould_ai_and_humans_use
fields. max_once = yes
and this anomaly has never been spawned by the owner of the science ship.max_once_global = yes
and this anomaly has never been spawned.spawn_chance = {}
does not evaluate to0
.- An anomaly event exists in
on_success = {}
that can be triggered. This depends on the anomaly event'smax_once
andmax_once_global
fields and whether or not it has been triggered before.
Finally, one last check is performed against the null_spawn_chance
field. If this check succeeds, the anomaly will not spawn. It is unclear if the anomaly spawn system will then go and grab another anomaly category from the weighted list if this check succeeds. Nonetheless, if this last check fails, then the anomaly event will be spawned.
There are three important takeaways from this. First, due to point #1 above, if an empire spawns an anomaly and does not research it immediately, it cannot spawn again until they do. Therefore, if you have multiple anomaly events tied to that anomaly category, all of those events are effectively being held hostage until the empire investigates the anomaly. Hypothetically, suppose the empire is destroyed before it can investigate the anomaly. In that case, this could lead to a situation where all anomaly events associated with that anomaly category become permanently inaccessible for the remainder of that game.
Second, because anomalies can only spawn on celestial bodies that have never been surveyed, it isn't easy to thoroughly test custom anomaly categories using the survey
console command. This command will survey all bodies in the galaxy, and as a consequence, will most likely spawn every possible anomaly, including your custom anomaly. However, because everything has now been surveyed, it will no longer be possible to investigate your custom anomaly and then try to get it to spawn again, should you have set it up such that it is able to.
Third, by default, most anomaly categories can only spawn for player empires to keep AI empires from stealing them all. This is controlled by the should_ai_use
and should_ai_and_humans_use
fields. AI empires are instead given access to much less narratively stimulating but functional AI events, found in Stellaris\common\anomalies\99_anomaly_categories_ai.txt
.
Anomaly categories[编辑 | 编辑源代码]
An anomaly category defines the name and description of an anomaly as seen in the situation log, the likelihood of the anomaly appearing, any restrictions on when and where the anomaly can appear, and the events that can occur after investigating it. Anomaly categories used to be split up into two files, but this changed in 2.1.[1] Thorough documentation of proper anomaly category formatting and all possible configuration options was kindly provided in the game files at Stellaris\common\anomalies\readme.txt
:
an_anomaly_category = { # Anomaly category ID key should_ai_use = yes/no # Allows AI empires to generate the category. Default: no should_ai_and_humans_use = yes/no # If yes, both AI and human empires can use this anomaly (overrides should_ai_use) desc = "key" # Optional, if no desc is given "<category key>_desc" is assumed desc = { # Can also use triggered descs. First valid entry will be used. trigger = { ... } # Scope: planet, from = ship text = "key" # Localization key for description } picture = GFX_picture # Picture displayed in category window level = int # Anomaly level, 1 to 10 null_spawn_chance = 0.5 # Default 0. 0.0 - 1.0 (0 to 100%) chance category will NOT spawn # even if it is picked by the anomaly die roll. Used to make # categories for unusual objects (e.g. black holes) actually rare. max_once = yes/no # default NO, if true will spawn category only once per empire max_once_global = yes/no # default NO, if true will spawn category only once per game spawn_chance = { # Chance for this anomaly category to spawn, base = <num> # relative to other valid categories. Default: base = 0 modifier = { # Spawn chance modifier add/factor = <num> <triggers> # Scope: planet, from = ship } } on_spawn = { <effects> } # Executes immediately when anomaly category is spawned. # Scopes are this/root: planet, from: ship # NOTE: on_spawn effects will not run if category is spawned through console on_success = { # Picks anomaly event to fire; similar to random_list 1 = { # Base chance max_once = yes # Individual outcomes default to max_once = yes, max_once_global = no # and max_once_global = no modifier = { # Optional modifiers add/factor = <num> <triggers> # Scope: ship, from: planet } anomaly_event = <id> # New effect anomaly_event fires specified event ID. Scope: ship, from: planet } # Can also use ship_event, though it gets different scopes: # ship, from: ship, fromfrom: planet 1 = <event id> # shorthand for 1 = { anomaly_event = <event id> } } on_success = <event id> # Shorthand for on_success = { 1 = { anomaly_event = <event id> } } } # Only use if there is only one outcome in the category
Example[编辑 | 编辑源代码]
Consider, for instance, you wish to create an anomaly that only occurs on asteroids (i.e., it can only spawn when surveying an asteroid). Your first step will be making a new anomaly category file in your mod at common\anomalies\
. You can name the file whatever you want, but let's call this one my_asteroid_anomaly_category.txt
. Your initial skeleton would look like this:
an_anomaly_category = { should_ai_use = desc = picture = level = null_spawn_chance = max_once = max_once_global = spawn_chance = { base = 1 } on_success = { } }
First you want to define the name of the anomaly category. This must be unique, and the best practice is to use a common prefix across all files and objects you create for any mods you make. In this case we'll go with my_asteroid
, which makes the name of your anomaly category my_asteroid_category
. Next, set the should_ai_use
field to no
, as we don't want the pesky AI stealing your narrative masterpiece from the player! The desc
field is where you reference a localization key for the description that appears in the situation log; let's call it "my_asteroid_category_desc"
. Similarly, the picture
field is where you reference a event image that will appear in the situation log; let's use GFX_evt_asteroid_field
, since this is an asteroid event. Finally, pick an appropriate difficulty level for the anomaly and fill in the level
field. This is just a simple asteroid anomaly, so let's go with 3
.
The next set of fields relate to when your anomaly can spawn. The first one, null_spawn_chance
, is used to create a chance the anomaly won't spawn even if the anomaly spawn system picks it. This is meant more for making anomalies rarer, so let's just set it to 0
to disable it. The next two fields, max_once
and max_once_global
, specify whether or not your anomaly can spawn more than once. Normally you would want to set max_once
to yes
for more generic anomalies with a single outcome, and max_once_global
to yes
for narratively unique anomalies that have ramifications extending beyond the empire discovering it. In this case, you want to have several outcomes of this same event, so let's set both to no
. Finally, the spawn_chance
block determines the weighted chance your anomaly will spawn. This is where we can ensure your anomaly only spawns on asteroids by changing the base chance to 0
and adding a modifer
block to add 1
when the body is an asteroid.
Finally, you can use the on_success
block to define the possible events you want to be able to fire when the anomaly is investigated. In this case, you want to define three events, with the first having twice the chance of happening compared to the other two. This is achieved by setting a base chance of 2
for the first event and 1
for the other two events. You also don't want the same player to see these events multiple times, so you set the max_once
field of each event to yes
. These events aren't so unique it wouldn't make sense for other empires to encounter them though, so you set max_once_global
to no
.
Your anomaly category code now looks like the following:
my_asteroid_category = { should_ai_use = no desc = "my_asteroid_category_desc" picture = GFX_evt_asteroid_field level = 3 null_spawn_chance = 0 max_once = no max_once_global = no spawn_chance = { base = 0 modifier = { add = 1 is_asteroid = yes } } on_success = { 2 = { max_once = yes max_once_global = no anomaly_event = my_asteroid_event.1 } 1 = { max_once = yes max_once_global = no anomaly_event = my_asteroid_event.2 } 1 = { max_once = yes max_once_global = no anomaly_event = my_asteroid_event.3 } } }
my_asteroid_event.1
, my_asteroid_event.2
, and my_asteroid_event.3
are the event IDs of your three anomaly events, one of which will be shown in the continuiation of this example in the next section.
Anomaly events[编辑 | 编辑源代码]
Anomaly events are identical to standard events. The unique part about them is that anomaly categories trigger them, and they must be ship events. Please visit the events page for a more detailed look at events.
Example[编辑 | 编辑源代码]
Continuing the prior example, the following is an implementation of the anomaly event my_asteroid_event.1
. This code will need to reside in your mod's events\
directory. As before, you can name the file whatever you want, but let's call this one my_asteroid_event.txt
. We won't go into much detail this time, but there are some important things to note. First, anomaly events have the context root = ship
, from = planet
. Second, anomaly events exclusively set is_triggered_only
to yes
, as they never trigger themselves. Third, it is common to use the immediate
block to clean up the celestial body the event is triggering on. In our example, we want to reward the player with either an engineering deposit or a mineral deposit, so we want first to remove any pre-existing deposits on the asteroid.
Your anomaly event code would therefore look like the following:
namespace = my_asteroid_event ship_event = { id = my_asteroid_event.1 title = "my_asteroid_event.1.name" desc = "my_asteroid_event.1.desc" picture = GFX_evt_mining_station show_sound = event_ship_bridge location = from is_triggered_only = yes immediate = { from = { clear_deposits = yes } } option = { name = "my_asteroid_event.1.a" from = { set_deposit = d_engineering_2 } } option = { name = "my_asteroid_event.1.b" from = { set_deposit = d_minerals_5 } } }
References[编辑 | 编辑源代码]
帝国 | 帝国 • 思潮 • 政府 • 国民理念 • 起源 • 承诺 • 议程 • 传统 • 飞升天赋 • 法令 • 政策 • 遗珍 • 科技 • 自定义帝国 |
人口 | 岗位 • 派系 |
领袖 | 领袖 • 领袖特质 |
物种 | 物种 • 物种特质 |
行星 | 行星 • 行星特征 • 轨道矿藏 • 建筑 • 区划 • 行星决议 |
星系 | 星系 • 恒星基地 • 巨型结构 • 虫洞 • 星门 • 地图 |
舰队 | 舰队 • 舰船 • 部件 |
地面战 | 陆军 • 轰炸姿态 |
外交 | 外交 • 联邦 • 星海共同体 • 评价修正 • 宣战理由 • 战争目标 |
事件 | 事件 • 异常现象 • 特殊项目 • 考古遗址 |
游玩 | 游玩 • 定义 • 研究 • 经济 • 游戏开局 |
动态修改 | 动态 • 指令效果 • 触发条件 • 作用域 • 修正 • 变量 • AI |
媒体/本地化 | Maya 导出器 • 图形 • 肖像 • 旗帜 • 事件图片 • 界面 • 图标 • 音乐 • 本地化 |
Other | 控制台命令 • 存档编辑 • Steam 创意工坊 • 模组制作教程 |