Solving the mystery: Unit Maintenance

Status
Not open for further replies.
The costs should scale with number of cities. Small empires are really out of luck with trying to defend themselves.
 
That seems to work well, and fits the XML variables.
I think we have a winner!

Yes, I tried to work them in. Don't ask me where the factor 2 in the exponent is coming from, though. An easy test to verify if the function works indeed is to modify the xml values, do a test run, and compare with the new values plugged into that function.

I would run some tests myself but my CPU is currently occupied with physics :lol:
 
The costs should scale with number of cities. Small empires are really out of luck with trying to defend themselves.
So a small empire should be able to maintain 10 units cheaper than a big empire? No way!

Don't ask me where the factor 2 in the exponent is coming from
Yeah, unclear why they couldn't remove it and just set the UNIT_MAINTENANCE_GAME_EXPONENT_DIVISOR to 3.5.
 
So a small empire should be able to maintain 10 units cheaper than a big empire? No way!

Not that many. Even an OCC should be able to handle 3-5 defensive units and not have ridiculous costs, especially when one has to defend from land and sea incursions.
 
Ok, the formula holds. I made a mod setting 8 -> 1000 and 7 -> 1 and at turn 10 I got a maintenance of 22 with 2 units. If the exponent divisor were still 7, I'd have had to pay only 21, and the dependence on n also fit the multiplier part of the function, so I'd consider the mystery solved ;)

The final formula is

c(t,n) = ((j/100 + m/1000 t) round(n,2))^(1 + 2/(1000*d) t)

where j = INITIAL_GOLD_PER_UNIT_TIMES_100, m = UNIT_MAINTENANCE_GAME_MULTIPLIER, d = UNIT_MAINTENANCE_GAME_EXPONENT_DIVISOR, n = number of units, t = number of turns

The round function is meant to round to the next multiple of 2 as fits the data.
 
Not that many. Even an OCC should be able to handle 3-5 defensive units and not have ridiculous costs, especially when one has to defend from land and sea incursions.

You're missing the point; why should a small empire be able to maintain X units, whatever X is, at lower cost than a large empire pays for those same X units?
 
Thinking about it, I don't actually have a good answer for that. Forget about it.
 
Ok, the formula holds. I made a mod setting 8 -> 1000 and 7 -> 1 and at turn 10 I got a maintenance of 22 with 2 units. If the exponent divisor were still 7, I'd have had to pay only 21, and the dependence on n also fit the multiplier part of the function, so I'd consider the mystery solved ;)

The final formula is

c(t,n) = ((j/100 + m/1000 t) round(n,2))^(1 + 2/(1000*d) t)

where j = INITIAL_GOLD_PER_UNIT_TIMES_100, m = UNIT_MAINTENANCE_GAME_MULTIPLIER, d = UNIT_MAINTENANCE_GAME_EXPONENT_DIVISOR, n = number of units, t = number of turns

The round function is meant to round to the next multiple of 2 as fits the data.

You're really good at this aren't you? I had a bastardized formula but yours is a perfect fit with my own data samples I gathered independently.

There is a slight error in the formula however. When I was playing with INITIAL_GOLD_PER_UNIT_TIMES_100, it would multiply the entire maintenance cost whereas the current form only affects the initial cost. Aka if I put in 50000 for that value it should read 500 cost for turn 0, and 508 for turn 1. As it is this does 500, then 500.00008.

Doing:

c(t,n) = (j/100)((0.5 + m/1000 t) round(n,2))^(1 + 2/(1000*d) t)

would fit my data though I'm a bit stumped why it needs an extra 0.5 in there.

Also the rounding to the next 2 doesn't seem entirely explicit. I could make the rounding go away by using big enough multipliers. Fortunately the next patch should allow us to do away with that part of the formula.
 
You're really good at this aren't you? I had a bastardized formula but yours is a perfect fit with my own data samples I gathered independently.

There is a slight error in the formula however. When I was playing with INITIAL_GOLD_PER_UNIT_TIMES_100, it would multiply the entire maintenance cost whereas the current form only affects the initial cost. Aka if I put in 50000 for that value it should read 500 cost for turn 0, and 508 for turn 1. As it is this does 500, then 500.00008.

Doing:

c(t,n) = (j/100)((0.5 + m/1000 t) round(n,2))^(1 + 2/(1000*d) t)

would fit my data though I'm a bit stumped why it needs an extra 0.5 in there.

Also the rounding to the next 2 doesn't seem entirely explicit. I could make the rounding go away by using big enough multipliers. Fortunately the next patch should allow us to do away with that part of the formula.

I'm not bad, thanks for the compliment. The info you posted is very relevant, and once again shows me that assumptions are often misleading :lol:

I did some more in-game tests, this time modifying j, too, and my new formula is:

c(t,n) = ((j n)//100 (1 + 2t m/1000))^(1 + 2t/(1000*d))

Where // denotes an integer division

This formula explains your observation that j is multiplied on everything, should fit your data, and as a corollary also explains where the rounding issue comes from: It is a result of the integer division of INITIAL_GOLD_PER_UNIT_TIMES_100 times n by 100. This formula yields the same results as yours for the relevant cases, by the way, but also works for cases of j different than k*100 + 50 ;)

Another nice thing about this formula is the symmetry of the factor two in both the time-dependencies of the exponent and the base, hinting to a possible error where the turn number is multiplied by 2 by accident.

Edit: I haven't checked yet if j//100 should be in the bracket with n or outside of it, that's why one side is missing :P

Edit2: Ok, the j belongs into the bracket. It's possible the integer division is done with the whole base but I'm running out of time to check, so if anybody feels like checking, be my guest.
 
I'm not bad, thanks for the compliment. The info you posted is very relevant, and once again shows me that assumptions are often misleading :lol:

I did some more in-game tests, this time modifying j, too, and my new formula is:

c(t,n) = (j//100 n (1 + 2t m/1000))^(1 + 2t/(1000*d))

Where // denotes an integer division

This formula explains your observation that j is multiplied on everything, should fit your data, and as a corollary also explains where the rounding issue comes from: It is a result of the integer division of INITIAL_GOLD_PER_UNIT_TIMES_100 by 100. This formula yields the same results as yours for the relevant cases, by the way, but also works for cases of j different than k*100 + 50 ;)

Another nice thing about this formula is the symmetry of the factor two in both the time-dependencies of the exponent and the base, hinting to a possible error where the turn number is multiplied by 2 by accident.

Edit: I haven't checked yet if j//100 should be in the bracket with n or outside of it, that's why one side is missing :P

Edit2: Ok, the j belongs into the bracket

annoying, unit hammer cost/100 would be MUCH better
 
annoying, unit hammer cost/100 would be MUCH better

I actually liked the proposition to give each unit a fixed maintenance that is shown nicely visible on the UI. It's easier to understand, you can make decisions more easily about how much a unit will cost you, and you can use it to balance certain units. Mounted units, for example, should be more expensive because supplying them with horses is a non-trivial issue (and because they were mostly nobles).
 
I guess they might be worried about exploits where you can keep a huge army of old units and a large gold reserve, in case you need to suddenly upgrade them, without actually having to pay the maintenance costs of the later units.

Similarly, the human might be significantly better at exploiting this kind of mechanic.
 
I guess they might be worried about exploits where you can keep a huge army of old units and a large gold reserve, in case you need to suddenly upgrade them, without actually having to pay the maintenance costs of the later units.

Similarly, the human might be significantly better at exploiting this kind of mechanic.

Well, that's why I would probably modify it so that the cost of an obsolete unit was based on the end unit it upgraded to. (ie once you have steel, Warriors would cost what Longswordsmen do))

(and the human can already exploit the "build/buy older unit then upgrade it as opposed to build/buy the current unit." provides a great way to tourn Gold into hammers)
 
I guess they might be worried about exploits where you can keep a huge army of old units and a large gold reserve, in case you need to suddenly upgrade them, without actually having to pay the maintenance costs of the later units.

Similarly, the human might be significantly better at exploiting this kind of mechanic.

I don't see the difference between that and keeping a large gold reserve to buy new units in an emergency, and that's already in the game. The problem with that is that the AI is more likely to attack you if you have a weak army, but sometimes this is exactly what you intend.

Blocking could be a more relevant problem, but frankly: Who cares? Blocking isn't as useful as people make it out to be as long as units cost at least one or two gold. You could still have an inflation mechanism, too, with an inflation rate that's displayed in the UI (economics overview) and that can be even used for game design.
 
I don't see the difference between that and keeping a large gold reserve to buy new units in an emergency, and that's already in the game. The problem with that is that the AI is more likely to attack you if you have a weak army, but sometimes this is exactly what you intend.

Well, that is the reason, why human sometimes need to have standing army, instead of buying it in last minute.
 
Status
Not open for further replies.
Back
Top Bottom