Introducing: PyScenario - easy-to-use scenario event scripting for RFC

Can I load the game I had going previously and check for less lag, or does it not work that way? :)
 
Can I load the game I had going previously and check for less lag, or does it not work that way? :)
No, you can't. The Triggers aren't saved together with the RFC stuff anymore, but in another place (actually in a tile object :eek:). This prevents constant pickling and storing of large amounts of data, which takes time.

Please post/send any further games with lag issues and I will try to time what actually causes it.
 
I have some time set aside for coding new content this weekend, so I was wondering if anyone has any specific request?

The methods on my drawing board right now are:

treaty() - for setting war/peace, with options for open borders and vassals
collapse() - for forcing a Civ out of business, with some optional results
degrade() - for making a tile more arid, with options to spare resources (could be used to simulate desertification over whole map ares)
kill() - for razing cities and/or killing units
gold() - for adding/subtracting gold

Or, I might just get down and dirty with the long-promised in-game messages (and pop-ups). :king:

But if there are actual requests I will do my best to whip something up. :goodjob:
 
I'm trying to rename "Roma" in "Romola" (only an experiment :p) what am I doing wrong?

Code:
Trigger().turn(97,120).name("Romola","Roma").once()

i get different errors every turn (the city renames correctly btw)

EDIT: oh now it works...i just started another game...so i can't test and modify the triggers while playing like with pyton?
 
EDIT: oh now it works...i just started another game...
Oh, good! :goodjob:

so i can't test and modify the triggers while playing like with pyton?
3.8 Reloading Triggers

Any time a Python module associated with the mod is saved during gameplay, then all the Python modules will be reloaded. (You will probably be editing your Scenario module while the game is running.) When this happens all the Triggers that were loaded on initialization are instantly lost!

To reload all Triggers you need to use the shortkey shift + alt + R. But this will only work if the Scenario module really has been re-saved! (Otherwise reloading will erase the Triggers from the memory... Save the module and reload the Triggers once again.)
The technical explanation is that when the Python automatically reloads (and I mean all of it) then all "objects" are also created again. This means that all old objects expire - and this also affects the PyScenario object holding the list of Trigger objects, containing Condition and Action objects, and so on.

PyScenario only reads the Scenario module (your script) on initialization, but this process can be initiated on command by using the hotkey mentioned above. (This is also documented in the script template itself...)

(I plan on buildng the Alpha version of PyScenario around the BUG mod and then it will be possible to automatically rebuild Triggers when the Python modules are reloaded.)
 
oh sorry i missed this part *_*

I have another question: is it possible to trigger an event only if more than one specific civilization is not human? (example: I want to spawn some units only if Rome and Greece are not human)

umm and it would be cool if one event could be triggered only if two civilizations are at war (or in peace)
 
I have another question: is it possible to trigger an event only if more than one specific civilization is not human? (example: I want to spawn some units only if Rome and Greece are not human)
No, not with the current setup. I do however intend to build in support for using the PyScenario classes (mainly Conditions and Actions) in regular Python programming. So instead of learning how make iteration happen and how to decipher the CivIV Python API, there would be another procedure to follow. But it would be actual Python programming - with some useful tools.

In your case, since the human player wouldn't be likely to see any of the spawned units - could it be sufficient to simply flip the Greek city to the Romans (if this is what the purpose would be)? It is a more deterministic route but PyScenario is pretty much about scripting history. :p

oh and it would be cool if one event could be triggered only if two civilizations are at war (or in peace)
This exact thing is something I intend to work on tonight! :goodjob: (As I already did the new Actions mentioned in a post above.:king:)

So the new Conditions will most likely be war() and faith(). The first one can be used to trigger events based on war/peace, and the second one conditions the target player to have a specific state religion.

What other Conditions and Actions would seem useful to you? Perhaps something that has to do with Civics?
 
Just a quick question: I'm making the war() Condition and it dawned on me that the target player and the rival Civ might not have met at the time when the Condition is checked... Should such a situation count as a positive or a negative outcome? (Should the Condition be considered to be met if the two sides haven't made contact yet?)

Any opinions, thoughts?
 
In your case, since the human player wouldn't be likely to see any of the spawned units - could it be sufficient to simply flip the Greek city to the Romans (if this is what the purpose would be)?
ummm but by doing so depending on how i set trigger the player could lose or acquire a city for free...

Should such a situation count as a positive or a negative outcome?
I think that they should be counted as in peace (for the case that they already met once and they lost contact i don't know °_°)
 
I have another question: is it possible to trigger an event only if more than one specific civilization is not human? (example: I want to spawn some units only if Rome and Greece are not human)
Ok, next up is a feature that can be used to tie together Triggers into larger events.

The principle is that there will be a Action that can set "flags" (a string - any combination of letters) that are recognized by the entire script. So in your example, the first Trigger could check whether or not the Greeks are human. If they are not, then the "AI Greece" flag is set.

The next Trigger both checks if the Romans are human - and looks for the string "AI Greece" among the scenario flags. If the Romans are AI and the requested flag is found, then the unit spawning Action is Triggered.

All this could of course be part of a larger cluster of Triggers making up one single historical event.

Right now I have to figure out what to call the Action that sets the flag - and what to call the Condition that looks for it. (Well "flag()" comes to mind... what about the other one?)

---

Or I might do something else completely. :rolleyes: Like give all Triggers names (optional) and then have a Condition that looks up if the Trigger by that name has fired. That might actually be better... I think I'll have to think about this more. :p

---

The new Conditions and Actions are done, by the way. :king: The next update is still days away so there is still time for more requests. :goodjob:
 
ummm but by doing so depending on how i set trigger the player could lose or acquire a city for free...
This is something I've tried to avoid from the get-go; the flip() Action actually has built-in conditions:
flip( name=None, eOwner=None, bMinorsOnly=True, bAIOnly=True, bSafe=True )

(...)

Only cities belonging to Minor Civs and controlled by the AI are, by default, subject to city flipping. These settings (bMinorsOnly and bAIOnly, respectively) can however be altered.
So what you do is:
Code:
flip(bMinorsOnly=False)
Which of course would be the same as:
Code:
flip(bMinorsOnly=False,bAIOnly=True)
Spoiler :
Because bAIOnly uses the default value.

I think that they should be counted as in peace (for the case that they already met once and they lost contact i don't know °_°)
But why would you wanna know if, say, the Spanish are at peace with the Aztecs - if they haven't met? What Actions would you use in such a Trigger with that Condition?

I just don't know, myself... The final verdict will however be whatever is most useful - in actual testing. So, basically you decide. :king:
 
Ok, this is what I finally came up with:

From the next update it will be possible to label individual Triggers with the label() method (neither a Condition nor a Action). This string value is stored with the Trigger object itself and can be used for debugging - or in the future - as part of a graphical interface (development tool) where you get to describe your Triggers in words for easy identification.

But there is another feature built into this; The new flag() Condition checks if a specific Trigger has fired (and thus cleared all of its Conditions). This isn't really done by looking up a Trigger with the matching description - it has actually already been done at initialization (as Trigger descriptions never change) and thus the second Trigger instance stores a reference to the first Trigger as a field attribute. But the specifications of this would hardly concern the user. :D

To summarize, this means that it will be possible, with the next update, to bind together Triggers by giving them labels and checking whether or not those Triggers have fired. This way one Trigger firing can allow another - or several others - to fire, and so on. (There can be long chains of these bindings.)

This should go some way to open up the limitations that are built into the application. :king:
 
great! :D

But why would you wanna know if, say, the Spanish are at peace with the Aztecs - if they haven't met? What Actions would you use in such a Trigger with that Condition?

Don't know...maybe there should be a third ouput that means that they have not met? (so the trigger would fail when controlling both if they are at war and if they are not)
 
Don't know...maybe there should be a third ouput that means that they have not met? (so it would fail when controlling both if they are at war and if they are not)
Yeah, this is actually how it works now. :goodjob:

You set a boolean argument to either war or peace, and depending on this and the actual diplomatic state the Condition may pass - or not. But there is, as you describe it, a third option if the Civs haven't met. They are technically "at peace" (well, actually "not at war") but the Condition isn't met whatever the settings - as there is no diplomatic relationship. This prevents the Trigger (which might only fire once) from firing before the protagonist has met the antagonist, so to speak. :D

But it could be turned the other way around if need be. (Then the Condition would always pass if there is no contact.) Actually, this could be a setting in itself - whether or not the Condition should pass with no contact. What do you think? (Arguments with default settings hardly make it more cumbersome to use the method, but it does clutter up the API entry with additional information.)

Bonci, did you ever get through all the documentation or are you learning by doing? :D I'm not saying that its a bad way to get into this, but it would probably help to use the API and the tutorial as a reference. (I actually need to look up methods either in the API or in the source code myself before trying to use any. Because this application is getting somewhat large now... :p)
 
yep i read the documentation (at least the api) now i'm trying to add some realism to the roman game :)

But it could be turned the other way around if need be. (Then the Condition would always pass if there is no contact.) Actually, this could be a setting in itself - whether or not the Condition should pass with no contact. What do you think? (Arguments with default settings hardly make it more cumbersome to use the method, but it does clutter up the API entry with additional information.)

i think that it could be useful to have some way to know if two civilization have met or not...
 
i think that it could be useful to have some way to know if two civilization have met or not...
You mean like a contact() Condition or the like? It isn't sufficient to use the war() method and set it to look for a peace treaty (as described above)? Because if the two sides haven't met, then the Conditions isn't met either.

Other than that, I'm actually building in a check for contact in other methods, like the new treaty() method. (You can't make war/peace or open borders with Civs that you haven't met. The same with the new vassalize() Action.) So a contact() method might not be entirely necessary...

But if you find a real need for it, then sure. :king:

Good luck with those pesky Romans! (With the next update it isn't just possible to flip Carthage on a given turn, but also have it autorazed with the kill() Action. And there is a way to sow salt in the ruins with the degrade() Action. :D) I'm looking forward to seeing the fruits of you efforts! :goodjob:
 
From the next update it will be possible to label individual Triggers with the label() method (...)

The new flag() Condition checks if a specific Trigger has fired (and thus cleared all of its Conditions). (...)

...this means that it will be possible (...) to bind together Triggers by giving them labels and checking whether or not those Triggers have fired.
Not quite. I've renamed the flag() Condition triggers() and it can now be used to check whether or not several (actually any number of) Triggers have fired, making this feature somewhat more powerful. :goodjob:

The flag() method will instead become a add-on to the units() Action, used to give spawned units special "call signs". This makes them "flags" and the script can detect if one has been destroyed by utilizing the captured() Condition.

I'm not sure if this will be in the next update or not, but the idea is that you can have units (like historical figures) be scenario flags that in turn can trigger other events. Like when a King unit has been slayed it can either reappear (another spawn) in the capitol or the capturer could collect a ransom in gold. :king: (Or whatever.)

Well, this is the theory, at least. :p
 
Sorry if you've said already, but my memory is drawing a blank - is it possible to set triggers to fire only if a civ is human?
 
Sorry if you've said already, but my memory is drawing a blank - is it possible to set triggers to fire only if a civ is human?
No, I actually don't think so... I think I've only been restricting the human player as I, as a rule of thumb, don't think he should get any spawns or the like. But if you can think of a use for a human-only Condition then, sure. :D

Lets see... The check() Condition has a argument bHuman that is set to False by default, meaning that the human player isn't allowed. If set to True, then also the Human player is allowed. (Then it works just as if the check() method was omitted - no check is performed.)

What if the True value would only allow for the human player, then? Because a None value could well be the no-check argument. (Such a thing is actually necessary because there is another setting also...) If no one can see any immediate drawbacks of such a setup it will be implemented in the next update. :king:

Bonci's proposed contact() Condition will also make an appearance. :goodjob:
 
The reason I wanted it is because I've given free cities to silly AI civs such as Japan who settle 7 cities on Honshu (for no reason).

This is great for the AI, but if a human player picks Japan, the cities don't spawn (which is fine) but the human player has no free settlers (unlike in normal RFC). So I wanted a trigger that would only fire if Japan is a human civ, to spawn 1 settler (or however many until we have the same number of settlers as you get in a non-modded game) on the starting plot on turn 1.

Same for Arabia, same for Vikings, same for China :)
 
Top Bottom