• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
Hi all! I’m Caligula, our resident scripting language magician. As someone who works with our scripting language - both using it and improving it - on a daily basis, I’m very happy to be able to show off some of the new stuff that modders (and us inhouse) will be able to use going forwards, once the upcoming patch hits.

I’ll begin with a rundown of the new features:
  • Espionage: modders can add new operations, much like arc sites
  • First Contact: script driven, so modders can change much of the system, but all first contact is now technically one long event chain, so overwriting could be an issue. Luckily we have a new effect, “fire_on_action”, which has been inserted into various places that should alleviate this
  • Become the Crisis: code features e.g. the interface are all activated by script. So in theory, one could overwrite the whole feature to be whatever sort of progression to a goal you happen to want to mod in.
  • Emperor/Custodian: feature designed by the most experienced Content Designer at PDS. Brought with it many collateral scripting improvements, such as far more flexibility with galcom resolutions and the ability to spawn federation / community fleets via script.

Now, it’ll be exciting to see what modders do with this, but there’s so much more that we’ve done since 2.8 hit, so...

General improvements and standardisations

It would be fair to say that the Stellaris scripting language has grown incrementally according to the game's needs. This is not unexpected - Stellaris itself has grown incrementally. But it has had the side effect that a lot of different people have contributed to it, and so inconsistencies between different implementations have arisen. On the user side, this would show itself in, for example, things which work in one place but do not work in other, equivalent places.

For the upcoming patch, we had time to take a holistic view of certain things and implement some general improvements and standardisations.

A quick win in this regard is what is known internally as "script lists". These are a code system which generates random/every/any/count_whatever_object from a single section of code - guaranteeing that the way that array is built is the same between them, i.e. any_owned_pop checks exactly the same pops as every_owned_pop would execute on. We have been using these for quite a while, but there were still some very old implementations for certain scopes that predated them. The result of this was in some cases confusion - for example, x_pop and x_planet did sometimes radically different things depending on whether you used every, random, any or count (e.g. working in different scopes, sometimes referring to all the objects in the game and sometimes all of those belonging to the current scope...). Disturbingly, it was found that any_ship referred to "any ship in the game" and was in fact used wrong 100% of the time in our scripts. Another result was that in some cases one of the versions (usually the "count" version) was simply missing.

With the next patch, nearly all of the pre-script list implementations have been removed and replaced with script lists. In some cases, the opportunity was taken to clarify what the script list did, e.g. the "planet" script list is now split between "galaxy_planet" and "system_planet". (This will break some mods, for which I am a bit sorry, but not very :D It was worth it, and the patch notes will give details on what changed. In most cases, a batch-replace will suffice. Also, because of script lists, a fair few count_x triggers have changed names to lose an "s" at the end, which is slightly regrettable from a grammatical point of view). Some have also had some functionalities expanded, e.g. owned_pop, owned_planet and system_within_border now all work in sector scope.

A further area singled out for improvement was references to scopes in effects and triggers, e.g. create_pop = { species = <whatever> }. It turned out that there were quite significant variations as to what <whatever> in that example could be, depending on the effect or trigger. In some cases, only the species was allowed; in others, perhaps species or leader or country or pop; in others, the same but not pops… In some cases, we even used something called “owner_main_species”, which worked in just those places (unlike “owner_species”, which was the same but worked everywhere…). Our solution was to go through each and every trigger and effect and enforce standardisation - with the same code functions used in each case - for any script call to a species, country, planet, leader, or solar system location. No more shall we be confused that something works in one place but not in another!

This also lets us make sure that errors are correctly (and usefully) logged each time a scripter gets one of these wrong. (N.B. for modders not in the know: the error log can be found in Documents/Paradox Interactive/Stellaris/logs/error.log). In a similar vein, error logging has generally been improved across the whole scripting language. A large number of error messages lacking essential information (e.g. file location) have been updated to include that - as guardian of our overnight testing error logs, I have gone on a personal crusade against useless error log messages. Furthermore, we have fixed a disturbing number of cases where something didn't work but didn't warn you - e.g. doing something wrong in a trigger so it is always false, or messing up an effect so it did nothing. I'm not going to promise that this will never happen anymore, but a concerted effort has been made to eliminate such cases. Modders should expect the error log to warn them of a lot more issues both during startup and during the campaign. This has also made us somewhat more effective in fixing script bugs, since many more are now caught in the aforementioned overnight tests.

Variables

Onto something a bit different. On Stellaris, inhouse scripters and modders alike have long looked with envy upon the capabilities of the newer PDS game engines, compared to our own ability to do maths in script. We did have variables, but their functionality has been a bit more limited than we may have desired. In fact, I’ve seen some of the ways that modders get around their limitations, which have been incredibly motivating to make such horrible scripts no longer be necessary!

In 2.8, the following was possible with variables:
  • You can check, set, add, subtract, divide or multiply variables against values, other variables on the same scope, or the same variable on other scopes
  • You can export various galaxy generation settings as variables
  • You can refer to variables in localisations, but if the variable’s value is 0, it will show as blank because the variable is cleared
  • Variables can be used as a parameter in a handful of places, such as the count in a “while” effect

Quite a lot of improvements have been made since then, and further ones are planned for the near future. In the upcoming patch:
  • You can also check, set, add, subtract, divide or multiply variables against different variables on other scopes
  • There are new effects to modulo (% operator), round up, round down and round to the closest full number
  • A new trigger check_variable_arithmetic checks the value of a variable if you’d perform some arithmetic to it in a certain way, e.g. multiply it by another value or variable (add, subtract, multiply, divide and modulo all work)
  • New effects to export various game values to variables have been added. These are: export_modifier_to_variable (check_modifier_value trigger also exists now), export_resource_stockpile_to_variable, export_resource_income_to_variable
  • add_modifier, add_resource, resource_stockpile_compare now have “mult” parameters where a variable is accepted. So you can scale resource costs and bonuses in effects by a variable now.
  • Variables are no longer cleared when they are 0, but instead when you use the clear_variable effect, so they can be reliably used in localisations.
  • Certain usages of variables now have error logging, in case you try and use one that hasn’t been set.

Additionally, we have started making it possible to use variables way more widely. The idea is that we want to change how simple numerical effects and triggers (i.e. ones which accept a number as the right hand side parameter and do not have any “{ }”) work:
  • Effects should allow you to use a variable, and should grab the number from that variable
  • Triggers should also let you use a variable, and should check themselves against the value of that variable
  • Triggers should by default also let you check them against another scope for which that trigger would work. So “num_pops > from” should check if the current object has more pops than “from” does
  • It should be possible to export the current value of a trigger to a variable via an effect, i.e. “export_trigger_value_to_variable = { trigger = num_pops variable = my_var }” => sets the my_var variable to the number of pops the current scope has.

Unfortunately, it only recently became possible for us to pursue these changes, and while the groundwork has been set for them, they are not yet fully implemented - finishing the Nemesis expansion and accompanying patch has rightly taken priority (the changes are not without danger: it’s a lot of lines of code that have to be modified for it). So consider this a preview for how it will look in the hopefully near future, and in the meantime, the fleet_power trigger already works in the way specified, and export_trigger_value_to_variable is in the patch, albeit working with only that trigger.

Button Effects

Inhouse, we made the UI by assigning a function to buttons in the source code. But there’s also support for interface buttons that you mod into the game. In previous versions, these did not take the scope of the object that they were attached to, so if you added a button to a planet, it would still execute the effect on your country rather than that planet. We have fixed that for a bunch of cases: they will now be able to deduce their interface's planet, fleet, ship, system, ambient object, megastructure, federation, archaeology site, first contact site, spy network or espionage operation. (Incidentally, debug console commands like “effect …” and “trigger …” now work in those same scopes)

Disclaimer: The way it works is a tad hacky and it may be possible to confuse it by opening multiple interfaces at once. I recommend checking “is_scope_type = planet/whatever” in the allow and/or effect sections of the button effect. But the signs are that it should work with no problem in most cases, which is better than none!

More nice things
  • In most places where you could previously use logical operators such as >, >=, =<, <, you can now use != for “is not equal” too.
  • Message types now have their own folder, so mods can add to them without overwriting the file (great for intermod compatibility, and also for modders being able to add QoL without overwriting each other)
  • Messages spawned by the create_message effect now support using loc commands such as [This.GetName] (where “This” is the specified target of the message).
  • Also, since we had to fix a large number of cases where there were references to the “Galactic Community” rather than the “Galactic Imperium”, [ ] locs now work in quite a variety of extra places.
  • The effects “add_victory_score = <number>” and “win = yes” now exist. I’m sure no one will misuse them.
  • Added new event types: leader_event, system_event, starbase_event, first_contact_event, and espionage_operation_event. Though mean time to happen does not work for any of them at the moment - fixing that wasn’t a priority, as it is generally better to avoid mean time to happen anyway.
  • Hardcoded juggernaut behaviour is now tied to a ship size being a starbase that is mobile, rather than the “juggernaut” key. I.e. mod-made juggernauts are now possible without crippling bugs
  • It’s now possible to hide a static modifier from the list of country modifiers
  • You can check the distance of objects within the same solar system now by adding “same_system = yes” to the distance trigger
  • There’s quite a lot of new on_actions, and you can make your own ones with fire_on_action effect
  • And a lot more.

Finally, I'll leave you with the new trigger docs (as of today), which are now found in their own file called trigger_docs.log, and which really speak for themselves. Also, don't forget Paradox Insider will premier this Saturday at 8 PM CET (7 PM UK, 2 PM ET, 11 AM PT) on http://twitch.tv/twitchgaming
 

Attachments

  • trigger_docs.log
    253,4 KB · Views: 0
Did you just start a separate thread with my post as the focus? Was so confused looking at the notifications.

But what you're suggesting has always been doable, it's just not done in vanilla. If you really want an example of how flexible the resource spawning system is in stellaris, look to a (quite long) old thread of mine here, https://forum.paradoxplaza.com/forum/threads/resources-a-retrospective.1425984/
where I walk through
  1. restoring cut resources based on planetary space deposits, planetary surface deposits and galactic clusters (as defined by the game)
  2. restoring stratified resources (where resources only spawn in certain parts of the galaxy - e.g. zro only in nebula gas clouds)
  3. (though I dont mention this in that thread) you can also hide resources from appearing before you meet certain pre-requisites (e.g. unlocking a tech or getting an AP) - this is how resources used to work and how it works in games like CIV (you don't know where Oil is... until you know what oil is). Currently you always know where a resource is in stellaris, you just cant exploit it without the relevant tech, nothing is hidden.
    • You could use this premise to make "hive only" resources, or psychic only resources that cant even be seen by non hive or non psychic empires. and many other weird things.
The problems with resource scarcity/overabundance are not linked to scripting problems, they're a fundamental game balance problem.
V2.2 collapsed like a dozen resources down into 3 strategic ones, which are also used for critical components (ship guns, and Tier 2+ research labs, T2+ building upkeep costs) making their demand inelastic - forcing you to mass produce them, nullifying their less-common nature.
For a moment I thought my speech was confused, as I am not a native English speaker.

The idea of working with the fleet is very interesting, I can't even think of the possibilities that this can generate, a more dynamic galaxy where ethics is important because it starts to impact where we end up investing everything, in the war.
 
Seeing Stellaris address tech debt is good news for FIXING stellaris all around. If you are one of the people whinging over bugs/broken systems all the time this is one of the dev diaries you should be cheering about.

Clearing techdebt is a huge thing for reducing other issues in a game this complex.
 
  • 8Like
  • 2
Reactions:
so long story short.
u have begone scripting witch will hopefully make the A.I. better??
but you've just started so it wont be done when the expansion comes out?
any thing that fixes the A.I. i would really love all the features are cool but if the A.I. cant handle them whats the point.
A.I. in this case being a prescripted narrative.
i hope this is the case
 
  • 1
  • 1
Reactions:
The modding changes look really nice.

I am hoping their are some changes to species archetype in there. Since when you create a new archetype from my experience with my mod it doesn't generate some modifers such as how lithiods have lithoid_pop_happiness, nor does it allow you to inherit from biological and use biological_pop_happiness., and many other modifers. Thus causing a whole bunch of issues with creating a new archetype, especially if as the mod developer that new pop category is considerd biological.
 
Did you just start a separate thread with my post as the focus? Was so confused looking at the notifications.

But what you're suggesting has always been doable, it's just not done in vanilla. If you really want an example of how flexible the resource spawning system is in stellaris, look to a (quite long) old thread of mine here, https://forum.paradoxplaza.com/forum/threads/resources-a-retrospective.1425984/
where I walk through
  1. restoring cut resources based on planetary space deposits, planetary surface deposits and galactic clusters (as defined by the game)
  2. restoring stratified resources (where resources only spawn in certain parts of the galaxy - e.g. zro only in nebula gas clouds)
  3. (though I dont mention this in that thread) you can also hide resources from appearing before you meet certain pre-requisites (e.g. unlocking a tech or getting an AP) - this is how resources used to work and how it works in games like CIV (you don't know where Oil is... until you know what oil is). Currently you always know where a resource is in stellaris, you just cant exploit it without the relevant tech, nothing is hidden.
    • You could use this premise to make "hive only" resources, or psychic only resources that cant even be seen by non hive or non psychic empires. and many other weird things.
The problems with resource scarcity/overabundance are not linked to scripting problems, they're a fundamental game balance problem.
V2.2 collapsed like a dozen resources down into 3 strategic ones, which are also used for critical components (ship guns, and Tier 2+ research labs, T2+ building upkeep costs) making their demand inelastic - forcing you to mass produce them, nullifying their less-common nature.
I just tested this (but with a hard-coded value as a stand in until 2.9) by copy-pasting the empire_limit block (and then possible_construction block) from the Titan to the Battleship. [steamapps\common\Stellaris\common\ship_sizes\00_ship_sizes.txt]

1615504782581.png

empire_limit = {
base = 1
max = 9999
naval_cap_div = 40
}
I use 40 as battleships have a fleet cap usage of 8, so if I want to restrict the fleet to 20%, 140/(5*8) = 140/40 = 3.5 = 4 battleship-sized ships permitted. However the "empire_limit" block seems to be rigid, you cant stick it in an IF statement or within potential_construction = {} without getting script errors.

With 2.9 / the ability to manipulate variables, it should be possible to emulate the empire_limit block but with more flexibility via the potential_construction block. I've quickly written up the below example (which is inserted in to a battleship ship_size potential_construction field

1615509090867.png


This itself probably wont work, as I cant check 2.9 errors, but the final example will likely end up being some scripted variation on this (or one that calls a separate scripted_effect to calculate this), making #BBs allowed for construction vary with ethos [or whatever other limit one desires], assuming I have understood @Caligula Caesar 's new export variables.
 
Last edited:
  • 6
  • 1Like
Reactions:
As an aspiring modder who literally can't make up his mind, and thus hasn't even gotten into scripting events and whatnot, all I still have to say, is: Yes please more moddability improvements, I would love more!

Even if I don't know yet how to use 'em, it means eventually I have more options when I do, and I don't even need to mention how better modders will just go nuts with said options.
 
Last edited:
A quick win in this regard is what is known internally as "script lists". These are a code system which generates random/every/any/count_whatever_object from a single section of code - guaranteeing that the way that array is built is the same between them, i.e. any_owned_pop checks exactly the same pops as every_owned_pop would execute on. We have been using these for quite a while, but there were still some very old implementations for certain scopes that predated them. (...)

With the next patch, nearly all of the pre-script list implementations have been removed and replaced with script lists.
YESSSSS. It's about time these relics got replaced. This is going to be fun!!
 
Don't think I'll play this game again until we see the end result of the population changes that were proposed months ago. I am liking what I've been seeing though. If I am understanding the changes correctly, will we finally be able to make functional planet/sector automation? Previously, you couldn't project resource production/costs from queued buildings. I don't even think you had access to variables at some parts to even start attempting at doing it.

I really like this game, but it's not really playable for me until the micro hell is removed. Improvements like these to the modding capabilities are a step in that direction.
 
  • 2
  • 1
Reactions:
Don't think I'll play this game again until we see the end result of the population changes that were proposed months ago. I am liking what I've been seeing though. If I am understanding the changes correctly, will we finally be able to make functional planet/sector automation? Previously, you couldn't project resource production/costs from queued buildings. I don't even think you had access to variables at some parts to even start attempting at doing it.

I really like this game, but it's not really playable for me until the micro hell is removed. Improvements like these to the modding capabilities are a step in that direction.
I haven't touched Stellaris since they announced the building slot and population changes. Come on PDX, let me kill the galaxy already!!
 
  • 2Like
Reactions:
These are very interesting changes, thanks a lot!
Could you elaborate on fire_on_action a little bit more?

Does this allow for arbitary scripted on actions like CK3s scripted on_actions?
Sure! Basically, an on_action coded in as a string with various events and random events attached. The effect lets you fire one of the existing ones (if you really want to try and break things :p ), or alternatively a new one you have invented. You can choose not to specify scopes in it, in which case it will behave like the effects to fire events (root becomes from, etc). Alternatively, like the fire event effects, you can also overwrite scopes via "scopes = { from = event_target:my_target }"

The benefits of this effect over, say, a standard random list are:
- Mod compatibility (I expect modders to ping me asking for the effect to be inserted in certain places we haven't thought of, after release)
- The random_events field checks the trigger for an event before adding it to the list of events that can fire. So you can have a list of 8 events with a 1/8 chance each, if only one of those is able to fire because of the triggers, that one will always fire. I.e. it's like a random list where you pasted all the triggers for the events in "modifier = { factor = 0 }" boxes, but it's way less verbose you don't need to update it in case an event's triggers are ever changed.

Will these script changes positively affect performance?
Having better ways of doing things in script means that we can make scripts that are more efficient, which in turn means better performance for doing the same thing. Depends somewhat on how much we are able to update old scripts (a gargantuan task), and it is always hard to evaluate how much effect a change of script has on performance (say you have changed something checked every day to take 1/3 of the time to evaluate - that's going to have an effect, but when we are talking about microseconds, it is hard to see it, and since the game is always getting bigger in terms of content, someone will swiftly add something else to take that performance improvement - but it's still more efficient!).

What we found, though, is that the single best way to improve performance is to drastically reduce the number of pops, to be honest.

Yes, this happens when a mod uses triggers from other mods, if one of the mods is not present, the trigger won't exist, and should return false. Instead, it is always true.
We have to sanitize the code to also check for a global flag to be sure the other mod is present, but if one mod doesn't have a global flag set at startup, were're basically stuck with an unusable trigger. This would improve compatibility a lot.
I'll add it to my list of things to do. No promises for when I get round to it, though.

Is there anything equivalent to the trigger doc here for modifiers? It would be nice to have a consolidated list for modding civics/origins. I've seen one on the wiki but it doesn't seem to be maintained through 2.8.3.
You can get them from setup.log. It's not ideal, we plan to separate it into a modifiers.log, when we get the chance.

Ah, thanks for the write up there. I'm a very novice level coder though so I'm not exactly sure what the differences therein entail.

New version is:
Code:
any_owned_species - Check if any of the species <on the planet/in the country> meet the specified criteria - checks whether the enclosed triggers return true for any of them
any_owned_species = { <count=<num/all>> <triggers> }
Supported Scopes: planet country

Old version is:
Code:
any_owned_species - Check if any of the species <on the planet/in the country> meet the specified criteria
any_owned_species = { <triggers> }
any_owned_species - Check if any of the species <on the planet/in the country> meet the specified criteria - checks whether the enclosed triggers return true for any of them
any_owned_species = { <count=<num/all>> <triggers> }
Supported Scopes: planet country
Supported Targets: THIS ROOT PREV FROM OWNER CONTROLLER CAPITAL SOLAR_SYSTEM LEADER RANDOM FROMFROM PREVPREV PREVPREVPREV PREVPREVPREVPREV

Are you able to summarize the difference here for me?
No change (unless the code behind the functions it draws upon has changed - I'm a bit unsure there). I just did a batch-clarification of the documentation on all any/every/random/count triggers and effects.

Check out Imperial Routine mod, especially beta branch on GitLab by Iyur (IRM).
Tbh seeing Iyur's mod single-handedly persuaded me to add some extra things for sectors so you can manipulate them in script a bit better.

...what? No it wasn't?
Indeed not. In fact, it should work way better than in 2.8.3, now.
 
  • 9
  • 4Like
Reactions:
This may be the best time to ask this random question.
x_owned_planet, does that check all planets in your borders, or only all colonized planets in your borders?
All colonised planets that belong to you.
 
  • 4
  • 3Like
Reactions:
There’s quite a lot of new on_actions, and you can make your own ones with fire_on_action effect
Could we see a list of the new on actions? :p

Sure! Basically, an on_action coded in as a string with various events and random events attached. The effect lets you fire one of the existing ones (if you really want to try and break things :p ), or alternatively a new one you have invented. You can choose not to specify scopes in it, in which case it will behave like the effects to fire events (root becomes from, etc). Alternatively, like the fire event effects, you can also overwrite scopes via "scopes = { from = event_target:my_target }"

The benefits of this effect over, say, a standard random list are:
- Mod compatibility (I expect modders to ping me asking for the effect to be inserted in certain places we haven't thought of, after release)
- The random_events field checks the trigger for an event before adding it to the list of events that can fire. So you can have a list of 8 events with a 1/8 chance each, if only one of those is able to fire because of the triggers, that one will always fire. I.e. it's like a random list where you pasted all the triggers for the events in "modifier = { factor = 0 }" boxes, but it's way less verbose you don't need to update it in case an event's triggers are ever changed.
so this would not work?

fire_on_action = { on_action = on_ship_damaged_victim scopes = { from = ship fromfrom = ship } }

I do not understand how this would work if the code does not know to use it when a ship is damaged?based on this one

# This = owner of ship 1 (destroyed)
# From = owner of ship 2 (combatant)
# FromFrom = ship 1
# FromFromFrom = ship 2
on_ship_destroyed_victim = {}

or is fire_on_action more like :

random list = { list of events = { } force-scope FROM and FROMFROM for the list of events }
 
  • 2
Reactions:
I will ask again:

Can we please have some more documentation? Chances are it's been laying around in your workstations for years.
It would be great if you could add some organization to it and release it as a unit - or create/update the relevant sections in the wiki.

(for the love, I know there was an attchament in the OP....)
 
  • 4
  • 2
Reactions:
Become the Crisis: code features e.g. the interface are all activated by script. So in theory, one could overwrite the whole feature to be whatever sort of progression to a goal you happen to want to mod in.
  • Emperor/Custodian: feature designed by the most experienced Content Designer at PDS. Brought with it many collateral scripting improvements, such as far more flexibility with galcom resolutions and the ability to spawn federation / community fleets via script.

Do these mean that it would be possible to create a mod that would replace the "galactic empire goes super evil, builds doomsday device of evil" plot with a "galaxy unites under an emperor to face a greater threat that requires a massive device / effort to stop" plot? I'm thinking particularly something along the lines of defeating Boskone / the Eddorians from E.E. "Doc" Smith's Lensman universe; which required both a literally galactic-scale psychic effort combined with the use of serious gigaweapons (in modern terms, a pair of antimatter planets moving at 15c on opposed courses that are dimensionally phased in on either side of the target planet). A somewhat lesser but more modern example might be the effort to defeat the Achuultani from the David Weber's Mutineers' Moon / Armageddon Inheritance universe, which required multiple epic battles (including a complicated trap involving dozens of "planetoid" ships (Juggernaut + scale) and then triggering the system's sun to nova, which wipes out over a million attacking ships, nearly half of the invasion fleet.)

I'm aware that at some level, the "Guardian" role starts that process, but it's lacking both the element of "we have to unite more firmly under a single leader with a fanatic focus to defeat the foe" and the particularly interesting element of "we have to build (in stages) a giga-widget of unprecedented power"; both of these are classic epic SF tropes that shouldn't be limited to "the bad guys".
 
  • 3Like
Reactions:
u have begone scripting witch will hopefully make the A.I. better??
The tl;dr is:
  • bugs will be easier to track down
  • mods will have more tools to do cool new things with, and those tools will make more sense
  • cool new user interfaces to do cool new things will be easier to write and less likely to summon demons from your nose
The direct impact of this on the AI's competence and behaviour will be quite limited.
 
  • 4
  • 2Like
Reactions:
Question personally related to one of my little mods; have there been any updates to the “any_owned_species” function? I have a mod that adds a new faction and the checks all broke when I switched any_owned_species in for any_owned_pop.
Yes, I investigated and fixed that today.
 
  • 8Like
  • 2
  • 1Love
Reactions:
Could we see a list of the new on actions? :p


so this would not work?

fire_on_action = { on_action = on_ship_damaged_victim scopes = { from = ship fromfrom = ship } }

I do not understand how this would work if the code does not know to use it when a ship is damaged?based on this one



or is fire_on_action more like :

random list = { list of events = { } force-scope FROM and FROMFROM for the list of events }
The first version you said would work. Assuming the ships are valid targets. But of course, that on_action is fired from code, I don't see why or how you'd try and fire it from script.
 
  • 3Like
  • 2
Reactions: