Garrisoned City 100% less likely to Revolt

When Revolutions is on, any "City X% Less Likely to Revolt" promotion has a different effect. It increases the total stability from the city's garrison by the %, up to the cap on garrisons (-15 if the city gets instability from nationality, -20 if not). The base stability from garrisons is a factor of how many units are present, plus the presence of defensive buildings until you reach Liberalism. So if you want to hold down a difficult city, you still need multiple units, but a Loyalty-/Patrol-promoted unit will make the garrison more effective, or free up units if you were already devoting enough of them to be over the cap.

Changing the game text on these promotions for the presence/absence of Revolutions is outside my capabilities.
 
So if I have a city with 2 units, each with a "City 10% less likely to revolt" promotion, do they stack? Is the effectiveness of the garrison increased by +10% or +20%?
 
So if I have a city with 2 units, each with a "City 10% less likely to revolt" promotion, do they stack? Is the effectiveness of the garrison increased by +10% or +20%?

Yes, but you'll need to stack up a decent modifier to have any effect. The Python code is fairly straightforward, but I think anything less than 100% total gets damped out. This is the code section:
Code:
            #Afforess Revolt Protection
            garIdx *= int((100 + (pCity.plot().getRevoltProtection())) / 100)
            #Afforess End

            garIdx = int(math.floor( self.garrisonModifier*garIdx + .5 ))

garIdx at the beginning is the original garrison factor, calculated from the number of units and the presence of city defenses.

This part of the code is supposed to multiply the garrison change by the RevoltProtection, but then it multiplies it again by the garrison modifier, which defaults to 2.0, adds .5 and then reduces it to an integer. This is where I think a small amount of Patrol promotions get cut out, probably because that .5 is adding to a negative number, so subtracting from the absolute magnitude. I think we having some clashing programming going on. Afforess added the revolt protection, and it seems to work for 100% or more revolt protection, but not anything less. I'm disassembling the math right now to see what I can find.

With the original code, I did some actual in-game testing and I found that a stack of 6 garrison units didn't see any changes until I promoted 4 of them to Patrol I. On the other hand, 2 Praetorians with Loyalty and 4 other units had more of a garrison effect than 1 Praetorian plus 5 units, and both had more than 6 units with no promotions.
 
So rule of thumb is "have a total of at least 100% total revolt protection across the garrison units" to actually get an effect.
Thanks!
 
I think there's more than one problem at work. I think Afforess' formula has an int where there shouldn't be one. That's why less than 100% revolt protection isn't returning anything.

I'm also trying to figure out why both int and floor are being used on the next line. floor already returns an integer, so int seems unnecessary. There is a difference between int and floor, I'm not trying to deny that. But I wonder what is the purpose of using both.
 
This gives me the results I want. I can leave int and floor alone at the end, but do all the multiplying at once and do it first. This gives a garrison of -4 with 4 units and no Patrol promotions, -5 with 4 units and 1 Patrol, and -6 with 4 units and 2 Patrol promotions.

Code:
            #Afforess Revolt Protection
            garIdx = garIdx * self.garrisonModifier * (100 + pCity.plot().getRevoltProtection())/100
            #Afforess End

            garIdx = int(math.floor(garIdx + .5 ))
 
Are you going to use the modified the formula in some future revision?

Meanwhile, I ran some tests to get some numbers for myself.
Setup is a generic Duel map, founded a couple of cities, and spawned a bunch of units, moving them back and forth into and out of the cities to see how the garrison revolution modifier changes.
I found out that the maximum modifier is -15 (what does "Nationality instability" mean in this case? City culture was 100% mine), and the modifier varied as follows:

NO revolution-reducing promotions (Loyal, Patrol, etc)
N° of units -------- Modifier
0,1 ---------------- 0
2,3 --------------- -3
4 to 6 ------------ -6
7 to 10 ----------- -9
11 to 15 --------- -12
16 and more ---- -15​


-100% total revolution-reducing promotions (1 "Loyal" or a combination of 4x "Patrol"(2), etc)
N° of units ----- Modifier
1 ---------------- 0
2 --------------- -6
4 to 6 --------- -12
7 and more --- -15


-225% total revolution-reducing promotions (5x "Patrol"(3))
N° of units ------ Modifier
5 ---------------- -15


Recap of revolution-reducing promotions:
Loyal: -100% , only with Great General or Praetorian (Rome U.U.)
Patrol line (available at Fascism): 1 -10% ; 2 -15% (-25% total); 3 -20% (-45% total)
Pharaoh's Propaganda (Kemetism religion): -30%
Mujahid (Islam religion): -50%
 
Nationality index is supposed to be positive (increasing instability) if your nationality percentage is less than 60%; you can offset it somewhat with culture spending but you can't negate it unless you have more than 50%. I'm not sure what combination of factors led you to have instability from nationality while you had 100% nationality. If you saved your experiment, I'd like to see it. As long as you have instability from nationality, your stability from garrisons is capped at -15, but if you don't, then the cap goes up to -20.
 
Here's the save.
I am still using an old revision (want to finish an old game before updating to the new exploration mechanics).
Also in use is the megacivpack.
 

Attachments

Here's the save.
I am still using an old revision (want to finish an old game before updating to the new exploration mechanics).
Also in use is the megacivpack.

I did not realize you were playing a version that old. That game was saved from rev993. What you're seeing is the way the revolution mechanics used to work. I did not add the garrison cap increases until rev1015. Before that, the caps were actually -10 (nationality problems)/-15 (no nationality problems). I increased the caps to give players an additional way to fight revolutions, if they were willing to pay for it in terms of garrison unit commitments. I didn't just want to make garrisons more effective in general.
 
Not completely working as intended. It does work somewhat right now, but only for full multiples of 100% revolt protection. Anything less gets cut off. I'm tweaking the formulas to allow smaller percentages to work as well, although with small garrisons and small %, you probably won't see any actual effect.

The thing that I can't fix is that the game text still displays "% less likely to revolt" rather than the actual "% to garrison effectiveness". That needs DLL editing to cover flipping between Revolutions and No Revolutions.
 
I did not realize you were playing a version that old. That game was saved from rev993. What you're seeing is the way the revolution mechanics used to work. I did not add the garrison cap increases until rev1015. Before that, the caps were actually -10 (nationality problems)/-15 (no nationality problems). I increased the caps to give players an additional way to fight revolutions, if they were willing to pay for it in terms of garrison unit commitments. I didn't just want to make garrisons more effective in general.

Thanks for checking!
I'll do some new testing when I'll finally finish the old game and upgrade to the current revision.
 
The thing that I can't fix is that the game text still displays "% less likely to revolt" rather than the actual "% to garrison effectiveness". That needs DLL editing to cover flipping between Revolutions and No Revolutions.

I think I'm missing the point; why shouldn't we just change the text? In the dll that text is only called once and it's already independent from the Revolution/No Revolutions choice...

Code:
    if (GC.getPromotionInfo(ePromotion).getRevoltProtection() != 0)
    {
        szBuffer.append(pcNewline);
        szBuffer.append(gDLL->getText("TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT", GC.getPromotionInfo(ePromotion).getRevoltProtection()));
    }

where TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT reads

Code:
        <Tag>TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT</Tag>
        <English>[ICON_BULLET]Garrisoned City %d1_percent%% less likely to Revolt</English>
 
I think I'm missing the point; why shouldn't we just change the text? In the dll that text is only called once and it's already independent from the Revolution/No Revolutions choice...

Code:
    if (GC.getPromotionInfo(ePromotion).getRevoltProtection() != 0)
    {
        szBuffer.append(pcNewline);
        szBuffer.append(gDLL->getText("TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT", GC.getPromotionInfo(ePromotion).getRevoltProtection()));
    }

where TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT reads

Code:
        <Tag>TXT_KEY_PROMOTION_REVOLT_PROTECTION_TEXT</Tag>
        <English>[ICON_BULLET]Garrisoned City %d1_percent%% less likely to Revolt</English>

The text works fine if Revolutions is off, and even if Revolutions is on, it should work if you're dealing with revolts triggered by cultural pressure from another civilization.
The problem is that revolt protection doesn't do anything for revolts triggered by Revolution other than increasing the stability bonus from the garrison. So I think that makes the current text a little misleading. I would prefer if the text could flip between the current text if No Revolutions is on and something along the lines of "Increases stability from garrison by X%" if No Revolutions is off.
 
I would prefer if the text could flip between the current text if No Revolutions is on and something along the lines of "Increases stability from garrison by X%" if No Revolutions is off.

Got it, it shouldn't be too difficult. I'm having a hard time very recently at home but I hope I can upload this change as well in my next update.
Happy new year everyone! :)
 
Mmm, this one has been harder than expected. It looks like adding an IF condition to check if Revoulitions is ON or OFF is causing problem with parsing xml promotion file. I'll see if I can find a workaround but I'm delaying this to another release.
 
Back
Top Bottom