System modding

本页面部分全部内容上次核对于3.1版本


This guide is for adding and modifying Solar Systems to the game.

Game Map and System Creation[编辑 | 编辑源代码]

Stellaris appears to create the game map first using the \map files to create coordinates for the stars on the galaxy map, and then use the \star_classes file to pick what star class is at each coordinate, and then finalize the system with additional contents (planets, moons, asteroid belts) from the \system initializer files and \planet_classes files.

Star classes[编辑 | 编辑源代码]

Star classes can be found in common/star_classes. If you want to create one from scratch, create a new file and place it in that folder.

Note that "stars" and "star classes" are two different things: individual stars are considered the same as planets in the game code, and are found in common/planet_classes, while star classes refer to the classification of a solar system as a whole and will determine lighting, the system's icon in the galaxy map, and number of individual stars in a solar system. Information about modding individual stars can be found here.

Adding new star classes[编辑 | 编辑源代码]

Making a new star class is easy. Here's an example of a binary system that can be found in 00_star_classes:

sc_binary_1 = { # X-ray Binary Star System: Blue star around a Pulsar
    class             = a_star
    icon              = e_binary_star
    planet            = {
        key = pc_a_star
        class = a_star
    }
    planet            = {
        key = pc_pulsar
        class = pulsar
    }
    spawn_odds         = 5
    num_planets     = { min = 4 max = 10 }

    pc_desert       = { spawn_odds = 0 }
    pc_tropical     = { spawn_odds = 0 }
    pc_arid         = { spawn_odds = 0 }
    pc_continental  = { spawn_odds = 0 }
    pc_ocean        = { spawn_odds = 0 }
    pc_tundra       = { spawn_odds = 0 }
    pc_arctic       = { spawn_odds = 0 }
    pc_gaia         = { spawn_odds = 0 }
    pc_alpine       = { spawn_odds = 0 }
    pc_savannah     = { spawn_odds = 0 }

    is_environmental_hazard = yes
    modifier = { ship_shield_reduction = 1.0 }
}
  • "sc_binary_1" is the name of the star class used by the code. To assign the name the player will see, see localisation modding.
  • "class" is used to determine the system's lighting. You can use an existing one or create your own via gfx modding.
  • "icon" is the icon used by this system type in the galaxy view. By default it'll search for one that matches the star name ("binary_1_star" in this case) in the gfx/map/star_classes folder, but using "icon" lets you overwrite this with whatever icon you want.
  • While not included in the example above, you can also use "icon_scale = " to change the size of the icon on the galaxy map. 1 is default, 0.5 is half the size, etc.
  • "planet" is the type of star used by this star class by default. If it's a unary system with just one star, you don't need to write "class" again.
  • "spawn_odds" is exactly what it sounds like: the likelihood that this star class will spawn if it's used in a random list such as rl_standard_stars. If you don't plan to put it in a list, you can use any number or leave it out entirely.
  • "num_planets" is the number of planets that can be found in these systems. The number of planets in the solar system initializer will overwrite this by default, but if a random range is used there it'll use the number from here.
  • The planets' spawn odds are for if you want to alter the likelihood that certain planet classes will spawn in these systems. Neutron Stars, for example, have the values set to 0 by default since these systems won't be hospitable for life forms.
  • "is_environmental_hazard" marks the system as a hazard, obviously. The "modifier" applies a buff or debuff to ships and stations in the system.

Vanilla star classes[编辑 | 编辑源代码]

For reference, the existing star classes are the following:

Icon Class Star type Environmental effects
B Star.png sc_b Class B Star
A Star.png sc_a Class A Star
F Star.png sc_f Class F Star
G Star.png sc_g Class G Star
K Star.png sc_k Class K Star
M Star.png sc_m Class M Star
M Red Giant Star.png sc_m_giant Class M Red Giant
T Star.png sc_t Class T Brown Dwarf
Black Hole.png sc_black_hole Black Hole 战斗撤离几率 Combat Disengagement Chance +50% Disengagement Chance Reduction
速度 Speed +50% Emergency FTL Jump Cooldown
Neutron Star.png sc_neutron_star Neutron Star 亚光速航速 Sublight Speed +50% Sublight Speed Reduction
Pulsar.png sc_pulsar Pulsar 护盾承受值 Shield Hit Points +100% Shield Nullification
E binary star.png sc_binary_1 Binary Stars (A, Pulsar) 护盾承受值 Shield Hit Points +100% Shield Nullification
E binary star.png sc_binary_2 Binary Stars (B, Neutron Star) 亚光速航速 Sublight Speed +50% Sublight Speed Reduction
C binary star.png sc_binary_3 Binary Stars (M Giant, B)
C binary star.png sc_binary_4 Binary Stars (M Giant, F)
A binary star.png sc_binary_5 Binary Stars (B, B)
D binary star.png sc_binary_6 Binary Stars (M, G)
D binary star.png sc_binary_7 Binary Stars (K, F)
D binary star.png sc_binary_8 Binary Stars (G, F)
A binary star.png sc_binary_9 Binary Stars (A, F)
A binary star.png sc_binary_10 Binary Stars (A, T)
A trinary star.png sc_trinary_1 Trinary Stars (G, M, K)
A trinary star.png sc_trinary_2 Trinary Stars (B, A, F)
A trinary star.png sc_trinary_3 Trinary Stars (K, F, G)
A trinary star.png sc_trinary_4 Trinary Stars (B, K, T)

Solar system initializers[编辑 | 编辑源代码]

Solar systems are found in common/solar_system_initializers. If you want to create one from scratch, create a new file and place it in that folder.

For additional information, see example.txt inside the folder.

Unary Systems[编辑 | 编辑源代码]

A unary system consists of just one star and a handful of planets and moons. These are the most common types of systems in Stellaris, and we'll start our tutorial by making one.

@base_moon_distance = 10

my_system_initializer = {
    name = "My System"
    class = "rl_standard_stars"

    asteroid_belt = {
        type = rocky_asteroid_belt
        radius = 70
    }

    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 0
        orbit_angle = 1
    }

    change_orbit = 10

    planet = {
        class = pc_arid
        orbit_distance = 30
        orbit_angle = { min = 90 max = 270 }

        init_effect = {
            prevent_anomaly = yes
            generate_primitives_on_planet = yes
        }

        change_orbit = @base_moon_distance

        moon = {
            count = { min = 0 max = 1 }
            class = pc_molten
            orbit_distance = 5
            orbit_angle = { min = 90 max = 270 }
        }
    }

    change_orbit = 30

    planet = {
        count = { min = 1 max = 4 }
        class = pc_asteroid
        orbit_distance = 0
        orbit_angle = { min = 90 max = 270 }
    }

    planet = {
        count = { min = 3 max = 6 }
        orbit_distance = 20
        orbit_angle = { min = 90 max = 270 }

        change_orbit = @base_moon_distance

        moon = {
            count = { min = 0 max = 1 }
            orbit_distance = 5
            orbit_angle = { min = 90 max = 270 }
        }
    }

    neighbor_system = {
        trigger = { num_guaranteed_colonies >= 1 }
        distance = { min = 10 max = @distance }	
        initializer = "sol_neighbor_t1_first_colony"
    }
}

As before, let's go over each element one by one.

@base_moon_distance = 10

my_system_initializer = {
    name = "My System"
    class = "rl_standard_stars"

    asteroid_belt = {
        type = rocky_asteroid_belt
        radius = 70
    }
  • "@base_moon_distance" is a variable that can be set in each solar system initializer file. It's not strictly needed, but can be useful if you want to play around with moon orbit distances en masse rather than one at a time. All vanilla solar systems use 10 by default.
  • "my_system_initializer" is, again, the name the game code uses to identify this system. No need for localisation this time; the name the player will see is right there below it (in this case, "My System").
  • "class" is, of course, the star class. You can use a specific class such as sc_b, or a random list such as rl_standard_stars, which chooses a random one based on the spawn_odds in each star's code.
  • "asteroid_belt" adds an asteroid belt at a certain distance from the center of the system -- not necessarily from the sun! We'll get to that later. "type" refers to either a rocky, icy, or crystal asteroid belt, plus any others that one might mod into the game.

Now for the system's sun. Note that the star is, as I mentioned above, considered a planet by the game engine.

    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 0
        orbit_angle = 1
    }
  • "class", in the context of a planet refers to the planet class. Using "class = star" will make it the star class that matches the star type, so if we'd used sc_b above, the star would be pc_b_star -- a Class B Star. You can use pc_b_star anyway if you want, but that can cause complications with star lighting and, in a binary/trinary system, planet naming. More on that below. Anyway, just using "class = star" for the stars is recommended unless you have a good reason not to.
  • "size" is the size of the planet. This used to refer to the number of planet tiles, but since tiles are obsolete in general and useless on stars anyway, it just makes the star appear bigger or smaller. A size range of 20-35 is recommended for stars, since smaller than that looks silly and larger can swallow up ships flying overhead.
  • "orbit_distance" is the distance from the previous element, or if no such element exists, the system's center. For the lone star in a system, you naturally want this to be 0.
  • "orbit_angle" is the orbital angle from the previous planet, so if the previous had an angle of 30, using "orbit_angle = 20" would give it an overall angle of 50. Again, for the central star, this doesn't matter so you can use any old number. Most vanilla stars use 1 for some reason, so that's what I did here.

Now that the star is done, let's move on to the first planet.

    change_orbit = 10

    planet = {
        class = pc_arid
        orbit_distance = 30
        orbit_angle = { min = 90 max = 270 }

        init_effect = {
            prevent_anomaly = yes
            generate_primitives_on_planet = yes
        }

  • "change_orbit" increases the spacing between planets (in the system scope), or between a planet and its first moon (in the planet scope).
  • "class = pc_arid", so it will be an Planet arid.png Arid World.
  • "orbit_distance = 30" adds 30 units of space between the planet and the last element (in this case, "change_orbit = 10", so its total distance from the sun is 40 units).
  • "orbit_angle = { min = 90 max = 270 )" is pretty straightforward: a random angle, within ninety degrees of the previous element.
  • "init_effect" allows you to apply effects and scripted effects to the planet upon system generation. It can also be used in the system scope if you want to apply an effect to the system as a whole instead of just one planet.
    • "prevent_anomaly" is an effect that disables anomalies from appearing on this planet.
    • "generate_primitives_on_planet" is a scripted effect that creates a pre-FTL species on this planet.

Now for a moon.

        change_orbit = @base_moon_distance

        moon = {
            count = { min = 0 max = 1 }
            class = pc_molten
            orbit_distance = 5
            orbit_angle = { min = 90 max = 270 }
        }
    }
  • "change_orbit = @base_moon_distance" here adds 10 units of distance between the planet and its moon as indicated in the @ variable.
  • "count = { min = 0 max = 1 }" to randomize the number of moons between 0 and 1. You can go as high or as low as you want with this, though usually in vanilla you won't find more than 1 moon unless the planet is a gas giant.
  • "class = pc_molten" (for a Planet molten.png Molten World).
  • "orbit_distance = 5" (for a total of 15, including the "change_orbit" above).
  • "orbit_angle = { min = 90 max = 270 }", for the same randomized orbit angles as used in the planet itself.
    change_orbit = 30

    planet = {
        count = { min = 1 max = 4 }
        class = pc_asteroid
        orbit_distance = 0
        orbit_angle = { min = 90 max = 270 }
    }

Time to fill out the asteroid belt. We use "@change_orbit" again, this time keeping a close eye on the number used so that the total number of space used matches the 70 defined in the asteroid belt at the top of the file. Now we add the asteroids, making sure that "orbit_distance = 0" for all of them. We want them inside the asteroid belt, after all! "orbit_angle" is a little tricky here: since the asteroids are all in the same orbit, it's possible that they might clip together. You can get away from that by directly choosing their specific orbit angles.

If your asteroid belt is icy rather than rocky, use "pc_ice_asteroid" instead of "pc_asteroid". If it's crystalline, use "pc_crystal_asteroid" or "pc_rare_crystal_asteroid".

    planet = {
        count = { min = 3 max = 6 }
        orbit_distance = 20
        orbit_angle = { min = 90 max = 270 }

        change_orbit = @base_moon_distance

        moon = {
            count = { min = 0 max = 1 }
            orbit_distance = 5
            orbit_angle = { min = 90 max = 270 }
        }
    }

More planets! We'll leave "class = " out for these ones, allowing them to spawn as whatever the game engine wants them to be (based on the criteria spelled out in common/star_classes). The number of planets is also randomized between 3 and 6, each of which has 0 to 1 moons.

    neighbor_system = {
        trigger = {
            num_guaranteed_colonies >= 1
        }
        distance = { min = 10 max = @distance }	
        initializer = "sol_neighbor_t1_first_colony"
    }
}
  • "neighbor_system" tells the game to spawn another, specific system within a certain distance of this system, and under what criteria. Pretty self-explanatory.

Binary and Trinary Systems[编辑 | 编辑源代码]

Some star systems have two or three suns, respectively. Such systems can be pretty complex in real life (just ask Mintaka!) but generally there are two types of binary/trinary systems, classified as "P-Type" and "S-Type".

P-Type[编辑 | 编辑源代码]

P-Type (or "circumbinary") systems have planets that orbit the barycenter of both (or all three) stars simultaneously. Sirius is an example of this kind of system, as is Tatooine in the Star Wars universe.

P-Types are the easiest to make in Stellaris. Instead of a single star with "orbit_distance = 0", do the following:

    planet = {
        class = star
        size = { min = 30 max = 35 }
        orbit_distance = 15
        orbit_angle = { min = 90 max = 270 }
    }
    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 10
        orbit_angle = 180
    }

Then just add your planets as normal, change the star class to rl_binary_stars or rl_trinary_stars (or a specific class of either), and you're good to go!

  • Using "class = star" for both/all three stars will assign their class in accordance with the type of binary/trinary system: with "sc_binary_1", for instance, the first star will be A-class, and the second will be a Pulsar.
  • If it's a trinary instead of a binary:
    • Add a third star in the same manner.
    • Change the second star's orbit angle to 145.
    • Give the third star an orbit angle of 70, an orbit distance of 0, and a maximum size of 25.
  • The orbit distances, orbit angles, and star sizes are entirely up to you; the values given above just look the nicest in my opinion. Feel free to experiment!

S-Type[编辑 | 编辑源代码]

In S-Type systems, each star has its own system of planets. Think of them as two or three unary systems that are close enough together that you can travel between them without needing a hyperdrive. 40 Eridani is an example of such a system, as is Vulcan in the Star Trek universe.

To recap, a unary system with one sun has basically this structure:

    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 0
        orbit_angle = 1
    }

    planet = {
        count = { min = 3 max = 6 }
        orbit_distance = 20
        orbit_angle = { min = 90 max = 270 }

        change_orbit = @base_moon_distance

        moon = {
            count = { min = 0 max = 1 }
            orbit_distance = 5
            orbit_angle = { min = 90 max = 270 }
        }
    }

The structure of an S-type star and its planets looks more like this:

    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 0
        orbit_angle = 1
        satellite_naming_policy = upper_case_roman_numerals

        planet = {
            count = { min = 3 max = 6 }
            orbit_distance = 20
            orbit_angle = { min = 90 max = 270 }
            satellite_naming_policy = lower_case_latin_letters

            change_orbit = @base_moon_distance

            moon = {
                count = { min = 0 max = 1 }
                orbit_distance = 5
                orbit_angle = { min = 90 max = 270 }
            }
        }
    }

See the differences?

  • In a unary system, the planets are all defined in the system scope. In an S-type binary or trinary system, the planets are defined in their specific star's scope. This ensures that they will have the correct orbit lines and names.
  • "satellite_naming_policy" indicates how this star's planets (or this planet's moons) will be named. A star should use "upper_case_roman_numerals" for its planets; planets should use "lower_case_latin_letters" for their moons.

A full S-type trinary system would look like this:

    planet = {
        class = star
        size = { min = 30 max = 35 }
        orbit_distance = 0
        orbit_angle = 1
        satellite_naming_policy = upper_case_roman_numerals

        planet = {
            count = { min = 3 max = 6 }
            orbit_distance = 20
            orbit_angle = { min = 90 max = 270 }
            satellite_naming_policy = lower_case_latin_letters

            change_orbit = @base_moon_distance

            moon = {
                count = { min = 0 max = 1 }
                orbit_distance = 5
                orbit_angle = { min = 90 max = 270 }
            }
        }
    }

    planet = {
        class = star
        size = { min = 25 max = 30 }
        orbit_distance = 230
        orbit_angle = { min = 90 max = 270 }
        satellite_naming_policy = upper_case_roman_numerals

        planet = {
            count = { min = 3 max = 5 }
            orbit_distance = 20
            orbit_angle = { min = 90 max = 270 }
            satellite_naming_policy = lower_case_latin_letters

            change_orbit = @base_moon_distance

            moon = {
                count = { min = 0 max = 1 }
                orbit_distance = 5
                orbit_angle = { min = 90 max = 270 }
            }
        }
    }

    planet = {
        class = star
        size = { min = 20 max = 25 }
        orbit_distance = 0
        orbit_angle = { min = 90 max = 270 }
        satellite_naming_policy = upper_case_roman_numerals

        planet = {
            count = { min = 2 max = 4 }
            orbit_distance = 20
            orbit_angle = { min = 90 max = 270 }
            satellite_naming_policy = lower_case_latin_letters

            change_orbit = @base_moon_distance

            moon = {
                count = { min = 0 max = 1 }
                orbit_distance = 5
                orbit_angle = { min = 90 max = 270 }
            }
        }
    }
  • The second star, Star B, orbits 230 units away from the first, Star A. This is because we don't want the two systems to overlap. Star A has up to six planets, each orbiting at a distance of 20, which gives us a maximum system width of 120. Star B has up to five, giving it a maximum width of 100. 120 + 100 = 220, so we use 230 to give them a little extra space.
  • The third star, Star C, orbits at the same distance from A as B but at a different angle. This isn't a hard requirement, you can space it out further if you want, but all the vanilla systems do it that way and it just looks nicer in my opinion. We don't want systems to be too big, or it'll take forever to cross them at sublight speeds.

Usage[编辑 | 编辑源代码]

One thing I haven't gone over is usage -- how the game knows which system to generate. There are a few ways to do this, applied in the system scope.

  • "usage = misc_system_init" tells the game to randomly generate this system somewhere in the galaxy, based on the value entered for "usage_odds". You can also use modifiers for these if you want the system to spawn (or not) in a certain area of the galaxy. There's also "max_instances = " to ensure that you don't get more than X instances of these systems. For example:
usage = misc_system_init
usage_odds = {
    base = 2000000
    modifier = {
        factor = 0
        is_bottleneck_system = yes
    }
}
max_instances = 1
  • "usage = empire_init" tells the game that this system is an empire homeworld, which either the player or the AI can end up with if they choose "Random" in the empire creation screen. If you use this, make sure the system has a planet with the following:
planet = {
    home_planet = yes
    init_effect = {
        generate_empire_home_planet = yes			
        prevent_anomaly = yes
    }
}
  • "usage = custom_empire" is mostly the same as above, except it tells the game that this system is a prescripted empire homeworld which can be chosen in the empire creation screen, like Sol and Deneb. Make sure to give the system a name and description via localisation.
  • If no usage value is used, or if "usage_odds = 0", the system will never spawn in the galaxy unless specifically called to by an event or another external means.

General Advice[编辑 | 编辑源代码]

  • Remember when I said that using "class = pc_b_star" is just as good as "class = star" most of the time? That's true in unary systems, but it can lead to problems with planet and star names in binary or trinary systems. If you want to hard-code a specific star class regardless of the system class, use "class = star" and then add "init_effect = { change_pc = pc_b_star }" underneath.
  • The same as above goes for giving planets specific names. If you name the third planet in the system "Joe", the fourth planet will use "StarName III" in its place. You can get around this by using "init_effect = { set_name = "Joe" }" instead.
  • All planets, ships, etc. in a system will always be lit from the system's center regardless of the location of the star(s). The devs are working on a fix for this but until then we just have to live with it.
  • Asteroids and Ringworld sections don't have visible orbital lines by default, but if they're placed in the star's scope (such as in an S-type binary system) they will have lines, which looks kind of messy. Make sure you place them in the system scope whenever possible.
  • And speaking of Ringworlds, their individual segments always face the center of the system regardless of which star they orbit.
帝国 帝国思潮政府 • 国民理念 • 起源承诺议程传统 • 飞升天赋法令政策遗珍科技自定义帝国
人口 岗位派系
领袖 领袖领袖特质
物种 物种物种特质
行星 行星行星特征 • 轨道矿藏建筑 • 区划行星决议
星系 星系恒星基地巨型结构虫洞 • 星门地图
舰队 舰队舰船 • 部件
地面战 陆军轰炸姿态
外交 外交 • 联邦 • 星海共同体评价修正宣战理由 • 战争目标
事件 事件异常现象特殊项目考古遗址
游玩 游玩定义研究 • 经济游戏开局
动态修改 动态指令效果触发条件作用域修正变量AI
媒体/本地化 Maya 导出器图形肖像旗帜事件图片界面图标音乐本地化
Other 控制台命令存档编辑Steam 创意工坊模组制作教程