Re: Unit Upkeep Modifications
About income updating immediately… yes, in vanilla, it does. I also agree that it would be great if C2C did the same. But since updating other things mid turn that affect game play (build queue options like national units) is both difficult and low priority, I assumed that updates only affecting displayed values but not impacting gameplay would still be difficult and even lower priority. I have no problem with accurate information being displayed to the player, and encourage anyone that wants to tackle more frequent updates that don’t impact the application’s speed/memory/responsiveness to please go forward with that. But, I will reiterate that, when it comes to unit upkeep costs not changing, it is just a display problem. I tested this months ago, that losing a unit (to mission/battle/delete) does not impact the displayed gold per turn in the upper left of the main screen, but the actual gold per turn lost or gained between turns does accurately reflect the unit changes.
Now, in relation to the unit upkeep code directly…
@Toffer90 , no matter what any one other team member’s skills might be, you are obviously the person with the best understanding of the current state and contents of the entire C2C code base, period. So, I am likely to embarrass myself with this line of questioning. But, [redacted] My goal here is to help, and I think I have information, background, skill, and experience that allows me to try.
If I am reading the code correctly, the unit upkeep code is currently located only in CvPlayer.cpp, starting at line 9103.
[here I started on the 9th going through it line by line, tracing definitions through CvGameCoreDLL.cpp, and so forth, and describing exactly what I saw and how it was different than vanilla, and how the C2C xml has some Null values for some difficulties and other values I didn’t like, but it was really long… and then I saw today on discord that you are making changes, and I wasn’t done, so I deleted the paragraphs and decided going through differences didn’t matter. Sorry I didn’t finish and post this 5 days ago.]
To back up a little, the current state of the function doesn’t really matter, except in relation to how difficult it has to be to address our needs. Let’s examine the problems that need to be fixed, or at least the ways in which unit upkeep needs to be handled differently than vanilla civ4. Thus far, I see three separate ones mentioned in this conversation. They are subdued animals, promotions, and unit group size (when the Size Matters game option is activated). Are there any other ways that C2C needs to handle unit upkeep differently than BtS? Let’s examine those three requirements while we wait for a complete list containing anything else that needs to be handled.
I already offered one way that subdued animals could be handled. Another option would be to subtract them from the total amount of units before any math is done, so they aren’t even displayed as “free” units, let alone taken into account in the equation. A third would be something similar to what we have now, adding them to the number of free units after the free unit calculations have been done but before handicap costs are tallied. And so forth. (Another, possibly easier and more accurate method becomes obvious further down in the post.) Whatever we choose, it will have an impact on how supply for the subdued animals will need to be handled. Either way, I think there are a lot of options here, and I don’t see any that are invasive to a final overall solution.
Let’s skip past promotions for a moment, and come back to them. Unit group size is a significant player in this conversation. There are multiple creative ways I can think of for tallying those costs, but I think there is an important restriction in any efforts. Namely, that SM is still an option, not an integral and necessary part of C2C (I gather there is no unanimous outcry to change that, right
@JosEPh_II ?) If that is the case, any final solution must be able to handle the option being both on and off. In general, the two different ways of approaching a problem like this would be to either a) have two separate modules that take the same inputs and supply the same outputs in the same format, but are both very different under the hood and and need to be maintained completely separately, or b) have one method that handles both cases through one or a few parameters. Because my personal design preferences lean toward b) whenever possible, I will offer an idea for that approach, but I am also open to a) as a valid design decision. What if, instead of the unit upkeep cost going up or down by group size, we accomplish the exact same outcome through a different way. Say we have 3 companies of clubmen, and they merge to form 1 battalion of clubmen. Under current thought, that would go from 3 units with 1 (1 is arbitrary here, it is just a multiplier and 1 is easiest to demonstrate) gold upkeep/turn, to 1 unit with 1.2 gold upkeep/turn (I assume the 20% number is still accurate, found in post #1 of
https://forums.civfanatics.com/thre...-size-matters-game-option-version-2-0.523860/, but again any multiplier works in my example), or a modification of 3/turn to 1.2/turn, if the player were past their ‘free’ unit limit. This is difficult to handle, because each unit’s gold per turn must be handled and stored and ranked exactly as explained above, but also because each unit’s gold per turn will need to be handled completely differently if the SM option is switched off. Tangentially, balancing unit types and technological levels through upkeep costs would be somewhere between difficult and impossible, when switching between SM on and off. My suggestion is that each unit would not have a gpt value at all, let alone one to be handled and ranked. Instead we would just count units. Let me illustrate: when we have our 3 companies of clubmen, that is 3 units total for upkeep purposes (again, our 1 is arbitrary, I think companies are closer to 0.83, but this is just an illustration). When they merge, our 1 battalion is 1.2 units total for upkeep purposes. Just as before, as long as the player is past their ‘free’ unit limit, we go from 3 to 1.2, and so merge has the same effect on unit upkeep. Now, how much a single ‘unit’ costs in upkeep, whether that is 1 gold or more or less, is just a multiplier. How ever many free units there are or which ones are free doesn’t matter, the free unit count is created before the turn starts and is only modified when there is a population or civic change during the player turn, when a lot of other things are happening too. A nice accidental positive here is that graphical updates are easy, since when a unit is removed from the game (merge/split/mission/battle/delete/etc.), the existing code that handles that can just add or subtract from the variable containing the number of units, and call the module that does the subtraction from the free units to refresh the display. The easiest way to have the code handle this, is assume that every unit has a ‘unit upkeep number’ of 1, whether SM is on or off, and let the already coded upkeep variances for different size groups stay in place. Another option, that also wouldn’t conflict with SM being on or off, would be to have someone do a massive full unit audit (cough
@Thunderbrd ), and allow them to use ‘unit upkeep number’ (or a more aptly name property, call it what you will in the xml) as a tool to more finely tweak and balance units in relation to each other. (A coarse example might be culture units having 0.9 if all other units are 1, in order to make cultures just slightly more valuable, in a way that just isn’t possible in the current upkeep schema, or another might be to make nukes 1.1 or 1.5, which would slightly discourage having huge numbers of nukes just sitting around in a more nuanced way than properties or happiness can currently do.) This would also be a handy multiplier or comparison tool for the upcoming equipment mod. And it would be relatively easy to add this information to the mouseover in the build queue, in the format of “[100 - 100*value/default]% upkeep difference from a normal unit” (in our example, default is 1). I am sure there are other ways to handle the SM on/off option for unit upkeep, but this one seems easier to implement and easier for the player to understand than other ones I thought of, as well as easier to expand upon and tweak for modders.
Now, back to promotions (and equipment, in future versions). If we were to use the above to handle the SM option, we could very easily make promotions do the same thing… as long as the promotions we are dealing with are all percent modifiers. I have to admit my weakness here, that I don’t know the future plans for promotions that are supposed to impact costs, and I haven’t studied the late game well enough to remember all the current promotions, but I can’t think of any promotions currently in use that modify upkeep. If my understanding and recollection is correct, then we have an opportunity to devise that from the ground up. But even if not, I think we are ok. Let me give a few examples of one way promotions might work in this paradigm. Say we want to balance the Might promotions (not saying we need to, just an example). Each level of Might could multiply the modified ‘unit upkeep number’ by +25%. So, with a unit that naturally has a ‘unit upkeep number’ of 1, the promotion would make it worth 1.25 units for upkeep purposes. Or say we had a national unit (0.9 in an example above, again just an example), merged two levels, with Might, it would be worth 0.9*(1.2*1.2)*(1+0.25)=1.62 units. If the same unit also had a 50% reduced upkeep promo, it would then be worth 0.9*(1.2*1.2)*(1+0.25-0.5)=0.972 units. This sort of math will make sense to anyone who has taken apart the code for SM, and tried to understand how quality and group size interact. For those that haven’t, or don’t want anything to do with SM, our example wouldn’t have a merged unit, and the national unit with Might and reduced upkeep would be worth 0.9*(1+0.25-0.5)=0.675 units, which is going to look a whole lot like regular combat calculations, the kind you see in the combat odds mouseover. Separately, if there were promotions that didn’t give a percentage but instead a specific amount of gold per turn (hard to think of a good example, but maybe state sponsored media, so entertainer units would add 0.5 gpt to the treasury, or maybe a general unit that costs a flat salary for his retinue of 2 gpt from the treasury), the ‘free support’ mechanic really shouldn’t impact that, but instead be like buildings or trade income. Pretty easy for the player to understand. In the future, say around v43 or so, or whenever equipment starts making an appearance, we could do some fancy things like saying units with Bottleneck are more efficient in smaller groups and less efficient in larger groups, so Bottleneck would reduce upkeep by 1% or 5% of the unit, for every level lower than ‘normal’ the unit has split, but increase it by the same amount for every level higher than ‘normal’ the unit has merged. That requires a little algebra, but it isn’t a difficult line of code, per se. With SM off, these calculations (and these promotions) would simply and naturally have no impact on gameplay, and would not require any changes or separate maintenance, but any promotions that impact upkeep but have nothing to do with SM would still work the same way. Sure, there will always be difficult work to make units balanced under SM and also not, but upkeep wouldn’t play a role in that discussion (whereas I think it does now).
So, what would this look like at an empire wide scale? Say we have 100 units at various group sizes and promotion levels, all adding up to a modified and multiplied ‘unit upkeep number’ (I hate that name, I wish I were better at naming) of 127.63. We know that civ4 rounds all decimals down, and where they use the floor function has produced screaming fits in thousands of people, but you can decide for yourself where (or if) to use the floor function, whether at the unit level, the ‘unit upkeep number’ level, after it has been combined with unit handicap and supply, or after that number has been combined with the rest of the income and expenses. If my civ had 8 cities, each with 6 population, and I were at Settler difficulty (the iFreeUnits value in the SVN currently is 36), and my civic gave me an extra 5 free units (this will be based upon population instead of a hard coded number, but I understand that will take some time to balance) I would get 0.24*48 + 36 + 5 + 4 = 51.52 free units (the 4 is hard coded into the support mechanism, don’t know why), and would pay upkeep costs for 127.63 - 51.52 = 76.11 units (or however you round). If population or civic changed mid turn, the 51.52 would go up or down, and the trigger is easy. If units are created (subdued/captured) or removed (mission/killed/deleted) the 127.63 would go up or down, and the trigger is easy. Whenever these values are updated, a GUI refresh could be sent.
Also, I suggest this conversation be split off into its own thread, somewhere between post 2204 and 2208.
And to be clear, no part of this is meant to address supply, distance modifiers, or military unit cost (which is purely a civic setting). I think that supply could become more obvious for the player by better mouseover game text, but that can wait a few versions, and anything else along those lines can be more easily tweaked once this is clear and balanced and working well. But those lines of code are probably easier than the ones we are working with, in proximity, and use many of the same variables, so some people may want to voice opinions on those things here, now.
Anyway, this makes sense to me. In code, as a player, and in context of the future conversations I have been hearing about. I know I have only been lurking and listening for less than a year, and I hope that me having an opinion on the direction of a part of the mod isn’t offensive, but this seems to meet the goals of transparency, ability to be built upon, and easier to understand and maintain by multiple coders.