1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

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

Discussion in 'Rhye's and Fall Modmods' started by Baldyr, May 16, 2010.

  1. killerkebab

    killerkebab Prince

    Joined:
    Jun 25, 2009
    Messages:
    571
    Can I load the game I had going previously and check for less lag, or does it not work that way? :)
     
  2. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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.
     
  3. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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:
     
  4. Bonci

    Bonci King

    Joined:
    Oct 22, 2005
    Messages:
    740
    Location:
    Tridentum - Italia
    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?
     
  5. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Oh, good! :goodjob:

    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.)
     
  6. Bonci

    Bonci King

    Joined:
    Oct 22, 2005
    Messages:
    740
    Location:
    Tridentum - Italia
    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)
     
  7. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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

    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?
     
  8. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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?
     
  9. Bonci

    Bonci King

    Joined:
    Oct 22, 2005
    Messages:
    740
    Location:
    Tridentum - Italia
    ummm but by doing so depending on how i set trigger the player could lose or acquire a city for free...

    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 °_°)
     
  10. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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:
     
  11. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    This is something I've tried to avoid from the get-go; the flip() Action actually has built-in conditions:
    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.

    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:
     
  12. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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:
     
  13. Bonci

    Bonci King

    Joined:
    Oct 22, 2005
    Messages:
    740
    Location:
    Tridentum - Italia
    great! :D

    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)
     
  14. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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)
     
  15. Bonci

    Bonci King

    Joined:
    Oct 22, 2005
    Messages:
    740
    Location:
    Tridentum - Italia
    yep i read the documentation (at least the api) now i'm trying to add some realism to the roman game :)

    i think that it could be useful to have some way to know if two civilization have met or not...
     
  16. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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:
     
  17. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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
     
  18. killerkebab

    killerkebab Prince

    Joined:
    Jun 25, 2009
    Messages:
    571
    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?
     
  19. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    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:
     
  20. killerkebab

    killerkebab Prince

    Joined:
    Jun 25, 2009
    Messages:
    571
    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 :)
     

Share This Page