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

Formula for City Combat Strength?

Discussion in 'Civ5 - General Discussions' started by dogfish44, Oct 19, 2014.

  1. dogfish44

    dogfish44 Chieftain

    Joined:
    Oct 19, 2014
    Messages:
    78
    Location:
    UK
    First of all, apologies in advance if this isn't the right place to ask this.

    I've been struggling to find much information on City Combat Strength - it's always vague "Hills increase" information.

    So, I'm asking for what the formula is to calculate Combat Strength of a City.

    Thanks in advance!
     
  2. joncnunn

    joncnunn Senior Java Wizard Moderator

    Joined:
    Mar 17, 2008
    Messages:
    8,621
    Location:
    Missouri
    I don't have the formula memorized, but here is the list of things affecting it.

    Walls, Castles, etc. boost both city hit points and it's strength.

    Population size is a factor.

    Presence of hills indeed increases that city's strength.

    In addition, the number of techs you have is also a factor.
     
  3. renton555

    renton555 Warlord

    Joined:
    Aug 9, 2011
    Messages:
    144
    I think more accurately its what era your civ is. In fact, I think the era is the biggest influence to the number.
     
  4. Vajrajina

    Vajrajina Chieftain

    Joined:
    Oct 7, 2014
    Messages:
    53
    Yupp. A newly founded Atomic era city starts with almost 100 strength.
     
  5. Makavcio

    Makavcio Prince

    Joined:
    Oct 1, 2010
    Messages:
    543
    Are you sure? I think you'd need some policies to reach 100 with only 1 pop.

    I must say that I'd love to see the exact formula. I know the general factors and I'm familiar with flat modifiers but around medieval era a few points more or less in city strength can make a huge difference.
     
  6. renton555

    renton555 Warlord

    Joined:
    Aug 9, 2011
    Messages:
    144
    I'm no expert but if I had to guess I'd say that the affectors, from most important to least important, are:

    1. era (unknown formula)
    2. terrain (apparently a +25% on top if hill, -10% on top if desert)
    3. defensive buildings (flat integer bonuses + hp based on buildings)
    4. garrison unit (unknown formula but probably easy to figure out)
    5. population (unknown formula)
     
  7. AW Arcaeca

    AW Arcaeca Deus Vult

    Joined:
    Mar 10, 2013
    Messages:
    2,969
    Gender:
    Male
    Location:
    Operation Padlock ground zero
    There's also a pantheon that effects it... Goddess of Protection, isn't it?

    Look man, I don't know if you know anything about C++ or not - I don't - but these segments from the base game coding seems to be relevant:
    Spoiler :
    Code:
    int CvCity::getStrengthValue(bool bForRangeStrike) const
    {
    	VALIDATE_OBJECT
    	// Strike strikes are weaker
    	if(bForRangeStrike)
    	{
    		int iValue = m_iStrengthValue;
    
    		iValue -= m_pCityBuildings->GetBuildingDefense();
    
    		CvAssertMsg(iValue > 0, "City strength should always be greater than zero. Please show Jon this and send your last 5 autosaves.");
    
    		iValue *= /*40*/ GC.getCITY_RANGED_ATTACK_STRENGTH_MULTIPLIER();
    		iValue /= 100;
    
    		if(GetGarrisonedUnit())
    		{
    			iValue *= (100 + GET_PLAYER(m_eOwner).GetGarrisonedCityRangeStrikeModifier());
    			iValue /= 100;
    		}
    
    		// Religion city strike mod
    		int iReligionCityStrikeMod = 0;
    		ReligionTypes eMajority = GetCityReligions()->GetReligiousMajority();
    		if(eMajority != NO_RELIGION)
    		{
    			const CvReligion* pReligion = GC.getGame().GetGameReligions()->GetReligion(eMajority, getOwner());
    			if(pReligion)
    			{
    				iReligionCityStrikeMod = pReligion->m_Beliefs.GetCityRangeStrikeModifier();
    				BeliefTypes eSecondaryPantheon = GetCityReligions()->GetSecondaryReligionPantheonBelief();
    				if (eSecondaryPantheon != NO_BELIEF)
    				{
    					iReligionCityStrikeMod += GC.GetGameBeliefs()->GetEntry(eSecondaryPantheon)->GetCityRangeStrikeModifier();
    				}
    				if(iReligionCityStrikeMod > 0)
    				{
    					iValue *= (100 + iReligionCityStrikeMod);
    					iValue /= 100;
    				}
    			}
    		}
    
    		return iValue;
    	}
    
    	return m_iStrengthValue;
    }
    Code:
    int CvCity::GetPower() const
    {
    	VALIDATE_OBJECT
    	return int(pow((double) getStrengthValue() / 100, 1.5));		// This is the same math used to calculate Unit Power in CvUnitEntry
    }
    Code:
    void CvCity::updateStrengthValue()
    {
    	VALIDATE_OBJECT
    	AI_PERF_FORMAT("City-AI-perf.csv", ("CvCity::updateStrengthValue, Turn %03d, %s, %s", GC.getGame().getElapsedGameTurns(), GetPlayer()->getCivilizationShortDescription(), getName().c_str()) );
    	// Default Strength
    	int iStrengthValue = /*600*/ GC.getCITY_STRENGTH_DEFAULT();
    
    	// Population mod
    	iStrengthValue += getPopulation() * /*25*/ GC.getCITY_STRENGTH_POPULATION_CHANGE();
    
    	// Building Defense
    	int iBuildingDefense = m_pCityBuildings->GetBuildingDefense();
    
    	iBuildingDefense *= (100 + m_pCityBuildings->GetBuildingDefenseMod());
    	iBuildingDefense /= 100;
    
    	iStrengthValue += iBuildingDefense;
    
    	// Garrisoned Unit
    	CvUnit* pGarrisonedUnit = GetGarrisonedUnit();
    	int iStrengthFromUnits = 0;
    	if(pGarrisonedUnit)
    	{
    		int iMaxHits = GC.getMAX_HIT_POINTS();
    		iStrengthFromUnits = pGarrisonedUnit->GetBaseCombatStrength() * 100 * (iMaxHits - pGarrisonedUnit->getDamage()) / iMaxHits;
    	}
    
    	iStrengthValue += ((iStrengthFromUnits * 100) / /*300*/ GC.getCITY_STRENGTH_UNIT_DIVISOR());
    
    	// Tech Progress increases City Strength
    	int iTechProgress = GET_TEAM(getTeam()).GetTeamTechs()->GetNumTechsKnown() * 100 / GC.getNumTechInfos();
    
    	// Want progress to be a value between 0 and 5
    	double fTechProgress = iTechProgress / 100.0 * /*5*/ GC.getCITY_STRENGTH_TECH_BASE();
    	double fTechExponent = /*2.0f*/ GC.getCITY_STRENGTH_TECH_EXPONENT();
    	int iTechMultiplier = /*2*/ GC.getCITY_STRENGTH_TECH_MULTIPLIER();
    
    	// The way all of this adds up...
    	// 25% of the way through the game provides an extra 3.12
    	// 50% of the way through the game provides an extra 12.50
    	// 75% of the way through the game provides an extra 28.12
    	// 100% of the way through the game provides an extra 50.00
    
    	double fTechMod = pow(fTechProgress, fTechExponent);
    	fTechMod *= iTechMultiplier;
    
    	fTechMod *= 100;	// Bring it back into hundreds
    	iStrengthValue += (int)(fTechMod + 0.005);	// Adding a small amount to prevent small fp accuracy differences from generating a different integer result on the Mac and PC. Assuming fTechMod is positive, round to nearest hundredth
    
    	int iStrengthMod = 0;
    
    	// Player-wide strength mod (Policies, etc.)
    	iStrengthMod += GET_PLAYER(getOwner()).GetCityStrengthMod();
    
    	// Apply Mod
    	iStrengthValue *= (100 + iStrengthMod);
    	iStrengthValue /= 100;
    
    	m_iStrengthValue = iStrengthValue;
    
    	// Terrain mod
    	if(plot()->isHills())
    	{
    		m_iStrengthValue += /*3*/ GC.getCITY_STRENGTH_HILL_CHANGE();
    	}
    
    	DLLUI->setDirty(CityInfo_DIRTY_BIT, true);
    }
     
  8. joncnunn

    joncnunn Senior Java Wizard Moderator

    Joined:
    Mar 17, 2008
    Messages:
    8,621
    Location:
    Missouri
    The code post above confirms it's number of techs and NOT which era you are in that determines the point scale.
    However, if the comments are up to date with the code, the boost from tech is slow when you don't have many but is rapid in end game.

    Hills bonus is a FLAT strength bonus, NOT percentage. If the comment is up to date with the code, it's 3.
     
  9. renton555

    renton555 Warlord

    Joined:
    Aug 9, 2011
    Messages:
    144
    If I'm reading that correctly it's pretty close to "by era" because the eras subdivide the tech tree into 1/8 portions (i think?) and each two eras is 25% of the tech tree so it looks like your cities get a huge bump in combat strength roughly once you are in the medieval, industrial, and atomic eras respectively (and again technically once you have researched all techs, i suppose). I guess what I mean is that its easy to mistake it for era in common observation.
     
  10. joncnunn

    joncnunn Senior Java Wizard Moderator

    Joined:
    Mar 17, 2008
    Messages:
    8,621
    Location:
    Missouri
    If you were to actually enter every era via completing the last one, then it would line up.

    But best practice is to enter Modern Era super early via using Oxford for Radio.

    Rean & Industrial eras are also popular to enter early (to allow Rationalism in the first case and in the second to avoid an unwanted Great Prophet)

    When not going Science, Info era is also entered super early via bypassing most of the Atomic Era techs. (Going Science, it's not as popular with the last techs needed spread out more)
     
  11. dogfish44

    dogfish44 Chieftain

    Joined:
    Oct 19, 2014
    Messages:
    78
    Location:
    UK
    Ah, excellent, thanks for digging this up ^_^
     
  12. kc123

    kc123 Chieftain

    Joined:
    Oct 25, 2014
    Messages:
    3
    Location:
    Connecticut, US
    I'm not a coding expert either, but I do know that the Kremlin plays a big role. If I'm not mistaken, it provides 12 defense in the city where it was built and increases the strength of defensive buildings by 25%, in all cities.
     

Share This Page