Stellaris

Stellaris

Modify the Galaxy
Modify your Stellaris experience by checking out the many mods created and shared by the community, including tweaks to almost any aspect of the game.
Learn More
Randomly Switching Empires
I've been working on kind of an elaborate setup, with predesigned empires populated around the galaxy. For debugging reasons, I wrote myself a little bit of code that lets me swap into a specific empire whenever I fire up the game to test my work. I've tweaked it a little bit, to bring up a random existing empire. I think it's a neat little bit of code and I think sharing it might help someone else with an "aha" about an easy way to handle scoping.

So, in "common\on_actions\00_on_actions.txt" I added the following little instruction to execute my event in the "on_game_start_country" area.
on_game_start_country = { events = { sandbox.1 game_start.33 # populate system with stations clones.2 # Clone Army Origin [... etc etc ...] } }

Then, in the "events" folder, I have "sandbox_events.txt". This currently does three little things to simplify my debugging/playtesting. First, it iterates through all the countries and establishes communications between them, because after a while you get sick of getting spammed with first contact. The, it goes back through and cleans up the tag I use to stop countries from trying to establish communications with themselves.

Then it looks for the every playable country that isn't AI (which in this case is only me). Then it grabs any random country that is played by the AI but is of a "default" country type - this way it won't select the tiyanki or marauders or other unusual empires. Then from inside the randomly selected country it says, "hey set the player of that last country I was looking at (event_target:original_human) to be the player of this country."

namespace = sandbox country_event = { id = sandbox.1 hide_window = yes is_triggered_only = yes fire_only_once = yes trigger = { is_ai = yes } immediate = { every_playable_country = { limit = { is_ai = yes } set_country_flag = SELF every_playable_country = { limit = { NOT = { has_country_flag = SELF } } establish_communications_no_message = PREV } } every_playable_country = { limit = { has_country_flag = SELF } remove_country_flag = SELF } every_playable_country = { limit = { is_ai = no } save_global_event_target_as = original_human random_playable_country = { limit = { is_ai = yes is_country_type = default } set_player = event_target:original_human } } } }

It's kind of an idiosyncratic way of working with objects in code, but once you get a handle on it, a lot more becomes possible. From any place where an effect can be called, you can scope anything using either "every_[insert whatever category]" with "limit = { [conditions ] ". Then inside that scope you can scope a second item the same way, and use flags or event targets to execute a function back on the level above.

To show another example of the same principle in action... I have a "root_initializer" that contains one system, which in turn has an "init_effect" call. Inside that call, I define every species I'm going to invoke in the game setup. Then I use neighbor_system calls to downstream initializers to set up their local circumstances. That guarantees control over the flow, so the species define comes before the creation of their homesystem. So downstream, when I initialize the system, I can flag another world in its own init_effect as the species homeworld.

So... root_initializers.txt has a lot of code that looks like this:
create_species = { name = "Panspermian" class = "MAM" namelist = NECROID1 portrait = random traits = { ideal_planet_class = pc_habitat trait = trait_psionic trait = random_traits } effect = { save_global_event_target_as = panspermia_species } }

Now in this case, these guys are a disposable species who I'll erase with another event shortly after the game starts. But I have a whole stack of species that I create up front and I use global event targets to call back to hem later in the initializers.

Then "somewhere in the galaxy" there's a Sol, where Earth is defined. In this case, Earth is the homeworld to humans, but also to genetically engineered replicant clones and renegade servitors who have separate independent empires nearby. So by having initialized all three species up in the initializer that called Sol, I can assign the same homeworld to all three species.

planet = { name = "Terra" class = "pc_continental" orbit_distance = 25 orbit_angle = 120 size = 20 starting_planet = yes has_ring = no entity = "continental_planet_earth_entity" deposit_blockers = none modifiers = none flags = { planet_earth } init_effect = { save_global_event_target_as = sol_system_earth save_global_event_target_as = human_homeworld prevent_anomaly = yes event_target:human_species = { set_species_homeworld = event_target:human_homeworld } event_target:mechan_species = { set_species_homeworld = event_target:human_homeworld } event_target:replicant_species = { set_species_homeworld = event_target:human_homeworld } set_owner = event_target:human_country add_building = building_system_capital create_pop = { species = event_target:human_species } } moon = { name = "Luna" class = "pc_barren_cold" size = 5 orbit_distance = 15 orbit_angle = 40 has_ring = no entity = "cold_barren_planet_luna_entity" } }

You can throw your systems out from the root initializer at any arbitrary distance by putting the following in at the system level of the root initializer:
neighbor_system = { ###Inner Ring Alpha 01 = Sol hyperlane_jumps = { min = 1 max = 40 } initializer = sol_system_initializer }

Generally I've been working on an elliptical galaxy with hyperlanes set to full, so any place is within about 40 systems to any other place in my galaxy. For windier and weirder setups, you'd just up the maximum number of jumps you're willing to throw it. And then if you wanted to keep your replicants and mechans closer to Sol, use a "neighbor" system call from Sol with a much lower max jump limit.... I generally use 9 to guarantee someone falls near the core of an adjacent sector - close but not too close.

Anyways, I just thought I'd take a stab at explaining what I've learned, both to help clarify my understanding for myself and on the off chance that someone here looking to get their mods working might find it a bit clearer or more helpful than some of the other content out there.
Last edited by Geoff; 16 Jan @ 8:33pm