What factors affect a unit's contribution to city defense?

From what I've read, a unit garrisoned in a city has precisely one effect: the city's combat score is increased by a fraction of the unit's Strength (I've seen "1/3" and "1/5"). Its hitpoints are not increased, so rushing a military unit into a city that's about to fall is usually a waste of a unit.

Does anything else affect this? Are there promotions which make a unit more or less suitable as a garrison? Does a unit's presence in a city trigger attackers' bonuses or penalties against certain types of units (e.g., does a Pikeman get a bonus attacking a city garrisoned by a cavalry unit)?

A unit in a city can still attack, and then of course all the normal modifiers come into play. I'm only interested in defending a city at the moment.


Attack bonuses against units do not apply when attacking cities. The strength a unit adds varies mainly depending on it's own strength and current hp, and whether you have Oligarchy or not.

As for the strength formula, I looked at the code and this seems relevant: http://pastebin.com/3nCiC3Qv

Looks like city strength depends on the following:

  1. Number of techs
  2. Terrain
  3. Defensive buildings
  4. Garrison unit
  5. Population
  6. Religion

Specifically, the part concerning units:

    // 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());

So the formula for the strength a unit adds seems to be (Unit Combat Strength * 100) * Current Unit HP / Maximum Unit HP. This value is then apparently multiplied by 100 and divided by CITY_STRENGTH_UNIT_DIVISOR (which is 500 according to GlobalDefines.xml). Then in

    iValue *= /*40*/ GC.getCITY_RANGED_ATTACK_STRENGTH_MULTIPLIER();
    iValue /= 100;

it is multiplied by CITY_RANGED_ATTACK_STRENGTH_MULTIPLIER (which is 75 according to GlobalDefines.xml) and divided by 100.

Finally, in

            if(GetGarrisonedUnit())
            {
                    iValue *= (100 + GET_PLAYER(m_eOwner).GetGarrisonedCityRangeStrikeModifier());
                    iValue /= 100;
            }

it is multiplied by 100 + GetGarrisonedCityRangeStrikeModifier (which seems to be 0 normally and 100 with Oligarchy according to CIV5Policies.xml) and divided by 100 again.