如何在不使用控制台的前提下成为一个合格的第四天灾
提醒:文中的Mod基于群星3.8.4版本制作,启动器版本为2023.11,请注意时效
工具安装
CWTools
Paradox Language Services
PhotoShop DDS 插件
DDS plug-in for After Effects and Photoshop
VS Code
群星的配置文件多数是txt格式的,可使用VS Code并安装扩展CWTools
进行编辑,CWTools能够实现代码自动补全与错误提示,比较方便。安装完成后在扩展设置中设置群星的安装路径就可以用了,群星的安装路径为[Steam安装路径]/steamapps/common/Stellaris/
。
DDS插件
群星中很多图片文件的格式都是DDS,Photoshop需要安装插件才能将图片存储为DDS格式,把下载的插件文件(.8bi)放在PS目录下的./Required/Plug-ins/File Formats
这个文件夹里面,随后打开PS,在帮助-关于增效工具
中出现DDS就说明安装成功。
创建Mod
- 在群星启动器的左边栏中选择
所有已安装Mod
,然后点击右上角的上传MOD
- 在弹出的窗口中填写相关信息,这些信息后期都可以手动修改
- 名称:Mod在启动器和创意工坊中显示的名字,这里我以
Example
为例 - 版本:兼容Mod的游戏版本,你可以填写当前小版本,如
3.8.4
,也可以使用*
代替小版本号,如3.8.*
代表Mod可以在整个3.8大版本中使用 - 目录:在
mod/
后面填写Mod所在文件夹的名称,可以与Mod名称不同,这里我已exp
为例 - 标签:Mod的种类,记录Mod更改了哪些游戏内容,主要作用是方便其他人在创意工坊中通过它筛选不同种类的Mod
- 点击创建MOD
- 在
C:/Users/Documents/Paradox Interactive/Stellaris/mod
中会出现以刚刚填写的目录命名的文件夹与同名的.mod
文件
mod创建完成后的文件目录如下:
1 2 3 4 5 6 7
| C:/Users/Documents/Paradox Interactive/Stellaris/mod │ ├─ exp.mod │ └─ exp │ └─ descriptor.mod
|
.../mod/exp.mod
记录的是我们创建本地Mod时填写的信息,一般不需要编辑它.../mod/exp/descriptor.mod
和.../mod/exp.mod
大同小异,我们在后续将Mod上传到创意工坊时会用到它.../mod/exp/
文件夹用来存放我们的Mod文件
注意事项
Mod原理
群星中Mod的工作原理大致如下:
- 如果Mod中存在与游戏本体相同的内容,那么Mod的内容会替换掉本体的内容。
- 如果Mod中的内容在本体中不存在,那么它将会与本体的内容合并。
- 如果多个Mod重复定义了相同的内容,则只有启动器中最底部的Mod会生效,也就是说前一个Mod中相同的内容都会被后一个Mod覆盖。
文件编码
Mod中的文件需要用到两种编码模式,编码格式可以在VS Code底部的状态栏调整:
txt
文件和mod
文件使用UTF-8
编码yml
文件使用UTF-8 with BOM
编码
图片格式
图片制作完成后在PS中选择文件-存储为
,保存类型选择DDS
,然后点击保存,在弹出的对话框中选择Format
为DXT5
,勾选Mipmap
,Alpha Channel
选择Transparency
。
具体的图片尺寸可以去../Stellaris/gfx
中找对应的官方图片来确定,图标之类的文件在../Stellaris/gfx/interface/icons
中。
需要留意,虽然建筑图标的尺寸是98*98px,但是图片的左边和下边需要留出22px以上的空白,超出边界的内容不会显示。
多语言
本地化文件放置在mod/localisation
文件夹中,文件格式为yaml,不同语言的文件需要分开存放。群星根据文件开头的标识判断语言类型,英文为l_english:
,中文为l_simp_chinese:
,desc
后缀表示这段话是对上面属性的介绍。示例如下:
1 2 3 4
| //eg_l_english.yml l_english: eg:0 "Example" eg_desc:0 "This is an example description."
|
1 2 3 4
| //eg_l_simp_chinese.yml l_simp_chinese: eg:0 "示例" eg_desc:0 "这是一段示例的介绍。"
|
注意:文件名命名要独特一点,避免与其他Mod重复,重复的话可能不会生效,因为文件被覆盖了。
Mod示例
物种特质Mod
先来个最简单的,给物种添加一个永生的特质,这样领袖也不会刚满级就噶了。Mod文件目录如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| C:/Users/Documents/Paradox Interactive/Stellaris/mod/Immortal_Species_Trait │ ├─ common │ │ │ └─ trait │ │ │ └─ immortal_species_traits.txt │ ├─ gfx │ │ │ └─ interface │ │ │ └─ icon │ │ │ └─ traits │ │ │ └─ the_immortal.dds │ ├─ localisation │ │ │ ├─ ist_l_english.yml │ │ │ └─ ist_l_simp_chinese.yml │ ├─ thumbnail.png │ └─ descriptor.mod
|
下面是immortal_species_traits.txt
中的内容与说明
1 2 3 4 5 6 7 8 9 10 11
| the_immortal = { cost = 0 icon = "gfx/interface/icons/traits/the_immortal.dds" allowed_archetypes = { BIOLOGICAL } randomized = no immortal_leaders = yes modification = no ai_weight = { weight = 0 } }
|
下面是ist_l_simp_chinese.yml
中的内容
1 2 3
| l_simp_chinese: the_immortal:0 "永生" the_immortal_desc:0 "此物种永生"
|
建筑与太空基地Mod
目录结构都是大同小异的,这里对建筑定义文件进行说明,下面的建筑能让你成为一个合格的第四天灾(手动狗头)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| building_spb_sanctuary = { icon = "building_spb_sanctuary" can_be_ruined = no base_buildtime = 233 base_cap_amount = 1 planet_modifier = { pop_happiness = 0.3 planet_decision_enact_speed_mult = 1.00 planet_stability_add = 80 planet_crime_add = -80 planet_amenities_add = 233 planet_resettlement_unemployed_mult = 1.00 planet_orbital_bombardment_damage = -1.00 planet_jobs_unity_produces_mult = 0.6 planet_administrators_produces_mult = 0.6 planet_max_buildings_add = 11 pop_growth_speed = 1.0 planet_housing_add = 2333 building_time_mult = -0.3 planet_building_build_speed_mult = 0.3 planet_clear_blocker_time_mult = -0.3
job_technician_per_pop = 0.05 job_miner_per_pop = 0.2 job_chemist_per_pop = 0.05 job_gas_refiner_per_pop = 0.05 job_translucer_per_pop = 0.05 job_foundry_per_pop = 0.1 job_artisan_per_pop = 0.1 job_farmer_per_pop = 0.1 job_clerk_per_pop = 0.2 job_researcher_per_pop = 0.1
job_merchant_add = 1 job_head_researcher_add = 2 job_archaeoengineers_add = 3
planet_technician_energy_produces_add = 6 planet_miners_minerals_produces_add = 6 planet_miners_alloys_produces_add = 3 planet_metallurgists_alloys_produces_add = 6 planet_artisans_consumer_goods_produces_add = 6 planet_farmers_food_produces_add = 6
planet_jobs_exotic_gases_produces_mult = 0.6 planet_jobs_rare_crystals_produces_mult = 0.6 planet_jobs_volatile_motes_produces_mult = 0.6 planet_metallurgists_produces_mult = 0.6 planet_artisans_produces_mult = 0.6 planet_researchers_produces_mult = 0.6 trade_value_mult = 0.3 trade_value_add = 233 }
country_modifier = { country_government_civic_points_add = 3 edict_length_mult = 10.0 pop_government_ethic_attraction = 0.10 envoys_add = 3 intel_decryption_add = 30 intel_encryption_add = 30 add_base_country_intel = 30 ship_windup_mult = -0.30 ship_winddown_mult = -0.30 ship_fire_rate_mult = 0.30 ship_disengage_chance_mult = 0.3 ship_emergency_ftl_min_days_mult = -0.30 ship_emergency_ftl_mult = -0.30 country_leader_cap_add = 3 country_naval_cap_add = 3000 army_health = 0.30 country_resource_max_add = 500000 megastructure_build_speed_mult = 0.3
all_technology_research_speed = 0.3 science_ship_survey_speed = 0.3 ship_anomaly_research_speed_mult = 0.3 num_tech_alternatives_add = 3 ship_archaeological_site_excavation_speed_mult = 0.3 ship_ftl_jumpdrive_range_mult = 3.0 ship_jumpdrive_cooldown_mult = -0.3 species_leader_exp_gain = 0.3 country_resource_max_minor_artifacts_add = 2000 category_archaeostudies_research_speed_mult = 1.0 }
army_modifier = { army_starting_experience_add = 1000 } resources = { category = planet_buildings cost = { alloys = 233 } upkeep = { energy = 100 consumer_goods = 20 food = 10 } produces = { energy = 3000 unity = 100 minerals = 500 alloys = 150 consumer_goods = 150 volatile_motes = 10 exotic_gases = 10 rare_crystals = 10 nanites = 3 sr_zro = 3 sr_living_metal = 3 sr_dark_matter = 3 society_research = 100 engineering_research = 100 physics_research = 100 minor_artifacts = 3 } } allow = { owner = { is_ai = no } } }
|
领袖Mod
这个Mod实现的功能如下:
- 游戏开局时创建一个采用独特肖像的新领袖,并让这个新领袖成为新的统治者
- 这个领袖有三个专属的特质
- 每月1号重置领袖肖像与年龄(因为物种基因修饰时肖像会变成默认种族的),并消除全部负面特质
Mod的文件结构如下图所示。
以下是部分代码示例
On actions
1 2 3 4 5 6 7 8 9 10 11 12
| on_game_start_country = { events = { bronya.0 } }
on_monthly_pulse_country = { events = { bronya.3 } }
|
事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| namespace = bronya
country_event = { id = bronya.0 hide_window = yes is_triggered_only = yes trigger = { is_ai = no } immediate = { set_country_flag = ruled_by_bronya } after = { hidden_effect = { create_leader = { class = governor name = NAME_Bronya immortal = yes set_age = 17 gender = female skill = 1 traits = { trait = leader_trait_yamen trait = leader_trait_three_duck_turbo trait = leader_trait_lychee } event_leader = yes effect = { set_leader_flag = ruler_bronya } } last_created_leader = { change_leader_portrait = Bronya0 } set_leader = last_created_leader } } }
country_event = { id = bronya.3 hide_window = yes is_triggered_only = yes trigger = { is_ai = no has_country_flag = ruled_by_bronya } immediate = { if = { limit = { has_country_flag = ruled_by_bronya } every_owned_leader = { limit = { has_leader_flag = ruler_bronya } change_leader_portrait = Bronya0 set_age = 17 remove_all_negative_traits = yes } } } }
|
领袖特质
特质图标的大小是29*29像素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
leader_trait_lychee = { cost = 0 valid_for_all_ethics = yes councilor_trait = yes icon = "gfx/interface/icons/traits/trait_lychee.dds" modifier = { all_technology_research_speed = 0.3 ship_archaeological_site_excavation_speed_mult = 0.3 species_leader_exp_gain = 0.3 planet_jobs_food_produces_mult = 0.3 empire_size_penalty_mult = -0.3 country_starbase_influence_cost_mult = -0.3 army_experience_gain_mult = 0.3 pop_growth_speed = 0.3 } leader_class = { governor }
initial = no randomized = no
notify_on_gained = no }
|
肖像
我使用了最简单的方法:静态肖像,肖像图片的尺寸是496*380像素。
1 2 3 4
| portraits = { Bronya0 = {textureFile = "gfx/models/portraits/Custom/Bronya0.dds"} }
|
星系Mod
最后一个也是最复杂的一个Mod,在银河系中心创建一个自定义的星系作为帝国的初始星系,文件结构关系如下图所示。
自定义恒星系
群星中默认的恒星系类型有单星、双星、三星类型,这里我要创建一个四星星系,星系的中央是黑洞,周围环绕着一颗中子星、一颗A类恒星和一颗B类恒星。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| sc_starry_galaxy_center = { class = black_hole icon = black_hole planet = { key = pc_black_hole class = black_hole } planet = { key = pc_b_star class = b_star } planet = { key = pc_neutron_star class = neutron_star } planet = { key = pc_a_star class = a_star } spawn_odds = 0 num_planets = { min = 8 max = 25 } is_environmental_hazard = yes modifier = { ship_disengage_chance_reduction = 0.5 ship_emergency_ftl_min_days_mult = 0.5 ship_speed_reduction = 0.5 } }
|
初始星系
将初始星系设置在银河中心的原理如下:游戏开始时在地图的随机位置创建一个正常的星系,为了方便区分,我把它叫做原初始星系,在这个星系的初始化过程中使用init_effect
在银河系中心创建一个上面自定义的恒星系,我把它称为银河中心星系。最后通过事件与脚本效果,将原初始星系的人口全部迁移到银河中心星系的宜居星球上,并在银河中心星系中创建新的太空基地、科研船、工程船与舰队,再摧毁原初始星系内的所有舰船、太空基地、开采站、母星上的建筑与区划。
因为我设置的这个星系太大,代码有接近500行,这里就不全放了,只放创建星云、创建巨构的特殊代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
d_starry_galaxy_center_system = { class = "sc_black_hole" usage = custom_empire name = "starry_name_galaxy_original_system" flags = { empire_home_system } planet = { class = star orbit_distance = 0 orbit_angle = 1 size = { min = 20 max = 30 } has_ring = no name = "starry_name_galaxy_original_system" }
planet = { home_planet = yes init_effect = { set_planet_flag = starry_galaxy_center_origin_planet } }
init_effect = { set_spawn_system_batch = begin no_scope = { spawn_system = { min_distance >= 1 max_distance <= 2 min_orientation_angle = 1 max_orientation_angle = 2 hyperlane = no initializer = starry_galaxy_center_init_00 } } random_system = { limit = { has_star_flag = starry_galaxy_center_flag_0 } save_event_target_as = starry_galaxy_center_flag_0 every_neighbor_system = { limit = { has_hyperlane_to = prev } remove_hyperlane = { from = this to = prev } } } set_spawn_system_batch = end } }
starry_galaxy_center_init_00 = { class = "sc_starry_galaxy_center" name = "starry_name_galaxy_center_system" flags = { empire_cluster starry_galaxy_center_flag_0 } planet = { class = star orbit_distance = 0 name = "starry_name_galaxy_center_system" init_effect = { save_event_target_as = matter_decompressor_star clear_deposits = yes } }
planet = { class = star orbit_distance = 0 orbit_angle = 120 size = 28 has_ring = no name = "starry_name_galaxy_center_homestar" change_orbit = 60 planet = { class = pc_gaia orbit_distance = 1 orbit_angle = { min = 90 max = 270 } name = "starry_name_galaxy_center_homeland" size = 30 has_ring = yes home_planet = yes init_effect = { set_planet_flag = starry_galaxy_center_real_init_system save_event_target_as = starry_galaxy_center_capital } moon = { class = "pc_barren_cold" size = 5 orbit_distance = 12 orbit_angle = 40 has_ring = no init_effect = { set_planet_flag = starry_init_moon } } } } init_effect = { save_event_target_as = starry_galaxy_center_system_target create_ambient_object = { type = "turbulent_nebula_2" location = this } last_created_ambient_object = { set_location = { target = prev distance = 0 angle = random } } if = { limit = { is_inside_nebula = no } create_nebula = { radius = 40 } set_star_flag = starry_galaxy_center_nebula } spawn_megastructure = { type = "matter_decompressor_ruined" planet = event_target:matter_decompressor_star } } }
|
事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| namespace = starry_galaxy_center_start
planet_event = { id = starry_galaxy_center_start.1 hide_window = yes is_triggered_only = yes trigger = { has_planet_flag = starry_galaxy_center_origin_planet }
immediate = { owner = { set_country_flag = starry_galaxy_center_country }
starry_home_planet_first_pass = yes } }
country_event = { id = starry_galaxy_center_start.2 hide_window = yes is_triggered_only = yes trigger = { has_country_flag = starry_galaxy_center_country }
immediate = { capital_scope = { starry_home_planet_secondery_pass = yes } } }
|
脚本效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
| starry_home_planet_first_pass = { IF = { limit = { OR = { has_planet_flag = starry_galaxy_center_origin_planet has_planet_flag = starry_galaxy_center_real_init_system } } owner = { give_technology = { tech = "tech_gateway_activation" message = no } } } }
starry_home_planet_secondery_pass = { IF = { limit = { has_planet_flag = starry_galaxy_center_origin_planet } owner = { save_event_target_as = starry_galaxy_center_owner } random_system = { limit = { has_star_flag = starry_galaxy_center_flag_0 } create_starbase = { size = "starbase_starport" module = "shipyard" module = "shipyard" building = "crew_quarters" } every_system_planet = { if = { limit = { is_colonizable = yes is_colony = no } create_colony = { owner = event_target:starry_galaxy_center_owner species = owner_main_species } generate_start_buildings_and_districts = yes save_event_target_as = starry_galaxy_center_capital
set_owner = root set_controller = root
set_capital = yes set_name = starry_name_galaxy_center_homeland sector = { set_name = starry_name_galaxy_center_system }
add_modifier = { modifier = soothing_crystals days = -1 } add_modifier = { modifier = good_vibrations days = -1 } add_modifier = { modifier = paradise_planet days = -1 }
add_deposit = d_alien_pets_deposit add_deposit = d_hot_springs add_deposit = d_underwater_vent add_deposit = d_rushing_waterfalls add_deposit = d_submerged_ore_veins add_deposit = d_tropical_island add_deposit = d_teeming_reef add_deposit = d_crystal_reef add_deposit = d_betharian_deposit } else_if = { limit = { has_deposit_for = shipclass_mining_station has_mining_station = no } create_mining_station = { owner = root } } else_if = { limit = { has_deposit_for = shipclass_research_station has_research_station = no } create_research_station = { owner = root } } } create_fleet = { effect = { set_owner = root create_ship = { name = random random_existing_design = science } set_fleet_stance = evasive } } create_fleet = { effect = { set_owner = root create_ship = { name = random random_existing_design = constructor } set_fleet_stance = evasive } } create_fleet = { set_take_point = yes effect = { set_owner = root set_name = "starry_first_fleet_name" while = { count = 3 create_ship = { name = random random_existing_design = corvette } } } } solar_system = { set_surveyed = { surveyed = yes surveyor = event_target:starry_galaxy_center_owner } } solar_system = { every_system_planet = { limit = { has_planet_flag = starry_init_moon } prevent_anomaly = yes add_modifier = { modifier = terraforming_candidate days = -1 } } } } every_owned_pop = { resettle_pop = { pop = THIS planet = event_target:starry_galaxy_center_capital } unemploy_pop = yes } remove_all_buildings = yes remove_all_districts = yes clear_deposits = yes destroy_colony = yes change_pc = pc_shielded solar_system = { every_fleet_in_system = { delete_fleet = { target = this kill_leader = no } } set_name = random } } }
|
Steam创意工坊
Mod制作完成后就可以上传到创意工坊了,这样其他玩家就可以订阅和使用你的Mod。
添加封面
在群星的启动器中,本地的Mod是不会显示封面的,只有Steam创意工坊订阅的Mod才会有封面,这个封面也是Mod在创意工坊中显示的封面。
封面图片有以下几点注意事项:
- 图片大小不超过
1MB
- 格式建议使用
png
- 长宽比一般为
1:1
- 建议命名为
thumbnail.png
,这里额外留意系统是否开启了文件扩展名显示
封面制作完成后打开mod文件夹内的descriptor.mod
,我这里的文件路径为.../mod/exp/descriptor.mod
,粘贴下面的代码并保存。
上传Mod
- 在群星启动器的左边栏中选择
所有已安装Mod
,然后点击右上角的上传MOD
- 在Mod下面的下拉菜单选择要上传的Mod
- 此时可以给Mod改名以及调整Mod支持的游戏版本
Mod ID
不需要填,上传时会自动生成- 选择上传至
Steam创意工坊
- 描述可以先不写,等后面到创意工坊里再写
- 点击
上传Mod
- 在Steam中找到自己的创意工坊物品,然后可以更改Mod的描述,并添加预览图片
- 编辑完成后记得更改可见性为公开,这样其他玩家才能搜索到你的Mod
更新Mod
更新Mod的步骤和上传大同小异:
- 在群星启动器的左边栏中选择
所有已安装Mod
,然后点击右上角的上传MOD
- 在Mod下面的下拉菜单选择要更新的Mod
Mod ID
中会自动填入Mod在创意工坊中的ID,依然不需要我们手动填- 点击
上传Mod
即可