Events system brainstorm

Okay great, I admit I haven't grasped the full picture you're working on all at once. Anyway sounds very encouraging.

I haven't had much time to do anything related to events outside of the yet-to-publish treesuccesion/forest fire hook. Have you done anything with the wandering nomads event? The one that occurs regularly early game and either gives military or population or culture or barbarians? (Never really understood the last choice)

As I may have mentioned earlier in this thread or another, I've theorycrafted out a plan for that one to bounce a series of decisions back forth between two players, when the event triggers in a border region. If you've taken another direction though on that one specifically, I'll probably focus on something else.
 
Okay great, I admit I haven't grasped the full picture you're working on all at once. Anyway sounds very encouraging.

I haven't had much time to do anything related to events outside of the yet-to-publish treesuccesion/forest fire hook. Have you done anything with the wandering nomads event? The one that occurs regularly early game and either gives military or population or culture or barbarians? (Never really understood the last choice)
Yes. It is one of several events (5 so far) with multiple ways to fire. I mostly used your ideas so there are three different versions that offer some arrangement of six choices (border growth, gold, free military unit, chance of free citizen*, free culture, and free worker). When the event fires, you'll see three of these choices. The next time, you might see other choices or a combination of some of these and some new ones, etc.

* The chance of a free citizen is to help balance it by lowering the value of that choice slightly.

Others events have a similar feel (the wanderer event no longer offers free GP points for the same four types of GP but expands to six types (i.e. choices) with three different versions with some mix of the six choices. Other events give different choices based on whether the city is coastal or not or different choices depending on the tech you have reached, etc.

And I intentionally set it up so that it doesn't just disable the choices that are not valid, but that you get an actual event that is unique to that situation. If the choice isn't available to non-coastal cities, you are not going to see that event fire for a non-coastal city. You get a different variant with choices that are valid.

As I may have mentioned earlier in this thread or another, I've theorycrafted out a plan for that one to bounce a series of decisions back forth between two players, when the event triggers in a border region. If you've taken another direction though on that one specifically, I'll probably focus on something else.
I like the idea, and it would be possible to make events that fire based on other players. I haven't hashed out any particular ideas for specific events yet. I actually would want to make this a full EP so it could be fully fleshed out and turned on/off as a player preferred.

How to make it trigger for only neighbors, I 'm not sure how I could do that. It might be possible, but I'll have to dig into some of the lua triggers to see what I can figure out (and then ask a lot of questions from others).
 
How to make it trigger for only neighbors, I 'm not sure how I could do that. It might be possible, but I'll have to dig into some of the lua triggers to see what I can figure out (and then ask a lot of questions from others).
When it's a city event, plan is to use Lua to loop through all plots within x tiles of the event city, check each one for foreign ownership. Can find the neighbor player that way. Maybe there is a more efficient way? Probably just need to loop through one outer ring surrounding the city, 3 or 4 plots out. Resource use may not be entirely trivial but that should work, and this will just be an occasional event anyway.

I'm a little hazy on whether it will be possible to modify event outcome based on this finding -- ie if there's a neighbor, will want to move into the 2-player version of this event, vs if there's no neighbor just proceed with one player version. I think it's just a matter of structuring the database entities appropriately but I haven't done much of this yet, need to explore what's possible in this sense

I'll pick something unique whenever I get to this, make my own new event, leave the existing ones to your overhaul. Hope is to create some kind of template that can be built out further by others for 2 player events. If you get to this stuff before I do, please keep us updated, I may just work off whatever you've started

Another thought related to all this -- how does AI decide on the best choice for an event? Do they see the possible outcomes and yields directly, or is there some other evaluation taking place? My initial thought was to create some kind of prisoners dilemma situation, but if the second player in the decision chain can just see the available outcomes directly, will have to rethink how this might work...
 
Last edited:
When it's a city event, plan is to use Lua to loop through all plots within x tiles of the event city, check each one for foreign ownership. Can find the neighbor player that way. Maybe there is a more efficient way? Probably just need to loop through one outer ring surrounding the city, 3 or 4 plots out. Resource use may not be entirely trivial but that should work, and this will just be an occasional event anyway.

I'm a little hazy on whether it will be possible to modify event outcome based on this finding -- ie if there's a neighbor, will want to move into the 2-player version of this event, vs if there's no neighbor just proceed with one player version. I think it's just a matter of structuring the database entities appropriately but I haven't done much of this yet, need to explore what's possible in this sense
Sounds like it could work. You might have to set simultaneous events so you could set a "neighbor" flag similar to how I'm setting "NoCoast" and "NoRiver" tags. Then you would have the second event trigger base on which flag the city had. I finally figured out (with help on here) how to put my flag events in LUA so they could be silent (i.e. no notifications) then I made the second event a standard event. Thinking it through, I'd have it force the flag event every time a city settled (or conquered) but it would need to run it for all cities on the map. It might still need to be a world event (one that hits all players) but the world event could be structured around the flags in each city.
I'll pick something unique whenever I get to this, make my own new event, leave the existing ones to your overhaul. Hope is to create some kind of template that can be built out further by others for 2 player events. If you get to this stuff before I do, please keep us updated, I may just work off whatever you've started
As I said, I like the idea and if you could develop a series of events, we could make it an EP. Ultimately, I'd like to have multiple people working on various EPs with general parameters for balance, avoiding yield bloat, etc. so we could have lots and lots more events in a number of thematic categories.
Another thought related to all this -- how does AI decide on the best choice for an event? Do they see the possible outcomes and yields directly, or is there some other evaluation taking place? My initial thought was to create some kind of prisoners dilemma situation, but if the second player in the decision chain can just see the available outcomes directly, will have to rethink how this might work...
You assign flavor values to each choice, and the AI leader picks the choice that most fits with the flavor value and what they are weighted to consider. There are 38 flavors ranging from yields to expansion to espionage to both military offense and defense. If you haven't assigned flavors, it's random selection.
 
Last edited:
With the baths event, even though "creative methods" is probably the meta pick, I always go with "the people will be clean," because I like that it makes my empire more dignified. So I think having CYOA chains along those lines could be nice, providing longer term benefits down the chain for benevolent decisions, and negative or neutral tradeoffs coming after picking the upfront yields decisions. I've seen other people comment that they don't really like being an exploitative tyrant (at least towards their own citizens) but do so because it's the strongest way to play, if some of the CYOA chains are focused on the well-being (or max. value extraction) of citizens that might create another avenue for letting the player shape their ruling style, instead of just relying on culture picks.

Some other examples might include the monument event; perhaps the +1 gold could be +2, but risk making people greedier (+needs from poverty), or the market event; maybe letting foreigners trade doesn't give -1 gold, just +1 culture, but also increases religious pressure on your cities. These are just off the top of my head but the idea is it's ok if different decisions are unbalanced as long as the entire tree is more or less balanced, with small negative decisions counteracting yield inflation.
 
How do you see if a dummy policy is active? For the religious events, I've got a lua script that runs on founding to create a policy based on which religion you went with. Which religious events you get then use that dummy policy to know which event chain to use. I'm just not sure how to see if the script actually creates the dummy policy or not. I could easily use IGE to create a prophet and found, but I still cannot see if the policy is active. I'm assuming it would be FireTuner but I have no idea how to use FireTuner yet.
 
How do you see if a dummy policy is active? For the religious events, I've got a lua script that runs on founding to create a policy based on which religion you went with. Which religious events you get then use that dummy policy to know which event chain to use. I'm just not sure how to see if the script actually creates the dummy policy or not. I could easily use IGE to create a prophet and found, but I still cannot see if the policy is active. I'm assuming it would be FireTuner but I have no idea how to use FireTuner yet.
There may be better ways to do this -- but when I need to test if something invisible is active, i'll write a conditional check for it right in the lua file, something like:

if HasPolicy then
print("policy x is active")​
end

This assumes there is a lua hook available to query whether player has a specific policy (ie HasPolicy is just pseudo-code stand in for w/e lua function is available -- I've never used such a hook/function myself). You'll see the print statement in the main firetuner console output. Comment this code block out once you're confident its working as intended (or delete it).

edit: API lists a Player:HasPolicyBranch(iPolicyBranchType) function that i'm guessing would work for a check as described above
 
Last edited:
Reviewing the lua logs, it's telling me I'm throwing an error in my religious events code:

Spoiler LUA code :

Code:
-- Dummy Policy Creator for Religious Events
-- Author: rsc2a
-- DateCreated: Feb 6, 2024
--------------------------------------------------------------   

local ePilgrimageBelief = GameInfo.Beliefs.BELIEF_PILGRIMAGE.ID
local eCeremonialBurialBelief = GameInfo.Beliefs.BELIEF_CEREMONIAL_BURIAL.ID
local eCouncilofEldersBelief = GameInfo.Beliefs.BELIEF_PAPAL_PRIMACY.ID
local eHeroWorshipBelief = GameInfo.Beliefs.BELIEF_INTERFAITH_DIALOGUE.ID
local eHolyLawBelief = GameInfo.Beliefs.BELIEF_CHURCH_PROPERTY.ID
local eDivineInheritanceBelief = GameInfo.Beliefs.BELIEF_PEACE_LOVING.ID
local eTheocraticRuleBelief = GameInfo.Beliefs.BELIEF_WORLD_CHURCH.ID
local eRevelationBelief = GameInfo.Beliefs.BELIEF_TITHE.ID
local eTranscendentThoughtsBelief = GameInfo.Beliefs.BELIEF_INITIATION_RITES.ID

local ePilgrimageDummyPolicy = GameInfoTypes.POLICY_PILGRIMAGE_DUMMY
local eCeremonialBurialDummyPolicy = GameInfoTypes.POLICY_CEREMONIAL_BURIAL_DUMMY
local eCouncilofEldersDummyPolicy = GameInfoTypes.POLICY_PAPAL_PRIMACY_DUMMY
local eHeroWorshipDummyPolicy = GameInfoTypes.POLICY_INTERFAITH_DIALOGUE_DUMMY
local eHolyLawDummyPolicy = GameInfoTypes.POLICY_CHURCH_PROPERTY_DUMMY
local eDivineInheritanceDummyPolicy = GameInfoTypes.POLICY_PEACE_LOVING_DUMMY
local eTheocraticRuleDummyPolicy = GameInfoTypes.POLICY_WORLD_CHURCH_DUMMY
local eRevelationDummyPolicy = GameInfoTypes.POLICY_TITHE_DUMMY
local eTranscendentThoughtsDummyPolicy = GameInfoTypes.POLICY_INITIATION_RITES_DUMMY

function OnReligionFoundDummy(iPlayer, iHolyCity, iReligion, iBelief1, iBelief2, iBelief3, iBelief4, iBelief5)

    local pPlayer = Players[iPlayer]

    if (iBelief1 == ePilgrimageBelief or iBelief2 == ePilgrimageBelief or iBelief3 == ePilgrimageBelief or iBelief4 == ePilgrimageBelief or iBelief5 == ePilgrimageBelief) then
        pPlayer:GrantPolicy(ePilgrimageDummyPolicy, true)
        return end
    end

    if (iBelief1 == eCeremonialBurialBelief or iBelief2 == eCeremonialBurialBelief or iBelief3 == eCeremonialBurialBelief or iBelief4 == eCeremonialBurialBelief or iBelief5 == eCeremonialBurialBelief) then
        pPlayer:GrantPolicy(eCeremonialBurialDummyPolicy, true)
        return end
    end

    if (iBelief1 == eCouncilofEldersBelief or iBelief2 == eCouncilofEldersBelief or iBelief3 == eCouncilofEldersBelief or iBelief4 == eCouncilofEldersBelief or iBelief5 == eCouncilofEldersBelief) then
        pPlayer:GrantPolicy(eCouncilofEldersDummyPolicy, true)
        return end
    end

    if (iBelief1 == eHeroWorshipBelief or iBelief2 == eHeroWorshipBelief or iBelief3 == eHeroWorshipBelief or iBelief4 == eHeroWorshipBelief or iBelief5 == eHeroWorshipBelief) then
        pPlayer:GrantPolicy(eHeroWorshipDummyPolicy, true)
        return end
    end

    if (iBelief1 == eHolyLawBelief or iBelief2 == eHolyLawBelief or iBelief3 == eHolyLawBelief or iBelief4 == eHolyLawBelief or iBelief5 == eHolyLawBelief) then
        pPlayer:GrantPolicy(eHolyLawDummyPolicy, true)
        return end
    end

    if (iBelief1 == eDivineInheritanceBelief or iBelief2 == eDivineInheritanceBelief or iBelief3 == eDivineInheritanceBelief or iBelief4 == eDivineInheritanceBelief or iBelief5 == eDivineInheritanceBelief) then
        pPlayer:GrantPolicy(eDivineInheritanceDummyPolicy, true)
        return end
    end

    if (iBelief1 == eTheocraticRuleBelief or iBelief2 == eTheocraticRuleBelief or iBelief3 == eTheocraticRuleBelief or iBelief4 == eTheocraticRuleBelief or iBelief5 == eTheocraticRuleBelief) then
        pPlayer:GrantPolicy(eTheocraticRuleDummyPolicy, true)
        return end
    end

    if (iBelief1 == eRevelationBelief or iBelief2 == eRevelationBelief or iBelief3 == eRevelationBelief or iBelief4 == eRevelationBelief or iBelief5 == eRevelationBelief) then
        pPlayer:GrantPolicy(eRevelationDummyPolicy, true)
        return end
    end

    if (iBelief1 == eTranscendentThoughtsBelief or iBelief2 == eTranscendentThoughtsBelief or iBelief3 == eTranscendentThoughtsBelief or iBelief4 == eTranscendentThoughtsBelief or iBelief5 == eTranscendentThoughtsBelief) then
        pPlayer:GrantPolicy(eTranscendentThoughtsDummyPolicy, true)
        return end
    end

    if Player:HasPolicyBranch(ePilgrimageDummyPolicy) then
        print("ePilgrimageDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eCeremonialBurialDummyPolicy) then
        print("eCeremonialBurialDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eCouncilofEldersDummyPolicy) then
        print("eCouncilofEldersDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eHeroWorshipDummyPolicy) then
        print("eHeroWorshipDummyPolicy x is active")
    end   
    if Player:HasPolicyBranch(eHolyLawDummyPolicy) then
        print("eHolyLawDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eDivineInheritanceDummyPolicy) then
        print("eDivineInheritanceDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eTheocraticRuleDummyPolicy) then
        print("eTheocraticRuleDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eRevelationDummyPolicy) then
        print("eRevelationDummyPolicy x is active")
    end   
    if Player:HasPolicyBranch(eTranscendentThoughtsDummyPolicy) then
        print("eTranscendentThoughtsDummyPolicy x is active")
    end   
end

GameEvents.ReligionFounded.Add(OnReligionFoundDummy)


Here's the error I'm getting:

[448149.968] Syntax Error: C:\...\LUA/ReligionEventsLUA.lua:38: '<eof>' expected near 'end'
[448149.984] Runtime Error: Error loading C:\...\LUA/ReligionEventsLUA.lua.
 
return end
should probably just be 'return' -- you have end followed by another end on the next line, so the lua runtime thinks the function is finished at like line 5. Whether 'return' accomplishes what you're after is another question (looks fine to me but I don't know the context here), but drop one of the 'end' everywhere you have them doubled-up and try again

I suspect you know this already, but a 'return' will end the function that contains it -- so like anytime any of those return lines is encountered, thats it, the function stops running for that specific call (it can still be called again by whatever next triggers it of course). If all of those conditionals are mutually exclusive circumstances, then it should work as you intend, I am second guessing only cuz its more common to see elseif used for this purpose. Also all your test/print conditionals at the end won't ever trigger if the runtime hits those 'return' lines; are you only concerned with testing for active policies if nothing is changed in the top part of the function? If you want it to run those checks every time the function runs, those 'return' lines will be a problem

edit: here's a possible alternative that accomplishes the same thing (ie the initial conditionals containing 'return' are indeed mutually exclusive), AND runs your print tests:
Spoiler :

Code:
-- Dummy Policy Creator for Religious Events
-- Author: rsc2a
-- DateCreated: Feb 6, 2024
--------------------------------------------------------------  

local ePilgrimageBelief = GameInfo.Beliefs.BELIEF_PILGRIMAGE.ID
local eCeremonialBurialBelief = GameInfo.Beliefs.BELIEF_CEREMONIAL_BURIAL.ID
local eCouncilofEldersBelief = GameInfo.Beliefs.BELIEF_PAPAL_PRIMACY.ID
local eHeroWorshipBelief = GameInfo.Beliefs.BELIEF_INTERFAITH_DIALOGUE.ID
local eHolyLawBelief = GameInfo.Beliefs.BELIEF_CHURCH_PROPERTY.ID
local eDivineInheritanceBelief = GameInfo.Beliefs.BELIEF_PEACE_LOVING.ID
local eTheocraticRuleBelief = GameInfo.Beliefs.BELIEF_WORLD_CHURCH.ID
local eRevelationBelief = GameInfo.Beliefs.BELIEF_TITHE.ID
local eTranscendentThoughtsBelief = GameInfo.Beliefs.BELIEF_INITIATION_RITES.ID

local ePilgrimageDummyPolicy = GameInfoTypes.POLICY_PILGRIMAGE_DUMMY
local eCeremonialBurialDummyPolicy = GameInfoTypes.POLICY_CEREMONIAL_BURIAL_DUMMY
local eCouncilofEldersDummyPolicy = GameInfoTypes.POLICY_PAPAL_PRIMACY_DUMMY
local eHeroWorshipDummyPolicy = GameInfoTypes.POLICY_INTERFAITH_DIALOGUE_DUMMY
local eHolyLawDummyPolicy = GameInfoTypes.POLICY_CHURCH_PROPERTY_DUMMY
local eDivineInheritanceDummyPolicy = GameInfoTypes.POLICY_PEACE_LOVING_DUMMY
local eTheocraticRuleDummyPolicy = GameInfoTypes.POLICY_WORLD_CHURCH_DUMMY
local eRevelationDummyPolicy = GameInfoTypes.POLICY_TITHE_DUMMY
local eTranscendentThoughtsDummyPolicy = GameInfoTypes.POLICY_INITIATION_RITES_DUMMY

function OnReligionFoundDummy(iPlayer, iHolyCity, iReligion, iBelief1, iBelief2, iBelief3, iBelief4, iBelief5)

    local pPlayer = Players[iPlayer]

    if (iBelief1 == ePilgrimageBelief or iBelief2 == ePilgrimageBelief or iBelief3 == ePilgrimageBelief or iBelief4 == ePilgrimageBelief or iBelief5 == ePilgrimageBelief) then
        pPlayer:GrantPolicy(ePilgrimageDummyPolicy, true)
    elseif (iBelief1 == eCeremonialBurialBelief or iBelief2 == eCeremonialBurialBelief or iBelief3 == eCeremonialBurialBelief or iBelief4 == eCeremonialBurialBelief or iBelief5 == eCeremonialBurialBelief) then
        pPlayer:GrantPolicy(eCeremonialBurialDummyPolicy, true)
    elseif (iBelief1 == eCouncilofEldersBelief or iBelief2 == eCouncilofEldersBelief or iBelief3 == eCouncilofEldersBelief or iBelief4 == eCouncilofEldersBelief or iBelief5 == eCouncilofEldersBelief) then
        pPlayer:GrantPolicy(eCouncilofEldersDummyPolicy, true)
    elseif (iBelief1 == eHeroWorshipBelief or iBelief2 == eHeroWorshipBelief or iBelief3 == eHeroWorshipBelief or iBelief4 == eHeroWorshipBelief or iBelief5 == eHeroWorshipBelief) then
        pPlayer:GrantPolicy(eHeroWorshipDummyPolicy, true)
    elseif (iBelief1 == eHolyLawBelief or iBelief2 == eHolyLawBelief or iBelief3 == eHolyLawBelief or iBelief4 == eHolyLawBelief or iBelief5 == eHolyLawBelief) then
        pPlayer:GrantPolicy(eHolyLawDummyPolicy, true)
    elseif (iBelief1 == eDivineInheritanceBelief or iBelief2 == eDivineInheritanceBelief or iBelief3 == eDivineInheritanceBelief or iBelief4 == eDivineInheritanceBelief or iBelief5 == eDivineInheritanceBelief) then
        pPlayer:GrantPolicy(eDivineInheritanceDummyPolicy, true)
    elseif (iBelief1 == eTheocraticRuleBelief or iBelief2 == eTheocraticRuleBelief or iBelief3 == eTheocraticRuleBelief or iBelief4 == eTheocraticRuleBelief or iBelief5 == eTheocraticRuleBelief) then
        pPlayer:GrantPolicy(eTheocraticRuleDummyPolicy, true)
    elseif (iBelief1 == eRevelationBelief or iBelief2 == eRevelationBelief or iBelief3 == eRevelationBelief or iBelief4 == eRevelationBelief or iBelief5 == eRevelationBelief) then
        pPlayer:GrantPolicy(eRevelationDummyPolicy, true)
    elseif (iBelief1 == eTranscendentThoughtsBelief or iBelief2 == eTranscendentThoughtsBelief or iBelief3 == eTranscendentThoughtsBelief or iBelief4 == eTranscendentThoughtsBelief or iBelief5 == eTranscendentThoughtsBelief) then
        pPlayer:GrantPolicy(eTranscendentThoughtsDummyPolicy, true)
    end

    if Player:HasPolicyBranch(ePilgrimageDummyPolicy) then
        print("ePilgrimageDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eCeremonialBurialDummyPolicy) then
        print("eCeremonialBurialDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eCouncilofEldersDummyPolicy) then
        print("eCouncilofEldersDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eHeroWorshipDummyPolicy) then
        print("eHeroWorshipDummyPolicy x is active")
    end  
    if Player:HasPolicyBranch(eHolyLawDummyPolicy) then
        print("eHolyLawDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eDivineInheritanceDummyPolicy) then
        print("eDivineInheritanceDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eTheocraticRuleDummyPolicy) then
        print("eTheocraticRuleDummyPolicy x is active")
    end
    if Player:HasPolicyBranch(eRevelationDummyPolicy) then
        print("eRevelationDummyPolicy x is active")
    end  
    if Player:HasPolicyBranch(eTranscendentThoughtsDummyPolicy) then
        print("eTranscendentThoughtsDummyPolicy x is active")
    end  
end

GameEvents.ReligionFounded.Add(OnReligionFoundDummy)
 
Last edited:
should probably just be 'return' -- you have end followed by another end on the next line, so the lua runtime thinks the function is finished at like line 5. Whether 'return' accomplishes what you're after is another question (looks fine to me but I don't know the context here), but drop one of the 'end' everywhere you have them doubled-up and try again

I suspect you know this already, but a 'return' will end the function that contains it -- so like anytime any of those return lines is encountered, thats it, the function stops running for that specific call (it can still be called again by whatever next triggers it of course). If all of those conditionals are mutually exclusive circumstances, then it should work as you intend, I am second guessing only cuz its more common to see elseif used for this purpose...

Yes. That is the intention. The idea is that you found a religion and, based on whichever founder you pick, it gives you a dummy policy. I do think I might have to modify it somehow to account for Byzantine possibly picking two founders but I'm not sure how to do that just yet (unless someone knows if a particular 'iBeliefX' coresponds to a founder, then I'll just limit the conditions to that iBeliefX). One idea I had was to have it so that either event chain could fire but once that first event fired, it blocked the other chain from running. Would add a bit of event randomness to the fact that Byzantine happened to pick two founders.

Also all your test/print conditionals at the end won't ever trigger if the runtime hits those 'return' lines; are you only concerned with testing for active policies if nothing is changed in the top part of the function? If you want it to run those checks every time the function runs, those 'return' lines will be a problem
Yes. I had a feeling that the dummy policies weren't firing and they are the starting condition for all the religious events. No religious dummy policies...no religious events.

I had thought about those test prints not firing because of those returns but when I saw the lua error, I knew it was going to be working anyways and just thought I'd clean that part up when someone offered a better solution.

edit: here's a possible alternative that accomplishes the same thing (ie the initial conditionals containing 'return' are indeed mutually exclusive), AND runs your print tests:
Thanks!
 
I do think I might have to modify it somehow to account for Byzantine possibly picking two founders but I'm not sure how to do that just yet (unless someone knows if a particular 'iBeliefX' coresponds to a founder, then I'll just limit the conditions to that iBeliefX). One idea I had was to have it so that either event chain could fire but once that first event fired, it blocked the other chain from running.
i cant really comment on the appropriateness of having it work this way in-game, but as far as structuring your code, you'd want to go back to the way you had it initially laid out (not my elseif version). You could let all the conditionals run without the return line at all, just get rid of those -- in some cases your code will do a few extra conditional checks after it evaluates the one that was actually chosen, but this religion founding stuff doesn't happen frequently in the game -- its more the every-turn occurrences that you want to minimize extra lua work for.
 
Your code can be simplified to:

Code:
-- Dummy Policy Creator for Religious Events
-- Author: rsc2a
-- DateCreated: Feb 6, 2024
-------------------------------------------------------------- 

local ePilgrimageBelief = GameInfoTypes.BELIEF_PILGRIMAGE
local eCeremonialBurialBelief = GameInfoTypes.BELIEF_CEREMONIAL_BURIAL
local eCouncilofEldersBelief = GameInfoTypes.BELIEF_PAPAL_PRIMACY
local eHeroWorshipBelief = GameInfoTypes.BELIEF_INTERFAITH_DIALOGUE
local eHolyLawBelief = GameInfoTypes.BELIEF_CHURCH_PROPERTY
local eDivineInheritanceBelief = GameInfoTypes.BELIEF_PEACE_LOVING
local eTheocraticRuleBelief = GameInfoTypes.BELIEF_WORLD_CHURCH
local eRevelationBelief = GameInfoTypes.BELIEF_TITHE
local eTranscendentThoughtsBelief = GameInfoTypes.BELIEF_INITIATION_RITES

local ePilgrimageDummyPolicy = GameInfoTypes.POLICY_PILGRIMAGE_DUMMY
local eCeremonialBurialDummyPolicy = GameInfoTypes.POLICY_CEREMONIAL_BURIAL_DUMMY
local eCouncilofEldersDummyPolicy = GameInfoTypes.POLICY_PAPAL_PRIMACY_DUMMY
local eHeroWorshipDummyPolicy = GameInfoTypes.POLICY_INTERFAITH_DIALOGUE_DUMMY
local eHolyLawDummyPolicy = GameInfoTypes.POLICY_CHURCH_PROPERTY_DUMMY
local eDivineInheritanceDummyPolicy = GameInfoTypes.POLICY_PEACE_LOVING_DUMMY
local eTheocraticRuleDummyPolicy = GameInfoTypes.POLICY_WORLD_CHURCH_DUMMY
local eRevelationDummyPolicy = GameInfoTypes.POLICY_TITHE_DUMMY
local eTranscendentThoughtsDummyPolicy = GameInfoTypes.POLICY_INITIATION_RITES_DUMMY

local tBeliefPolicy = {
    [ePilgrimageBelief] = ePilgrimageDummyPolicy,
    [eCeremonialBurialBelief] = eCeremonialBurialDummyPolicy,
    [eCouncilofEldersBelief] = eCouncilofEldersDummyPolicy,
    [eHeroWorshipBelief] = eHeroWorshipDummyPolicy,
    [eHolyLawBelief] = eHolyLawDummyPolicy,
    [eDivineInheritanceBelief] = eDivineInheritanceDummyPolicy,
    [eTheocraticRuleBelief] = eTheocraticRuleDummyPolicy,
    [eRevelationBelief] = eRevelationDummyPolicy,
    [eTranscendentThoughtsBelief] = eTranscendentThoughtsDummyPolicy,
}

function OnReligionFoundDummy(ePlayer, eHolyCity, eReligion, eBelief1, eBelief2, eBelief3, eBelief4, eBelief5)

    local pPlayer = Players[ePlayer]
    local tOwnedBelief = {eBelief1, eBelief2, eBelief3, eBelief4, eBelief5}

    for _, eOwnedBelief in tOwnedBelief do
        for eBelief, ePolicy in tBeliefPolicy do
            if eOwnedBelief == eBelief then
                pPlayer:GrantPolicy(ePolicy, true)
                -- Log for validation
                if Player:HasPolicy(ePolicy) then
                    sPolicyName = Locale.ConvertTextKey(GameInfo.Policies[ePolicy].Description)
                    print(sPolicyName .. " is active")
                end
            end
        end
    end
end

GameEvents.ReligionFounded.Add(OnReligionFoundDummy)

Note that you want HasPolicy, not HasPolicyBranch (which takes a PolicyBranchType).

This will give two event branches to Byzantium if they picked two founder beliefs, but you can always shuffle tOwnedBelief and return early when one is found if you want a random one to be active.
 
I think this would be the correct modifications to the latest code if I wanted to shuffle the tOwnedBelief and return early as @azum4roll proposed, right?

Spoiler LUA code :

Code:
-- Dummy Policy Creator for Religious Events
-- Author: rsc2a
-- DateCreated: Feb 6, 2024
--------------------------------------------------------------

local ePilgrimageBelief = GameInfoTypes.BELIEF_PILGRIMAGE
local eCeremonialBurialBelief = GameInfoTypes.BELIEF_CEREMONIAL_BURIAL
local eCouncilofEldersBelief = GameInfoTypes.BELIEF_PAPAL_PRIMACY
local eHeroWorshipBelief = GameInfoTypes.BELIEF_INTERFAITH_DIALOGUE
local eHolyLawBelief = GameInfoTypes.BELIEF_CHURCH_PROPERTY
local eDivineInheritanceBelief = GameInfoTypes.BELIEF_PEACE_LOVING
local eTheocraticRuleBelief = GameInfoTypes.BELIEF_WORLD_CHURCH
local eRevelationBelief = GameInfoTypes.BELIEF_TITHE
local eTranscendentThoughtsBelief = GameInfoTypes.BELIEF_INITIATION_RITES

local ePilgrimageDummyPolicy = GameInfoTypes.POLICY_PILGRIMAGE_DUMMY
local eCeremonialBurialDummyPolicy = GameInfoTypes.POLICY_CEREMONIAL_BURIAL_DUMMY
local eCouncilofEldersDummyPolicy = GameInfoTypes.POLICY_PAPAL_PRIMACY_DUMMY
local eHeroWorshipDummyPolicy = GameInfoTypes.POLICY_INTERFAITH_DIALOGUE_DUMMY
local eHolyLawDummyPolicy = GameInfoTypes.POLICY_CHURCH_PROPERTY_DUMMY
local eDivineInheritanceDummyPolicy = GameInfoTypes.POLICY_PEACE_LOVING_DUMMY
local eTheocraticRuleDummyPolicy = GameInfoTypes.POLICY_WORLD_CHURCH_DUMMY
local eRevelationDummyPolicy = GameInfoTypes.POLICY_TITHE_DUMMY
local eTranscendentThoughtsDummyPolicy = GameInfoTypes.POLICY_INITIATION_RITES_DUMMY

local tBeliefPolicy = {
    [ePilgrimageBelief] = ePilgrimageDummyPolicy,
    [eCeremonialBurialBelief] = eCeremonialBurialDummyPolicy,
    [eCouncilofEldersBelief] = eCouncilofEldersDummyPolicy,
    [eHeroWorshipBelief] = eHeroWorshipDummyPolicy,
    [eHolyLawBelief] = eHolyLawDummyPolicy,
    [eDivineInheritanceBelief] = eDivineInheritanceDummyPolicy,
    [eTheocraticRuleBelief] = eTheocraticRuleDummyPolicy,
    [eRevelationBelief] = eRevelationDummyPolicy,
    [eTranscendentThoughtsBelief] = eTranscendentThoughtsDummyPolicy,
}

function OnReligionFoundDummy(ePlayer, eHolyCity, eReligion, eBelief1, eBelief2, eBelief3, eBelief4, eBelief5)

    local pPlayer = Players[ePlayer]
    local tOwnedBelief = {eBelief1, eBelief2, eBelief3, eBelief4, eBelief5}

--------------------------------------------------------------
-- Shuffling the owned beliefs so Byzantium is randomized
--------------------------------------------------------------
    for i = 1, 4 do
        local r = math.random(i, 5)
         tOwnedBelief[i],  tOwnedBelief[r] =  tOwnedBelief[r],  tOwnedBelief[i]
    end

    for _, eOwnedBelief in tOwnedBelief do
        for eBelief, ePolicy in tBeliefPolicy do
            if eOwnedBelief == eBelief then
                pPlayer:GrantPolicy(ePolicy, true)
                -- Log for validation
                if Player:HasPolicy(ePolicy) then
                    sPolicyName = Locale.ConvertTextKey(GameInfo.Policies[ePolicy].Description)
                    print(sPolicyName .. " is active")
                    return  -- Added the return to jump out of the function for Byzantium
                end
            end
        end
    end
end

GameEvents.ReligionFounded.Add(OnReligionFoundDummy)
 
if Player:HasPolicy(ePolicy) then
sPolicyName = Locale.ConvertTextKey(GameInfo.Policies[ePolicy].Description)
print(sPolicyName .. " is active")
return -- Added the return to jump out of the function for Byzantium
end
I think the first line here you meant pPlayer? other than that, it raises my concern slightly that you might shuffle and make boolean comparisons on nil values -- might not be an issue, I can't recall the specifics exactly. I've never used this hook but I assume some of the eBelief# parameters will be nil most of the time. If you run into troubles, maybe consider eliminating the nils from tOwnedBelief as you shuffle.

I'm a little confused by the logic of your use of 'return'; like, it will work, just the placement of it makes me wonder if the intention will be achieved. Its inside a nested if that will always be true? Am I reading things right? as long as eOwnedBelief == eBelief is true, we give pPlayer a dummy ePolicy, then check if pPlayer has the dummy ePolicy (always true since we just gave it to them), and then terminate the entire function. Is it possible you meant 'break' here? Like you just want to end the inner for loop? I don't have a clear idea what you intend here, maybe you've got it right and its just me. Seems though the conditional I quoted above is redundant, as things stand. Maybe you meant for this conditional to be somewhere else? before the eOwnedBelief == eBelief conditional, perhaps?

edit: looking at it again, I *think* it would be better to eliminate the nested conditional, keep the contents. I suppose keeping the conditional is a way to check that GrantPolicy actually worked as I suggested above, though I think its safe to assume it did in this structure, kinda redundant when GrantPolicy and HasPolicy are one right after another.
Code:
for _, eOwnedBelief in tOwnedBelief do
    for eBelief, ePolicy in tBeliefPolicy do
        if eOwnedBelief == eBelief then
            pPlayer:GrantPolicy(ePolicy, true)
            -- Log for validation
            sPolicyName = Locale.ConvertTextKey(GameInfo.Policies[ePolicy].Description)
            print(sPolicyName .. " is active")
            return  -- Added the return to jump out of the function for Byzantium
        end
    end
end
 
Last edited:
What I was attempting to do was take the code that azum4roll provided and adjust it to take care of Byzantium.

Thinking is that

a) You found a religion.
b) Code runs. Checks what founder belief you selected and gives you a dummy policy based on the founder. (The religious events condition requires this dummy policy, so now religious events can be specific to a particular founder.)
c) Profit! ....except what if Byzantium chooses two founders? They would be getting two sets of religious events because the code gave them two dummy policies. Oops.

d) Let's tweak the code to jump out as soon as one dummy policy is awarded so Byzantium doesn't get two (thus the return).
e) Let's also make things a bit more random for Byzantium and shuffle the founder belief so they could get either set of events (but not both).

** As a bonus, this is helping give me experience that should help me to further diversify the events system with my current plans and hopefully providing a structure for additional EPs that can be created by other folks.
 
Last edited:
gotcha okay i was just confused by the nested conditional, i think you got it

If the intention is for there to be only one resulting event dummy policy anyway, it might be more efficient just to randomly pluck out a non-nil founder belief from tOwnedBelief, rather than shuffling the table itself. I think you'd also eliminate the nested for's that way. The nested for loops allowed byzantium to get two (or more) dummy policies, but then the return prevents that from happening, and just assigns the first in the shuffled list. instead of having a shuffled list & looping through that list then aborting, just pick one from the get-go and eliminate the shuffled list altogether? to some extent this might depend on how the event triggers themselves function. azum's code is very good it just does more than it sounds like you really need it to
 
Last edited:
gotcha okay i was just confused by the nested conditional, i think you got it

it might be more efficient just to randomly pluck out a non-nil founder belief from tOwnedBelief, rather than shuffling the table itself. I think you'd also eliminate the nested for's that way.
I had thought about doing just that. But I'm not sure with this...

function OnReligionFoundDummy(ePlayer, eHolyCity, eReligion, eBelief1, eBelief2, eBelief3, eBelief4, eBelief5)

...which eBeliefx corresponds to the founder. I would assume it's eBelief2 but I'm not sure. I thought this way was a bit safer in case the beliefs can get shuffled somehow.

The nested for loops allowed byzantium to get two dummy policies, but then the return prevents that from happening, and just assigns the first in the shuffled list.
Yes, exactly that.

instead of having a shuffled list & looping through that list then aborting, just pick one from the get-go and eliminate the shuffled list altogether? to some extent this might depend on how the event triggers themselves function
The trigger for the initial event (that starts the event chain) is having the dummy policy. So, as long as I can give the founder a dummy policy, the religious events will fire.

Additional info: The old religious events required reformation because the trigger was having the reformation building, and that was how the events were set to be specific to each founder. I didn't want reformation to be a requirement for the initial chain to start because it can happen so late. I wanted the religious events chain to start earlier but I still wanted them to be specific to the type of religion. Thus the need for this coding. One event in the chain still requires reformation, but it's only one event in the overall event group.
 
function OnReligionFoundDummy(ePlayer, eHolyCity, eReligion, eBelief1, eBelief2, eBelief3, eBelief4, eBelief5)

...which eBeliefx corresponds to the founder. I would assume it's eBelief2 but I'm not sure. I thought this way was a bit safer in case the beliefs can get shuffled somehow.
Yeah i was just thinking about this as well -- I assume there are only gonna be either 1 (or 2 for byzantium) of these that actually matter for your purposes. In theory we could probably eliminate a nested for loop if we knew which were founder & follower etc., but I suppose since we're not sure which parameter is which, it makes sense to loop over them all.

What you've got will leave you in good shape for future work as well, if you want to maybe make use of byzantium's second policy somehow: just take out the return and you're set
 
@rsc2a I'm curious how you are making use of the dummy policies to actually trigger the events attached to each -- are you checking for these dummy policies at the start of each turn? And then what? I'm still only theorycrafting some ideas connected to events, just wondering what you've worked out as the best method for starting an event chain
 
@rsc2a I'm curious how you are making use of the dummy policies to actually trigger the events attached to each -- are you checking for these dummy policies at the start of each turn? And then what? I'm still only theorycrafting some ideas connected to events, just wondering what you've worked out as the best method for starting an event chain
One of the conditionals you can set to make an event viable is policy. Under the Events table, there is a column for 'RequiredPolicy". For the religious events, I've just set the religion-specific dummy policy as a required policy to start the particular religious event chain. Once you fire the first event, you can use either that event itself if you feel like it (or continue to use 'RequiredPolicy').
 
Last edited:
Top Bottom