• Civilization 7 has been announced. For more info please check the forum here .

Prof. Garfield

Mar 6, 2004
I recently needed to find the calculation for a damaged unit's movement allowance for an event I want to write for a TOTPP with Lua scenario.

https://www.civfanatics.com/civ2/strategy/combatguide/#basics was the only thing I could find, and that is only good when the road multiplier is 3.

After some investigation, I believe I have found the correct calculation.

h=remaining hitpoints for unit
H=total hitpoints for unit
M = total movement points for unit (multiplied by the road multiplier. I.e. in standard game horsemen have M=6)
m = remaining movement points for unit (multiplied by the road multiplier)
r = road multiplier (in TOTPP, this is the "aggregate" multiplier, i.e. the LCM of road,rail, and alpine)
a % b is the "modulo" operator. That is divide a by b and take the remainder


m* = floor(hM/H)
if m* % r > 0 then m**=m*-m*%r+r
otherwise, m**=m*

If air unit, m = M
If sea unit, m = max(2*r,m**) [unless M=0 or r]
If land unit, m=max(r,m**) [unless M = 0]

Basically, the unit's percent of total movement is its percent of total hp, rounding down for the division. Then, if the unit's movement allowance is not a multiple of the road multiplier (i.e. the "in game" movement would show a fraction movement allotment on a unit that hasn't moved), the movement allowance is increased to the next multiple of the road multiplier.

My research has been done in Test of Time, though I'm pretty sure it holds for Classic/MGE as well. I'm fairly confident in my result, because it seems like the easiest way to program the functionality we observe (i.e. movement allowance is in "whole units," and proportional to remaining HP), but I couldn't figure out a way to automate the test with Lua.

Here's the code for the calculation
-- returns movement allowance for a unit, multiplied by the road/rail multiplier
function maxMoves(unit)
    local moveAllowance = (unit.hitpoints*unit.type.move)//unit.type.hitpoints
    local moveMult = totpp.movementMultipliers.aggregate
    if moveAllowance % moveMult > 0 then
        moveAllowance = moveAllowance - moveAllowance % moveMult + moveMult
    if unit.type.domain == 0 then
        return math.min(math.max( moveAllowance,moveMult),unit.type.move)
    elseif unit.type.domain == 1 then
        return unit.type.move
    elseif unit.type.domain == 2 then
        return math.min(math.max( moveAllowance,2*moveMult),unit.type.move)

Top Bottom