Posted onEdited onInOpen Source ProjectsWord count in article: 3.6kReading time ≈13 mins.
How to become a qualified 4th crisis without using the console.
The Mods mentioned in the document were created based on Stellaris version 3.8.4, with the launcher version being 2023.11. Please be aware of their timeliness.
The Paradox Wiki provides detailed instructions on mod creation. This document serves only as a personal development record for the mod and as a supplement to the Wiki content.
Software Installations
CWTools
Paradox Language Services
PhotoShop DDS Plug-in
DDS plug-in for After Effects and Photoshop
VS Code
Stellaris configuration files are mostly in txt format and can be edited using VS Code with the CWTools extension installed. CWTools provides features like code autocompletion and error prompts, making it quite convenient. After installation, you can set the Stellaris installation path in the extension settings, which is typically located at [Steam installation path]/steamapps/common/Stellaris/.
DDS Plug-in
In Stellaris, many image files are in DDS format. To save images as DDS format in Photoshop, you need to install a plugin. Place the downloaded plugin file (.8bi) into the ./Required/Plug-ins/File Formats folder within the Photoshop directory. Then, open Photoshop, and if you see DDS under Help -> About Plug-In in the menu, it means the installation was successful.
Mod Creation
In the Stellaris launcher, select “All installed mods” from the left sidebar, then click on “UPLOAD MOD” in the upper right corner.
In the pop-up window, provide the necessary information, which you can modify later:
Name: The name that will be displayed for your mod in the launcher and the Steam Workshop. For example, let’s use Example here.
Version: The game version your mod is compatible with. You can enter the current minor version, such as 3.8.4, or use an asterisk * to indicate compatibility with the entire 3.8 major version, like 3.8.*.
Directory: Enter the name of the folder where your mod files are located, following mod/. This name can be different from your mod’s name. Let’s use exp as an example.
Tags: Categories that describe your mod’s content changes, mainly for others to filter mods in the Steam Workshop by different types.
Click on CREATE MOD.
A folder with the name you provided for the directory and a corresponding .mod file will appear in C:/Users/Documents/Paradox Interactive/Stellaris/mod.
The directory of the files after the mod is created is as follows:
.../mod/exp.mod records the information we provided when creating the local mod and generally doesn’t need editing.
.../mod/exp/descriptor.mod is similar to .../mod/exp.mod, we will use it when uploading the mod to the Steam Workshop later.
The .../mod/exp/ folder is used to store our mod files.
Notes
Mod Principles
The operation of mods in Stellaris works roughly as follows:
If a mod contains content identical to the base game, the mod’s content will replace the base game’s content.
If the content in a mod does not exist in the base game, it will merge with the base game’s content.
If multiple mods define the same content, only the mod at the bottom of the launcher’s mod list will take effect, meaning that the content from earlier mods with the same definition will be overridden by later mods.
File Encoding
Mod files require two different encoding modes, which can be adjusted from the status bar at the bottom of VS Code:
txt and mod files use UTF-8 encoding.
yml files use UTF-8 with BOM encoding.
Image Formats
After completing image creation in Photoshop, go to File -> Save As, select the file type as DDS, and then click save. In the pop-up dialog, set Format to DXT5, check Mipmap, and for Alpha Channel, choose Transparency.
For specific image dimensions, you can refer to official images located in ../Stellaris/gfx. Files like icons for interfaces can be found in ../Stellaris/gfx/interface/icons.
Please note that although the size of building icons is 98x98px, you should leave at least 22px or more of blank space on the left and bottom of the image. Content exceeding these boundaries will not be displayed.
Localization files are placed in the mod/localisation folder, and the file format is YAML. Files for different languages should be stored separately. Stellaris determines the language type based on the identifier at the beginning of the file: English uses l_english:, Simplified Chinese uses l_simp_chinese:, and desc suffix indicates that the following text is an explanation of the above property. Examples are given below:
1 2 3 4
//eg_l_english.yml l_english: eg:0"Example" eg_desc:0"This is an example description."
Note: File naming should be unique to avoid conflicts with other mods. If there are duplicates, it may not work because the files get overwritten.
Mod Example
Species Trait Mod
Let’s start with something simple: adding an immortal trait to a species so that leaders don’t die of old age as soon as they reach maximum level. The Mod file directory is as follows:
Here is the content and explanation from immortal_species_traits.txt:
1 2 3 4 5 6 7 8 9 10 11
the_immortal = { cost = 0# Trait point cost icon = "gfx/interface/icons/traits/the_immortal.dds"# Icon path allowed_archetypes = { BIOLOGICAL } # Only allowed for biological species, not for machines randomized = no # This trait can not be randomly generated among species in the galaxy immortal_leaders = yes # Leaders with this trait are immortal, same effect as the Chosen One trait modification = no # This trait can not be acquired through species genetic modification ai_weight = { weight = 0# Can AI use this trait? 0 means AI is prohibited from using it. } }
And here is the content from ist_l_english.yml:
1 2 3
l_english: the_immortal:0"Immortal" the_immortal_desc:0"This species has an extremely long lifespan"
Building and Spaceport Mod
The directory structure is largely similar, so here’s an explanation of building definition files. The following buildings can turn you into a qualified 4th crisis (LOL).
building_spb_sanctuary = { icon = "building_spb_sanctuary"# Icon name, no need to include the path, it defaults to ./gfx/interface/icons/buildings/ can_be_ruined = no # Cannot be destroyed, won't be damaged during orbital bombardment base_buildtime = 233# Default build time base_cap_amount = 1# Number of these buildings that can be constructed on one planet
planet_modifier = { # Modifiers that only apply on the planet pop_happiness = 0.3# Pop happiness +30% planet_decision_enact_speed_mult = 1.00# Planet decision enactment speed +100% planet_stability_add = 80# Planet stability +80 planet_crime_add = -80# Crime -80 planet_amenities_add = 233# Amenities +233 planet_resettlement_unemployed_mult = 1.00# Resettlement of unemployed pops speed +100% planet_orbital_bombardment_damage = -1.00# Orbital bombardment damage reduction 100% planet_jobs_unity_produces_mult = 0.6# Jobs produce Unity +60% planet_administrators_produces_mult = 0.6# Administrators produce +60% planet_max_buildings_add = 11# Planet building slots +11 pop_growth_speed = 1.0# Organic pop growth speed +100% planet_housing_add = 2333# Housing +2333 building_time_mult = -0.3# Building time -30% planet_building_build_speed_mult = 0.3# Building build speed +30% planet_clear_blocker_time_mult = -0.3# Clear blocker time -30%
# The following indicates how many jobs are added per population for each type of job job_technician_per_pop = 0.05# Technician, displays as every 20 pops add 1 of this job job_miner_per_pop = 0.2# Miner job_chemist_per_pop = 0.05# Chemist job_gas_refiner_per_pop = 0.05# Gas Refiner job_translucer_per_pop = 0.05# Translucer job_foundry_per_pop = 0.1# Foundry job_artisan_per_pop = 0.1# Artisan job_farmer_per_pop = 0.1# Farmer job_clerk_per_pop = 0.2# Clerk job_researcher_per_pop = 0.1# Researcher
# The following indicates how many fixed output points each job type generates job_merchant_add = 1# Merchant job_head_researcher_add = 2# Head Researcher job_archaeoengineers_add = 3# Archaeoengineers
# The following indicates how many points of fixed output are added for each job type planet_technician_energy_produces_add = 6# Technicians produce Energy planet_miners_minerals_produces_add = 6# Miners produce Minerals planet_miners_alloys_produces_add = 3# Miners produce Alloys (surprise!) planet_metallurgists_alloys_produces_add = 6# Metallurgists produce Alloys planet_artisans_consumer_goods_produces_add = 6# Artisans produce Consumer Goods planet_farmers_food_produces_add = 6# Farmers produce Food
# The following indicates the percentage output increase for each job type planet_jobs_exotic_gases_produces_mult = 0.6# Jobs that produce Exotic Gases +60% planet_jobs_rare_crystals_produces_mult = 0.6# Jobs that produce Rare Crystals +60% planet_jobs_volatile_motes_produces_mult = 0.6# Jobs that produce Volatile Motes +60% planet_metallurgists_produces_mult = 0.6# Metallurgists, jobs producing Alloys +60% planet_artisans_produces_mult = 0.6# Artisans, jobs producing Consumer Goods +60% planet_researchers_produces_mult = 0.6# Researchers, jobs producing Research +60%
trade_value_mult = 0.3# Trade value +30% trade_value_add = 233# Fixed trade value added +233 }
allow = { owner = { is_ai = no } } # Prohibits AI from building }
Leader Mod
This mod provides the following functionalities:
Creates a new leader with a unique portrait at the start of the game and makes this new leader the new ruler.
This leader possesses three exclusive traits.
Resets the leader’s portrait and age on the 1st of every month (because when species gene modification occurs, the portrait reverts to the default species) and removes all negative traits.
The file structure of this Mod is shown below.
The following are some partial code examples
On actions
On actions is a way of triggering events, see Paradox Wiki for more information.
1 2 3 4 5 6 7 8 9 10 11 12
# common/on_actions/00_bronya.txt on_game_start_country = { # Execute the event bronya.0 at the start of the game events = { bronya.0 } }
on_monthly_pulse_country = { # Execute event bronya.3 at the beginning of each month events = { bronya.3 } }
country_event = { # Creating a leader and setting her as the ruler at the start of the game id = bronya.0# Event ID, used by triggers to match the event to execute hide_window = yes # Hide the event pop-up window is_triggered_only = yes # Specifies that the event can only be triggered by triggers or another event; otherwise, it would be constantly triggered, increasing CPU load trigger = { is_ai = no # Prevent AI from using this } immediate = { # Actions to be executed immediately after the event is triggered set_country_flag = ruled_by_bronya # Add a flag to the country for later matching } after = { hidden_effect = { # Perform actions without generating notifications create_leader = { # Create a leader class = governor # Governor type name = NAME_Bronya # Name key; its value needs to be set in the localization file immortal = yes # Immortal, won't die of old age set_age = 17# Set age (Note: Doesn't take effect here) gender = female # Gender skill = 1# Skill level traits = { # Set traits trait = leader_trait_yamen trait = leader_trait_three_duck_turbo trait = leader_trait_lychee } event_leader = yes # Prevent leader from joining factions effect = { set_leader_flag = ruler_bronya # Add a flag to the leader } } last_created_leader = { change_leader_portrait = Bronya0 # Set the portrait } set_leader = last_created_leader # Set as the ruler } } }
# Monthly event used to restore portraits, etc. country_event = { id = bronya.3 hide_window = yes is_triggered_only = yes trigger = { is_ai = no has_country_flag = ruled_by_bronya # Only countries with this flag can trigger this event } immediate = { if = { limit = { has_country_flag = ruled_by_bronya # Match the country } every_owned_leader = { limit = { has_leader_flag = ruler_bronya # Match the leader } change_leader_portrait = Bronya0 # Set the portrait set_age = 17# Set age remove_all_negative_traits = yes # Remove all negative traits } } } }
The last and most complex mod involves creating a custom solar system at the center of the Milky Way as the initial galaxy for your empire. The file structure is shown below.
Custom Solar System Class
In Stellaris, the default solar system types include single stars, binary stars, and trinary stars. Here, I want to create a quaternary solar system with a black hole at the center, surrounded by a neutron star, an A-class star, and a B-class star.
# common/star_classes/starry_star_classes.txt sc_starry_galaxy_center = { class = black_hole # Setting the system background icon = black_hole # Setting the icon style of the system on the star map planet = { # Black hole key = pc_black_hole class = black_hole } planet = { # B-class star key = pc_b_star class = b_star } planet = { # Neutron star key = pc_neutron_star class = neutron_star } planet = { # A-class star key = pc_a_star class = a_star } spawn_odds = 0# The probability of generating such solar systems randomly is... num_planets = { # Number of planets in the system min = 8 max = 25 } is_environmental_hazard = yes # Are there any environmental hazards modifier = { ship_disengage_chance_reduction = 0.5 ship_emergency_ftl_min_days_mult = 0.5 ship_speed_reduction = 0.5 } }
Custom Starting Solar System
The principle of setting the initial galaxy at the center of the Milky Way is as follows: at the beginning of the game, create a regular solar system at a random location on the map. For the sake of distinction, I refer to this as the “original starting solar system.” During the initialization process of this solar system, use init_effect to create the custom solar system at the center of the galaxy, which I call the “Central Galaxy.” Finally, through events and script effects, migrate all population from the original starting solar system to habitable planets in the Central Galaxy, create new spaceports, science ships, construction ships, and fleets in the Central Galaxy, and then dismantle all ships, spaceports, mining stations, and buildings within the original starting solar system and its sectors.
Because the solar system I’ve set up is quite extensive, the code spans nearly 500 lines. I won’t include all of it here, but I’ll provide the specific code for creating nebulas and constructing megastructures.
# The initializer for the original starting solar system. 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" }
init_effect = { set_spawn_system_batch = begin # Optimising the effect of spawn_system calls # Generate Central Galaxy 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 # Calling the Central Galaxy initialiser } } # Remove all hyper lanes 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 } ############################## # Omitted content ############################## }
# Central Galaxy initialiser starry_galaxy_center_init_00 = { class = "sc_starry_galaxy_center"# The previously customised solar system class name = "starry_name_galaxy_center_system" flags = { empire_cluster starry_galaxy_center_flag_0 } # Black holes with damaged matter decompressor planet = { class = star orbit_distance = 0 name = "starry_name_galaxy_center_system" init_effect = { save_event_target_as = matter_decompressor_star clear_deposits = yes } }
set_capital = yes # Set as capital set_name = starry_name_galaxy_center_homeland # Set homeworld name sector = { # Set sector name set_name = starry_name_galaxy_center_system }
# Add deposits to homeworld 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 } # Create mining station else_if = { limit = { has_deposit_for = shipclass_mining_station has_mining_station = no } create_mining_station = { owner = root } } # Create research station else_if = { limit = { has_deposit_for = shipclass_research_station has_research_station = no } create_research_station = { owner = root } } } # Recreate science ship create_fleet = { effect = { set_owner = root create_ship = { name = random random_existing_design = science } set_fleet_stance = evasive } } # Recreate constructor ship create_fleet = { effect = { set_owner = root create_ship = { name = random random_existing_design = constructor } set_fleet_stance = evasive } } # Recreate military fleet 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 } } } } # Set Central Galaxy as surveyed solar_system = { set_surveyed = { surveyed = yes surveyor = event_target:starry_galaxy_center_owner } } # Set the moon as a cCandidate planet for terraforming solar_system = { every_system_planet = { limit = { has_planet_flag = starry_init_moon } prevent_anomaly = yes add_modifier = { modifier = terraforming_candidate days = -1 } } } } # Move the entire population to this planet every_owned_pop = { resettle_pop = { pop = THIS planet = event_target:starry_galaxy_center_capital } unemploy_pop = yes } # Abandonment of the original planet and change of the planet to the shielded planet remove_all_buildings = yes remove_all_districts = yes clear_deposits = yes destroy_colony = yes change_pc = pc_shielded # Destroy all ships and space bases in the original starting solar system. solar_system = { every_fleet_in_system = { delete_fleet = { target = this kill_leader = no } } set_name = random } } }
Steam Workshop
Once your mod is complete, you can upload it to the Steam Workshop, allowing other players to subscribe to and use your mod.
Add a Cover Image
In Stellaris’ launcher, locally created mods won’t display a cover image. Only mods subscribed to on the Steam Workshop will have a cover image, which serves as the thumbnail for your mod on the Workshop.
Here are some considerations for the cover image:
The image size should not exceed 1MB.
It’s recommended to use the png format.
The aspect ratio is generally 1:1.
It’s suggested to name it thumbnail.png, but ensure your system displays file extensions.
After creating the cover image, open the descriptor.mod file inside your mod folder. In my case, the file path is .../mod/exp/descriptor.mod. Paste the following code and save:
1
picture="thumbnail.png"
Upload Mod
In the Stellaris launcher, select All installed mods from the left sidebar, then click UPLOAD MOD in the upper right corner.
In the dropdown menu under Mod, select the mod you want to upload.
At this point, you can rename the mod and adjust the game version it supports.
You don’t need to fill in the Mod ID; it will be generated automatically during upload.
Choose to upload it to the Steam Workshop.
You can leave the description blank for now and add it later on the Workshop.
Click Upload Mod.
In Steam, find your Workshop item and then edit the mod’s description and add preview images.
After editing, remember to change the visibility to Public so that other players can search for your mod.
Update Mod
The steps for updating a mod are similar to uploading:
In the Stellaris launcher, select All installed mods from the left sidebar, then click UPLOAD MOD in the upper right corner.
In the dropdown menu under Mod, select the mod you want to update.
The Mod ID field will be automatically filled with the mod’s Workshop ID; you don’t need to fill it manually.