Leon Marrick
Chieftain
- Joined
- Jun 27, 2002
- Messages
- 6
Fine Control of Movement and Hitpoints in Civ II: A Mathematical Explanation
Although still a fairly obscure technique, fractional movement (units that move 1 and 1/3 squares per turn) is known to several scenario designers. The best claim of first invention probably goes to William Keenan, and you may see such units in action in the excellent scenario "Imperium Romanum" by Bernd Brosling. The purpose of this essay is to explain this technique mathematically - and explain some other curious facts along the way.
New to the Civilization Fanatics website is the equally fine scenario "Imperialism 1870" by Phenix Benton. In his readme, he remarks that he was prevented from raising the road movement multiplier past seven by the limitations higher numbers would have placed on ship movement.
Last night I sat down with a pen and a scratch pad, and did some calculations. It turns out that Civ2 stores unit moves remaining in a signed byte value; such values go from 0 to 127. The internal value for moves remaining is not the number of grassland or ocean squares which a unit may cross, but the number of road squares. Therefore, you may figure the maximum movement rate of any unit by dividing 127 by the road movement multiplier, discarding any remainder. If it is three, no unit may move faster than 42 grassland/ocean squares. If it is seven, no unit may move faster than 18.
What happens when you try to exceed this value? To reiterate: moves are stored in a signed byte. Bytes store 256 possible values; signed bytes assign the first half to positive and the second half to negative values. Feed a number between 128 and 256 to a signed byte, and you get a negative value - which is the same in this context as zero. The unit does not move (at least, it does not move when at full strength).
OK. What happens when you feed in a value greater than 256? You get fractional movement.
Example: You have a road movement multiplier of 3. You edit rules.txt to give settlers a movement of 87. Doing so gives that unit 87 * 3 = 261 road movement points. This number is greater than 256, so you divide 261 by 256, and take the remainder: 5. This remainder is less than or equal to 127, so your unit will actually move. Because 5 divided by 3 is 1 2/3, your settler will get 1 2/3 moves per turn.
But what you really want is to be able to calculate in the opposite direction: to start with a desired movement, and calculate the number to insert in rules.txt.
Example: You have a road multiplier of 3. You want settlers to get precisely 1 and 1/3 moves per turn. If a remainder of 5 gets you 5/3rds or 1 and 2/3 moves, a remainder of 4 must get you 4/3rds or 1 and 1/3. We need to find some number that, when divided by 256, will yield a remainder of 4. Because you cannot enter fractional values in rules.txt, and our road movement multiplier is three, the number we are looking for must also be divisible by three. A simple-minded guy like me will just run down the list: (256 * 1) + 4 = 260. 260 is not divisible by 3. (256 * 2) + 4 = 516. 516 is divisible by 3. The answer is 516. Again to reiterate: this value is the number of road-connected squares a unit may move. Because the road movement multiplier is three, we divide 516 by 3 and get 172.
Check this out using your own rules.txt: If the road multiplier is three, and you give any unit a movement of 172, it will move 1 and 1/3 squares per turn.
Just for drill, we'll run through one more example: You have a road multiplier of seven. You want settlers to get 1 and 2/7 moves per turn. 1 and 2/7ths is the same as 9/7ths, so we're looking for a remainder of 9. (256 * 1) + 9 = 265. 265 is not divisible by 7. (256 * 2) + 9 = 521. 521 is not divisible by 7. (256 * 3) + 9 = 777. 777 is divisible by 7. The answer is 777. Divide 777 by the road multiplier of 7, and you get 111. If the road multiplier is seven, and you give any unit a movement of 111, it will move 1 and 2/7 squares per turn.
Fractional movement should now be clear enough. What none to my knowledge has discovered yet is that /hitpoints/ may also be precisely controlled! Because the internal value for hitpoints is usually ten times that shown in rules.txt, you apply a multiplier of 10, and calculate normally. One caveat: Unlike the case when using 3 or 7, you cannot get certain values when using 10. To be precise, you are allowed only even-numbered hitpoints (20, 22, 24, etc.) and not odd-numbered ones (you can't have a unit that starts out with 15 hitpoints).
If we can have fractional movement and fractional hitpoints, can we have fractional shield costs? No. The cost of a unit or structure is the number of shield rows, each of which normally have 10 shields. If you want one unit to cost 5 shields and another to cost 10, you would set the cost of the first to 1, that of the second to 2, and make shield rows contain 5 shields each.
And a last word: when using either fractional movement or hitpoints, the Civ2 unit information displays some very odd (often negative) numbers. Help players by explaining what is going on in your readme file.
Although still a fairly obscure technique, fractional movement (units that move 1 and 1/3 squares per turn) is known to several scenario designers. The best claim of first invention probably goes to William Keenan, and you may see such units in action in the excellent scenario "Imperium Romanum" by Bernd Brosling. The purpose of this essay is to explain this technique mathematically - and explain some other curious facts along the way.
New to the Civilization Fanatics website is the equally fine scenario "Imperialism 1870" by Phenix Benton. In his readme, he remarks that he was prevented from raising the road movement multiplier past seven by the limitations higher numbers would have placed on ship movement.
Last night I sat down with a pen and a scratch pad, and did some calculations. It turns out that Civ2 stores unit moves remaining in a signed byte value; such values go from 0 to 127. The internal value for moves remaining is not the number of grassland or ocean squares which a unit may cross, but the number of road squares. Therefore, you may figure the maximum movement rate of any unit by dividing 127 by the road movement multiplier, discarding any remainder. If it is three, no unit may move faster than 42 grassland/ocean squares. If it is seven, no unit may move faster than 18.
What happens when you try to exceed this value? To reiterate: moves are stored in a signed byte. Bytes store 256 possible values; signed bytes assign the first half to positive and the second half to negative values. Feed a number between 128 and 256 to a signed byte, and you get a negative value - which is the same in this context as zero. The unit does not move (at least, it does not move when at full strength).
OK. What happens when you feed in a value greater than 256? You get fractional movement.
Example: You have a road movement multiplier of 3. You edit rules.txt to give settlers a movement of 87. Doing so gives that unit 87 * 3 = 261 road movement points. This number is greater than 256, so you divide 261 by 256, and take the remainder: 5. This remainder is less than or equal to 127, so your unit will actually move. Because 5 divided by 3 is 1 2/3, your settler will get 1 2/3 moves per turn.
But what you really want is to be able to calculate in the opposite direction: to start with a desired movement, and calculate the number to insert in rules.txt.
Example: You have a road multiplier of 3. You want settlers to get precisely 1 and 1/3 moves per turn. If a remainder of 5 gets you 5/3rds or 1 and 2/3 moves, a remainder of 4 must get you 4/3rds or 1 and 1/3. We need to find some number that, when divided by 256, will yield a remainder of 4. Because you cannot enter fractional values in rules.txt, and our road movement multiplier is three, the number we are looking for must also be divisible by three. A simple-minded guy like me will just run down the list: (256 * 1) + 4 = 260. 260 is not divisible by 3. (256 * 2) + 4 = 516. 516 is divisible by 3. The answer is 516. Again to reiterate: this value is the number of road-connected squares a unit may move. Because the road movement multiplier is three, we divide 516 by 3 and get 172.
Check this out using your own rules.txt: If the road multiplier is three, and you give any unit a movement of 172, it will move 1 and 1/3 squares per turn.
Just for drill, we'll run through one more example: You have a road multiplier of seven. You want settlers to get 1 and 2/7 moves per turn. 1 and 2/7ths is the same as 9/7ths, so we're looking for a remainder of 9. (256 * 1) + 9 = 265. 265 is not divisible by 7. (256 * 2) + 9 = 521. 521 is not divisible by 7. (256 * 3) + 9 = 777. 777 is divisible by 7. The answer is 777. Divide 777 by the road multiplier of 7, and you get 111. If the road multiplier is seven, and you give any unit a movement of 111, it will move 1 and 2/7 squares per turn.
Fractional movement should now be clear enough. What none to my knowledge has discovered yet is that /hitpoints/ may also be precisely controlled! Because the internal value for hitpoints is usually ten times that shown in rules.txt, you apply a multiplier of 10, and calculate normally. One caveat: Unlike the case when using 3 or 7, you cannot get certain values when using 10. To be precise, you are allowed only even-numbered hitpoints (20, 22, 24, etc.) and not odd-numbered ones (you can't have a unit that starts out with 15 hitpoints).
If we can have fractional movement and fractional hitpoints, can we have fractional shield costs? No. The cost of a unit or structure is the number of shield rows, each of which normally have 10 shields. If you want one unit to cost 5 shields and another to cost 10, you would set the cost of the first to 1, that of the second to 2, and make shield rows contain 5 shields each.
And a last word: when using either fractional movement or hitpoints, the Civ2 unit information displays some very odd (often negative) numbers. Help players by explaining what is going on in your readme file.