Single Player bugs and crashes v37 plus (SVN) - After the 24th of December 2016

For Research Difficulty factor is added to Mapsize factor.
For Production Difficulty factor is summed with Global and Era factor.
This means they are effectively different numbers for further processing.

If you made Difficulty and Global factors multipliers to base or end value, then they would behave exactly as you wanted.

Alternatively you could make Difficulty factor sum with same things for research and production.
I will review the code further.
 
Which is thus to say nightmare was better balanced between research and construction than the rest of the settings. I suggest we drop the production cost global to zero if we're not going to change research rates.

Rax makes a point to further figure out what is not being taken into account in that ratio though.

But if you can't build enough to keep up with research you can't take care of many basic needs. Refer to tests run by other players on easier settings turned difficult for this reason, including joseph when he whines about upgrades being too expensive. If you can't keep the basics upgraded and things are obsoleting faster than you can replace them than that fouls up play.

So the easy fix here is to reduce the production global until you find the right balance again. Then that balance applies everywhere now.
Well Global factor for production is one with Difficulty and Era factors on further processing.
Code:
Normal/Noble/Standard factors. Era factor is 100 too.

  int iProductionNeeded;

   iProductionNeeded = GC.getBuildingInfo(eBuilding).getProductionCost(); 1000H

   iProductionNeeded *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent(); 1000H*100 = 100 000H
   iProductionNeeded /= 100; 100 000H/100 = 1000H

   int iModifier = (GC.getHandicapInfo(getHandicapType()).getConstructPercent() - 100); 100 - 100 = 0
   iModifier += GC.getDefineINT("BUILDING_PRODUCTION_PERCENT") - 100; 0 + 0 - 100 = -100 - Global modifier set to 0 in this simulation.
   iModifier += (GC.getEraInfo(getCurrentEra()).getConstructPercent() - 100); -100 + 100 - 100 = -100

    if (iModifier < 0)
    {
        iModifier = (-1 * iModifier + 100); -1*-100 + 100 = 200
        iProductionNeeded = iProductionNeeded * 100 / iModifier; 1000H*100/200 = 500H
    }
    else if (iModifier > 0)
    {
        iProductionNeeded *= 100 + iModifier;
        iProductionNeeded /= 100;
    }

   return std::max(1, iProductionNeeded); 500 H
Setting global production modifier to 0 halves production cost if other factors are set to 100.

Global factor should be multiplier to reduce costs to x% if you set it in xml at x% independently from all other factors.
Lets go abstract:
Lets say there is factor A, that is is used for further processing.
a lets say is Difficulty factor, b is Global factor and c is Era factor.
A = a + b + c.
A = a + 2b + c != 2A
A = a + 0 + 0 = a
I guess you should make program to do calculations for you :mischief:

Adding different factors makes them depend on each other.

That is if you really wanted to reduce building costs to 80% with global modifier, then you should reduce difficulty and era modifiers by 80% too.

In total there is Global modifier, Mapsize modifier, Difficulty modifier, Speed modifier and Era modifier.
Additionally Research have Beeline Stings and Production have Upscaled Costs option.

Research/production ratio is 1 on 0th column and 960359/30655 = 31x on 160th column assuming raw costs and normal buildings.
Maybe reducing iconstruct/itrain ramp to 5% steps away from Noble (10% deity->nightmare), reducing iresearch rampdown below Noble to 10% per step and setting iresearch to (or having small stepup/stepdown) 100 for all sizes would help calm down things?
In addition to making globaldefines production modifiers being multiplier for base or end values.

train/build modifiers:
Settler- 85
Chieftain - 90
Warlord - 95
Noble - 100
Prince- 105
Monarch - 110
Emperor - 115
Immortal - 120
Deity - 130
Nightmare - 150

research modifiers:
Settler- 70
Chieftain - 80
Warlord - 90
Noble - 100

research modifiers:
Duel- 85
Tiny - 90
Small - 95
Standard - 100
Large - 105
Huge - 110
Giant - 115
Gigantic- 120

Code:
Normal/Noble/Standard factors. Era factor is 100 too.

  int iProductionNeeded;

   iProductionNeeded = GC.getBuildingInfo(eBuilding).getProductionCost(); 

   iProductionNeeded *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent(); 
   iProductionNeeded /= 100; 
  iProductionNeeded *= GC.getDefineINT("BUILDING_PRODUCTION_PERCENT"); 
 iProductionNeeded /= 100; 

   int iModifier = (GC.getHandicapInfo(getHandicapType()).getConstructPercent() - 100); 
   iModifier += (GC.getEraInfo(getCurrentEra()).getConstructPercent() - 100); 

    if (iModifier < 0)
    {
        iModifier = (-1 * iModifier + 100); 
        iProductionNeeded = iProductionNeeded * 100 / iModifier; 1
    }
    else if (iModifier > 0)
    {
        iProductionNeeded *= 100 + iModifier;
        iProductionNeeded /= 100;
    }

   return std::max(1, iProductionNeeded); 500 H
 
Last edited:
In my previous post I should've mentioned that my research sped up a great deal. I believe I had a surplus allowing me to put 15-20% more into research, which is huge on nightmare. But that doesn't really help if construction has been slowed down to half of what it was before.

Of course you sped up production quite a bit a few SVN's back, so it's hard to say what I'm really used to... The problem is you're losing all the early production buildings so quick that all you're left with is mostly expensive production buildings that you'll have to construct all of, before anything else - or you risk slowing down too much. Which means most of the game is focused towards building production buildings, with short bursts of army building for wartime purposes.

And you have to try and not to remove those production rich forests, because production is such an important commodity and engineers take a long time to become important enough for you to switch to agriculture.

Interestingly enough, historical humanity did just the opposite. Slash and burnt the forest (unknowingly averting the next ice age) and made as much farmland as they could.
Most of the (European) forests we can visit today are the result of massive reforestation during the 17th to 19th centuries, connected with the increased importance of wooden shipbuilding. Farmland was what everybody had and forests existed on the edges of society, mostly owned by nobles who jealously guarded their rights to hunting there.
 
Last edited:
Well Global factor for production is one with Difficulty and Era factors on further processing.
Code:
Normal/Noble/Standard factors. Era factor is 100 too.

  int iProductionNeeded;

   iProductionNeeded = GC.getBuildingInfo(eBuilding).getProductionCost(); 1000H

   iProductionNeeded *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent(); 1000H*100 = 100 000H
   iProductionNeeded /= 100; 100 000H/100 = 1000H

   int iModifier = (GC.getHandicapInfo(getHandicapType()).getConstructPercent() - 100); 100 - 100 = 0
   iModifier += GC.getDefineINT("BUILDING_PRODUCTION_PERCENT") - 100; 0 + 0 - 100 = -100 - Global modifier set to 0 in this simulation.
   iModifier += (GC.getEraInfo(getCurrentEra()).getConstructPercent() - 100); -100 + 100 - 100 = -100

    if (iModifier < 0)
    {
        iModifier = (-1 * iModifier + 100); -1*-100 + 100 = 200
        iProductionNeeded = iProductionNeeded * 100 / iModifier; 1000H*100/200 = 500H
    }
    else if (iModifier > 0)
    {
        iProductionNeeded *= 100 + iModifier;
        iProductionNeeded /= 100;
    }

   return std::max(1, iProductionNeeded); 500 H
Setting global production modifier to 0 halves production cost if other factors are set to 100.

Global factor should be multiplier to reduce costs to x% if you set it in xml at x% independently from all other factors.
Lets go abstract:
Lets say there is factor A, that is is used for further processing.
a lets say is Difficulty factor, b is Global factor and c is Era factor.
A = a + b + c.
A = a + 2b + c != 2A
A = a + 0 + 0 = a
I guess you should make program to do calculations for you :mischief:

Adding different factors makes them depend on each other.

That is if you really wanted to reduce building costs to 80% with global modifier, then you should reduce difficulty and era modifiers by 80% too.

In total there is Global modifier, Mapsize modifier, Difficulty modifier, Speed modifier and Era modifier.
Additionally Research have Beeline Stings and Production have Upscaled Costs option.
I failed to understand what you are trying to say.
By reducing global modifier to 80 from 100, it means that the building will be built 20% faster, not that it will require 20% less hammers.
In your case, since iModifier is -100, it means we build things 100% faster (note that it's not the same as -100% construction cost), and got half the hammers cost as you said.
How would changing difficulty and era affect this? Overall, it's all summed up- there is no different between (a+(b+d)+c) and ((a+d)+b+c).
I'd expect that a bigger issue would be that one might expect 50, 50, 200 to result in a 50% production cost instead of 100%, but that doesn't seem to be the case.

Interestingly enough, historical humanity did just the opposite
In a sense, it's true in C2C as well.
2 food is enough for 1 person. 1 person (engineer) will give something along the lines of 2 hammers and 3 GP points. Usually, more as you invest in civics and fun stuff. Going on priests can lead to something around the 3 hammers, 1 currency and 2 gold per person working as priest.
This way, 2 hammers is a really poor choice.
The issue is, there is a limit to growth (up to something around the peopleX4 it gets wasted), and growth is extremely slow at the start of the game. In later eras, you get more food and lower food cost for growth, so cities start expanding. (stupidity for the win! as each level of education increases/reduces the food needed by 10%)
In this sense, if the cities required less food to grow, food would become a lot more valuable.
(I remind you that if you took care of disease and lack of food, the growth rate should be exponential)
 
Looking at the getProductionNeeded function code for the first time now, and here is my comment on how it should be.
Code:
int CvPlayer::getProductionNeeded(BuildingTypes eBuilding) const
{
    int iProductionNeeded;

    iProductionNeeded = GC.getBuildingInfo(eBuilding).getProductionCost();

    iProductionNeeded *= GC.getDefineINT("BUILDING_PRODUCTION_PERCENT")
    iProductionNeeded /= 100;

    iProductionNeeded *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent();
    iProductionNeeded /= 100;

    iProductionNeeded *= GC.getHandicapInfo(getHandicapType()).getConstructPercent();
    iProductionNeeded /= 100;

    iProductionNeeded *= GC.getEraInfo(getCurrentEra()).getConstructPercent();
    iProductionNeeded /= 100;

    if (!isHuman() && !isNPC())
    {
        if (isWorldWonderClass((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())))
        {
            iProductionNeeded *= GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIWorldConstructPercent();
            iProductionNeeded /= 100;
        }
        else
        {
            iProductionNeeded *= GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIConstructPercent();
            iProductionNeeded /= 100;
        }

        iProductionNeeded *= std::max(0, ((GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIPerEraModifier() * getCurrentEra()) + 100));
        iProductionNeeded /= 100;
    }

    return std::max(1, iProductionNeeded);
}
By setting the global define BUILDING_PRODUCTION_PERCENT = 0
One would expect all buildings to cost 1 Hammer regardless of what era, difficulty, or gamespeed that are active.​
By setting the global define BUILDING_PRODUCTION_PERCENT = 50
One would expect all buildings to cost half of what it would do (if the define was 100) regardless of what era, difficulty, or gamespeed that are active.​
By setting the global define BUILDING_PRODUCTION_PERCENT = 200
One would expect all buildings to cost double of what it would do (if the define was 100) regardless of what era, difficulty, or gamespeed that are active.​
 
Last edited:
I failed to understand what you are trying to say.
By reducing global modifier to 80 from 100, it means that the building will be built 20% faster, not that it will require 20% less hammers.
In your case, since iModifier is -100, it means we build things 100% faster (note that it's not the same as -100% construction cost), and got half the hammers cost as you said.
How would changing difficulty and era affect this? Overall, it's all summed up- there is no different between (a+(b+d)+c) and ((a+d)+b+c).
I'd expect that a bigger issue would be that one might expect 50, 50, 200 to result in a 50% production cost instead of 100%, but that doesn't seem to be the case.
Well in example I reduced global modifier to 0 from 100 and I got building getting built 50% faster.
Excepted behavior would be buildings getting build instantly
With global modifier of 1 I would except building getting 100x faster.
Now if you zero all handicap and erainfo itrain/iconstruct you still need some time to get building being built.
Also you would get different imodifier with different handicap and era modifiers.

Toffers example is much clearer - double something and you double time to get building.
Halve some modifier and you halve time needed to build something.
 
Last edited:
If I go back to all modifiers being multiplicative to each other than the same should be done for research. We'll just have to do that and then see where we're at then.
 
If I go back to all modifiers being multiplicative to each other than the same should be done for research. We'll just have to do that and then see where we're at then.

[Cumulative Tech Modifier] = ( iResearchPercent WorldInfo ) x ( iResearchPercent EraInfo ) x ( iResearchPercent HandicapInfo ) x ( iBeelineStingsTechCostModifier EraInfo )
[Base tech cost] = ( iCost
TechInfo ) x ( TECH_COST_MODIFIER ) x ( iTechCostModifier EraInfo, depends on what era the tech is in )

[Tech Cost] = [Base tech cost] x [Cumulative Tech Modifier] x ( iResearchPercent
GamespeedInfo ) x ( TECH_COST_EXTRA_TEAM_MEMBER_MODIFIER )

iResearchPercent EraInfo seems to be unused at all - for all eras it equals 100.
Beeline Stings modifies past era tech costs.

Also you might want to remove AItrain and AIconstruct from handicaps, if you build slower on higher difficulties, then AI shouln't build faster on higher difficulties.
Also remove map size modifier for tech cost as it means techs are relatively cheaper if everything is constant but map gets smaller.

Effectively tech cost looks more like this
[Cumulative Tech Modifier] = ( iResearchPercent WorldInfo ) x ( iResearchPercent HandicapInfo ) x ( iBeelineStingsTechCostModifier EraInfo )
[Base tech cost] = ( iCost
TechInfo ) x ( TECH_COST_MODIFIER XML constant ) x ( iTechCostModifier EraInfo, depends on what era the tech is in )

[Tech Cost] = [Base tech cost] x [Cumulative Tech Modifier] x ( iResearchPercent
GamespeedInfo ) x ( TECH_COST_EXTRA_TEAM_MEMBER_MODIFIER )

Including part of equation, that always fires we get:
[Cumulative Tech Modifier] = ( iResearchPercent WorldInfo ) x ( iResearchPercent HandicapInfo )
[Base tech cost] = ( iCost
TechInfo ) x ( TECH_COST_MODIFIER XML constant ) x ( iTechCostModifier EraInfo, depends on what era the tech is in )
[Tech Cost] = [Base tech cost] x [Cumulative Tech Modifier] x ( iResearchPercent
GamespeedInfo )

Beeline Stings affects era in earlier techs, Extra Team Member depends if you play in one team with someone (or AI) and TECH_COST_MODIFIER is constant defined in TechDiffusion_GlobalDefines.xml just like Building_Production_Percent.
TECH_COST_MODIFIER is defined as 0 - it is offset by 100 - basically TECH_COST_MODIFIER XML constant is equal to 1.

At the end we have something like this:
[Cumulative Tech Modifier] = (iCost TechInfo ) x ( iResearchPercent WorldInfo ) x ( iResearchPercent HandicapInfo ) x ( iTechCostModifier EraInfo, depends on what era the tech is in ) x ( iResearchPercent GamespeedInfo ) x ( TECH_COST_MODIFIER XML constant ) x ( iBeelineStingsTechCostModifier EraInfo )
 
Last edited:
So I suppose we goofed on that in the first place earlier this cycle.

Unfortunately, this means that things will be a bit screwed up for research to calendar. Which sucks. I was trying hard to avoid that. It's also going to take some serious testing to get it back dialed in.

iResearchPercent EraInfo seems to be unused at all - for all eras it equals 100.
Beeline Stings modifies past era tech costs.
Actually, I think you just hit the difference in some of your research vs production comparisons. If we need to adjust the construction and training in the era infos (and there was a reason for this) then we also need to adjust the research percent in EraInfo. Beeline stings is then just an extra factor for gameplay - a counterbalance to racing ahead for the tech bonus at a gateway tech.

Also you might want to remove AItrain and AIconstruct from handicaps, if you build slower on higher difficulties, then AI shouln't build faster on higher difficulties.
I agree.
 
Actually, I think you just hit the difference in some of your research vs production comparisons. If we need to adjust the construction and training in the era infos (and there was a reason for this) then we also need to adjust the research percent in EraInfo. Beeline stings is then just an extra factor for gameplay - a counterbalance to racing ahead for the tech bonus at a gateway tech.
iTechCostModifier EraInfo <- That is used as tech cost modifier - it starts at 0 (equivalent of 100) in Prehistoric and goes up to 70 (equivalent of 170) in Future by 5% steps/era

Unfortunately, this means that things will be a bit screwed up for research to calendar. Which sucks. I was trying hard to avoid that. It's also going to take some serious testing to get it back dialed in.
Most likely only in worldsize/handicap plane.
Shouldn't be that bad if you keep close to Noble difficulty or Standard map.
Duel/Settler factor was 0.1
Gigantic/Deity factor was 2.5.

Now Duel/Settler factor would be 0.5x0.6 = 0.3.
Gigantic/Deity factor would be 2x1.5 = 3
This means smaller than Standard and easier than Noble would have slower research later which is good.
Also bigger maps and harder difficulties shouldn't get too slow.
 
Last edited:
iTechCostModifier EraInfo <- That is used as tech cost modifier - it starts at 100 in Prehistoric and goes up to 170 in Future by 5% steps/era
Ah... right. So this is why it's not being perceived in the direct cost ratios. We should swap the use of those tags, iTechCostModifier, and iResearchPercent imo.

Toffer... please help me to consider the consequences of such a swap.
 
Also you might want to remove AItrain and AIconstruct from handicaps, if you build slower on higher difficulties, then AI shouln't build faster on higher difficulties.
Also remove map size modifier for tech cost as it means techs are relatively cheaper if everything is constant but map gets smaller.
I do not completely agree on this, imo the player shouldn't notice being penalized by difficulty by simply seeing that the beaker and hammer costs are higher or lower based on difficulty.
I would rather see iTrainPercent, iConstructPercent and iResearchPercent removed and a new iAIResearchPercent introduced than the opposite.
It is better that the AI get reductions instead of giving the player increases on higher diffs as that insulates against integer overloads and makes difficulties more subtle (gameplay would seem less changed even though the game gets harder).

There is little point in having both ways though so regardless of TB's decision it will be a xml sanity improvement to remove one of them.
 
I do not agree on this, imo the player shouldn't notice being penalized by difficulty by simply seeing that the beaker and hammer costs are higher or lower based on difficulty.
I would rather see iTrainPercent, iConstructPercent and iResearchPercent removed and a new iAIResearchPercent introduced than the opposite.
It is better that the AI get reductions instead of giving the player increases on higher diffs as that insulates against integer overloads and makes difficulties more subtle.
Personally, I fully agree with this opinion.
 
Ah... right. So this is why it's not being perceived in the direct cost ratios. We should swap the use of those tags, iTechCostModifier, and iResearchPercent imo.

Toffer... please help me to consider the consequences of such a swap.
I didn't quite get why we would want to make such a swap.

At least iTechCostModifier works exactly as designed as far as I know...
The Era iResearchPercent value is a bit strange as it is only the starting era that counts... perhaps we should change it so that it is the current player era that is used for this tag?
iModifier += (GC.getEraInfo(GC.getGameINLINE().getStartEra()).getResearchPercent() - 100);
 
I do not completely agree on this, imo the player shouldn't notice being penalized by difficulty by simply seeing that the beaker and hammer costs are higher or lower based on difficulty.
I would rather see iTrainPercent, iConstructPercent and iResearchPercent removed and a new iAIResearchPercent introduced than the opposite.
It is better that the AI get reductions instead of giving the player increases on higher diffs as that insulates against integer overloads and makes difficulties more subtle (gameplay would seem less changed even though the game gets harder).

There is little point in having both ways though so regardless of TB's decision it will be a xml sanity improvement to remove one of them.
I can respect that opinion and you have good arguments. As a player, however, I'd prefer not to have to do as I have, which is find out years after playing that the AI HAS had a secret set of advantages I wasn't aware of and THEIR version of Noble is NOT the version of Noble that I experience when I play. However, swapping to the other side of the coin, your approach MIGHT not make the difficulty levels feel quite as punishing in such a manner that it becomes, as was said earlier 'boring' waiting for things to be trained and constructed. Maybe we should split the difference a little.
 
I do not completely agree on this, imo the player shouldn't notice being penalized by difficulty by simply seeing that the beaker and hammer costs are higher or lower based on difficulty.
I would rather see iTrainPercent, iConstructPercent and iResearchPercent removed and a new iAIResearchPercent introduced than the opposite.
It is better that the AI get reductions instead of giving the player increases on higher diffs as that insulates against integer overloads and makes difficulties more subtle (gameplay would seem less changed even though the game gets harder).

There is little point in having both ways though so regardless of TB's decision it will be a xml sanity improvement to remove one of them.
Mirror side is fine too.
 
Last edited:
I didn't quite get why we would want to make such a swap.

At least iTechCostModifier works exactly as designed as far as I know...
The Era iResearchPercent value is a bit strange as it is only the starting era that counts... perhaps we should change it so that it is the current player era that is used for this tag?
True that starting era means next to nothing. I'll have to look at the difference between them and where they are applied exactly. It might just be that iResearchPercent should be doing AS iTechCostModifier is doing instead of what it is doing now, which is worthless and at that point the main thing is keeping naming conventions and the functioning behind them from one type of xml to the next the same.
 
As a player, however, I'd prefer not to have to do as I have, which is find out years after playing that the AI HAS had a secret set of advantages I wasn't aware of and THEIR version of Noble is NOT the version of Noble that I experience when I play.
Haha, true that is a good point, but let's be realistic, that is the way it is done in almost every game ever designed, difficulty changing the envioronment/NPC/AI stats instead of the human player stats.
I remember a sort of disillusionment from my early childhood when I understood that this was the case in all strategy games, I actually though the AI was designed so that changing the difficulty was the same as changing the AI IQ (making it smarter or dumber), it is however very rare for game designers to write several different AI codes dedicated to the different difficulties.
 
I do not completely agree on this, imo the player shouldn't notice being penalized by difficulty by simply seeing that the beaker and hammer costs are higher or lower based on difficulty.

That would mean that the AI should be more complex to be able deal with the variation in game parameters. Optimizing the AI for one set of parameters is hard enough, optimizing it for multiple sets of parameters is even harder. Since programming and balancing the AI is probably the hardest part of the game, I think that going with your proposal would be a massive mistake.
 
Back
Top Bottom