Possible fix for overly large REF

HG_CassiusA

Hallowed are the Ori
Joined
Nov 27, 2005
Messages
119
Location
Edmonton, Alberta, Canada
Try changing the values for

Code:
	<Define>
		<DefineName>REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE</DefineName>
		<iDefineIntVal>10</iDefineIntVal>
	</Define>
	<Define>
		<DefineName>REVOLUTION_EUROPE_UNIT_THRESHOLD</DefineName>
		<iDefineIntVal>75</iDefineIntVal>
	</Define>
	<Define>
		<DefineName>REVOLUTION_EUROPE_UNIT_SHIP_MODIFIER</DefineName>
		<iDefineIntVal>-50</iDefineIntVal>
	</Define>

in GlobalDefines.xml

I'm not sure what reasonable values would be though, but I think using any smaller number would reduce the problem.
 
Increasing "iAIKingUnitThresholdPercent" in CIV4HandicapInfo.xml seems to work nicely as well.
 
seems like the REF is linked with:
- gamespeed modifier
- starting age modifier
- <iAITrainPercent> modifier (doesn't make sense)
- AI gets a small bonus (<iAIKingUnitThresholdPercent>)
- REVOLUTION_EUROPE_UNIT_THRESHOLD constant
- REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE constant (= % of how more more bells i can produce compared to last time, before kings gets new unit. should scale with difficulty or?)
 
We need to look at the C++ specifically ... dr_A, the area you posted in the other thread, can you post the rest of that function, if it seems relevant?
 
Can those values be moved to the difficulty setting file, or will that make things go boom?

Edit: Also, keep in mind that while <iAIKingUnitThresholdPercent> is an AI-specific function, the European powers are AI powers, and thus the REF would only apply to AI opponents. The question is how the rest of the function that was found within would look.
 
You can't specifically move things around like that, without modding it in the dll (in c++).

The section dr_A found was specifically for AI *players*, I think (without seeing the rest of the function I can't be sure of that, but it sure looked that way). I think this is probably very much more complicated than just changing one number, unfortunately.
 
<iAIKingUnitThresholdPercent> is for not human

CvPlayer::doBells()
Code:
int CvPlayer::revolutionEuropeUnitThreshold() const
{
	int iThreshold = ((GC.getDefineINT("REVOLUTION_EUROPE_UNIT_THRESHOLD") * std::max(0, (getRevolutionEuropeUnitThresholdMultiplier()))) / 100);

	iThreshold *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent();
	iThreshold /= 100;

	iThreshold *= GC.getEraInfo(GC.getGameINLINE().getStartEra()).getTrainPercent();
	iThreshold /= 100;

	iThreshold *= GC.getHandicapInfo(getHandicapType()).getAITrainPercent();
	iThreshold /= 100;

	if (!isHuman())
	{
		iThreshold *= GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIKingUnitThresholdPercent();
		iThreshold /= 100;
	}

	return std::max(1, iThreshold);
}

CvPlayer::revolutionEuropeUnitThreshold()
Code:
void CvPlayer::doBells()
{
    if (getParent() == NO_PLAYER)
	{
		return;
	}

	int iBellsRate = getYieldRate(YIELD_BELLS);
	if (iBellsRate == 0)
	{
		return;
	}
	//add bells to political points
	for (int i = 0; i < GC.getNumFatherPointInfos(); ++i)
	{
		FatherPointTypes ePointType = (FatherPointTypes) i;
		changeFatherPoints(ePointType, iBellsRate * GC.getFatherPointInfo(ePointType).getYieldPoints(YIELD_BELLS));
	}

	//update revolution unit bells
	if (!isInRevolution())
	{
		changeBellsStored(iBellsRate);
		if (getBellsStored() >= revolutionEuropeUnitThreshold() && iBellsRate > GC.getCivilizationInfo(getCivilizationType()).getFreeYields(YIELD_BELLS))
		{
			changeBellsStored(-revolutionEuropeUnitThreshold());
			setRevolutionEuropeUnitThresholdMultiplier((getRevolutionEuropeUnitThresholdMultiplier() * (100 + GC.getDefineINT("REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE"))) / 100);

			if (NO_PLAYER != getParent())
			{
				CvPlayer& kParent = GET_PLAYER(getParent());
				FAssert(kParent.isEurope());

				CvCivilizationInfo& kCivilizationInfo = GC.getCivilizationInfo(kParent.getCivilizationType());
				int iNumFreeUnits = kCivilizationInfo.getNumCivilizationFreeUnits();
				std::vector<int> aiUnitWeights(iNumFreeUnits, 100);
				for (int i = 0; i < iNumFreeUnits; ++i)
				{
					int iUnitClass = kCivilizationInfo.getCivilizationFreeUnitsClass(i);
					UnitTypes eUnit = (UnitTypes) kCivilizationInfo.getCivilizationUnits(iUnitClass);
					if (eUnit == NO_UNIT)
					{
						aiUnitWeights[i] = 0;
					}
					else
					{
						if (GC.getUnitInfo(eUnit).getDomainType() == DOMAIN_SEA)
						{
							aiUnitWeights[i] += std::max(-100, GC.getDefineINT("REVOLUTION_EUROPE_UNIT_SHIP_MODIFIER"));
						}
					}					
				}

				if (iNumFreeUnits > 0)
				{
					int iIndex = GC.getGameINLINE().getSorenRand().pickValue(aiUnitWeights, "Pick Expeditionary force unit");
					int iUnitClass = kCivilizationInfo.getCivilizationFreeUnitsClass(iIndex);
					ProfessionTypes eUnitProfession = (ProfessionTypes) kCivilizationInfo.getCivilizationFreeUnitsProfession(iIndex);
					UnitTypes eUnit = (UnitTypes)kCivilizationInfo.getCivilizationUnits(iUnitClass);
					FAssert(eUnit != NO_UNIT);
					int iNumUnits = std::max(1, getRevolutionEuropeUnitThresholdMultiplier() / 100);
					for (int i = 0; i < iNumUnits; ++i)
					{
						addRevolutionEuropeUnit(eUnit, eUnitProfession);
					}

					const wchar* szUnitName;
					if (eUnitProfession != NO_PROFESSION)
					{
						szUnitName = GC.getProfessionInfo(eUnitProfession).getTextKeyWide();
					}
					else
					{
						szUnitName = GC.getUnitInfo(eUnit).getTextKeyWide();
					}

					CvWString szBuffer = gDLL->getText("TXT_KEY_NEW_EUROPE_ARMY", kParent.getCivilizationShortDescriptionKey(), getCivilizationShortDescriptionKey(), szUnitName, kParent.getCivilizationAdjectiveKey());
					gDLL->getInterfaceIFace()->addMessage(getID(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_UNIT_GREATPEOPLE", MESSAGE_TYPE_INFO, GC.getUnitInfo(eUnit).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_UNIT_TEXT"));
				}
			}
		}
	}
}

does anyone know how to make a debug msg appear onscreen in Col2? would help a lot^^
 
Now I remember why I never got into modding... if I want to WORK, I'll WORK on my own stuff. :)

But, looks like it does come down to the "REVOLUTION_EUROPE_UNIT_THRESHOLD" as your initial bells, which is then multiplied by "REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE" every time it trips. Sadly, this is a constant across ALL levels of difficulty. So, by default, it's 75 bells, then 84, then 92, then 101, etc...

So there's the problem. The multiplier is far, far too low, since your own liberty bell multipliers (from, say, the Printing Press) are likely to be over DOUBLE the threshold required (much less if you have Newspapers, etc). Very quickly, you can actually outpace the King's threshold.

The 75 to start seems fine, but the "REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE" really needs to change (and also be dependant on difficulty level). It should probably be much higher, perhaps 50 or so, to start with.

Unfortunately, I'm still stealing minutes. Can anyone check if this value can be dropped from 'global' and moved to the difficulty XML? If it can, this would do wonders for the game all by itself.
 
TFVanguard, you said that when you tried changing iAIKingUnitThresholdPercent you saw a difference, right?

If that's an AI value, why would that be?

Is it possible there's a bug causing that variable to be applied to Players on top of their own modifiers, which could be responsible for the large REFs?
 
Unfortunately, I'm still stealing minutes. Can anyone check if this value can be dropped from 'global' and moved to the difficulty XML? If it can, this would do wonders for the game all by itself.

maybe i can rig <iAIKingUnitThresholdPercent> and use it as REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE. has no purpose anyway.
i just getting the stuff for compiling a .dll.
you can think of fitting multipliers^^
 
TFVanguard, you said that when you tried changing iAIKingUnitThresholdPercent you saw a difference, right?

If that's an AI value, why would that be?

Is it possible there's a bug causing that variable to be applied to Players on top of their own modifiers, which could be responsible for the large REFs?

Well, there's a possibility that it's running it all down TWICE, one for England itself, then boosting it again when hitting your colony. That is, it's winding up doubling over these routines because when running colonies, it checks the parent - then it actually DOES the parent (which is an AI player). So, this'll hit the routine once regardless of if it was supposed to.
 
something must be wrong. with REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE=1000 the kings buys tons of cavallery or artillery, but like no soldiers.
 
I don't think using iAIKingUnitThreshold is a good idea - it has a purpose. If we're changing something in the DLL, just add that tag to the Handicap XML file REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE and REVOLUTION_EUROPE_UNIT_THRESHOLD. It's cleaner and better to do it that way.

dr_AllCOM3, if you can figure out the best numbers for each I'll get it into the XML file in my patch-mod this week/weekend and we can go from there.
 
Its the 'REVOLUTION_EUROPE_UNIT_THRESHOLD' value the one you have to change NOT the 'REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE'.

For example if you set the value to 'REVOLUTION_EUROPE_UNIT_THRESHOLD' to 1000, you will see theres almost no REF grow. From what I understand the 'REVOLUTION_EUROPE_UNIT_THRESHOLD' variable works with REF something like this (taking 1000 for example and being simplistic):

Each turn you generate bells, each time you accumulate 1000 bells the king adds a unit to the REF. Of course there are some variables and percentages that are multiplied to that 1000, but from what I could see the base is that value.

That means that the more the value the less the REF grow.

I just finished a game on Pilgrim with the value set on 150 and won. The REF was pretty easy. Of course I didnt build any bells until turn 175 and rushed for 50%. But I think 150 its a good place to start.
 
REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE also increases the amout of troops the king will get.
i modded the .dll, now i can see the numbers ingame.
 
REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE also increases the amout of troops the king will get.
i modded the .dll, now i can see the numbers ingame.
Yes, REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE only matters at the very start, until you'll get about 4*ln(2; REVOLUTION_EUROPE_UNIT_THRESHOLD_INCREASE) increases in a number of REF units. After that it doesn't really matter. Only REVOLUTION_EUROPE_UNIT_THRESHOLD does matter.

I think the bigger problem is that REF increases linearly with a number of produced bells. At the same time, each turn you lose 10% of your accumulated bells in each city. I think it's much better to count total accumulated bells towards REF (sum of CvCity::getRebelSentiment()) instead of total produced bells. As it is now, most founding fathers give you PENALTIES instead of bonuses as their benefits don't seem to outweight the increase in REF :crazyeye:
 
no, REF would stop then at some point and you could outbuild them.
If you have a bigger total population then you need more rebel sentiment in cities so to declare a revolution. So, all your soldiers will also increase a REF army. If you use CvCity::getRebelSentiment() then REVOLUTION_EUROPE_UNIT_THRESHOLD defines the ratio between your total population and a number of units in a REF army. So, it's possible to balance it across different difficulty levels. As it is now, you can't balance REVOLUTION_EUROPE_UNIT_THRESHOLD for both higher and lower difficulties - playstyle affects REF significantly more than that variable, and players shouldn't be punished for their playstyle on lowest difficulties.
 
That just opens a MASSIVE exploit in that you keep a mass of units as colonists/pioneers/soldiers that are never counted in the REF calculation.

Once your colonies reach 100% sentiment the threshold will plateau. Thats the extreme the other way cuz the player can have a small colony population with colonies of 100% but massive outside colony population, whilst the King has a tiny REF in relation to the tiny population.

Unless I'm missing something I don't see that working.
 
That just opens a MASSIVE exploit in that you keep a mass of units as colonists/pioneers/soldiers that are never counted in the REF calculation.

Once your colonies reach 100% sentiment the threshold will plateau. Thats the extreme the other way cuz the player can have a small colony population with colonies of 100% but massive outside colony population, whilst the King has a tiny REF in relation to the tiny population.

Unless I'm missing something I don't see that working.
If it worked that way, then it should have been exploitable in the original Col2.

CvTeam::canDoRevolution(), CvTeam::getRebelPercent(), CvTeam::getTotalPopulation(), CvUnit::changeTotalPopulation(), CvUnit::updateOwnerCache()

Every unit that can found a city, including soldiers, counts in getTotalPopulation() and so in canDoRevolution() too. So, if you have 40 colonists/pioneers/soldiers and 10 citizens, you'll have 20% rebel sentiment at best. Cannons aren't counted, but that is true for an original Col2 too. Also, we may mod it to include cannons as well if nessesary.
 
Back
Top Bottom