View Full Version : alterring speed settings - research vrs production


suburbanite09
Dec 11, 2007, 07:22 PM
I am a 100% newb to modding. In civ 2 there was a way to slow the tech research in the scenario editor so it took longer to research techs but the production stayed the same. This would make it so you had time to build all the buildings for a tech and many units before the tech became outdated. You could carry out full wars in the ancient and medieval eras. The way the game is set up by default, the techs fly by so fast, by the time you build the buildings in your cities there are 2 - 3 more buildings to build, and before you know it, its the modern era.

I want to take the epic speed setting and make the production modifier that of the normal or quick speed setting so that research is slow but production is fast.

I am using Civ 4 gold edition ( :( yeah, i know)

Seven05
Dec 12, 2007, 10:55 AM
It's an easy XML change to mix and match the settings for each different gamespeed, if you look at Civ4GameSpeedInfo.xml in the Assets/XML/GameInfo folder it should make sense. Just be forewarned, slowing research without slowing production will result in cities that have nothing to build except units wich will run you out of money in upkeep. To combat that effect I created a new process in Assets/XML/GameInfos/Civ4ProcessInfo.xml that allows cities to 'idle' before getting the techs required to produce wealth, culture or research:

<ProcessInfo>
<Type>PROCESS_IDLE</Type>
<Description>TXT_KEY_PROCESS_IDLE</Description>
<Strategy>TXT_KEY_PROCESS_IDLE_STRATEGY</Strategy>
<TechPrereq>NONE</TechPrereq>
<ProductionToCommerceModifiers>
<iProductionToCommerceModifier>20</iProductionToCommerceModifier>
<iProductionToCommerceModifier>20</iProductionToCommerceModifier>
<iProductionToCommerceModifier>0</iProductionToCommerceModifier>
</ProductionToCommerceModifiers>
<Button>Art/Interface/Buttons/Actions/Sleep.dds</Button>
</ProcessInfo>

The new idle process converts 20% of the hammers to Gold & Research making it less effective than the normal research or wealth processes but better than wasting hammers on units that you have to disband to keep from going bankrupt.

If you're not afraid of SDK changes I can share the code I used to change game speeds into a 'turns per era' option where the turn number is used to determine the current era and then tech costs are dynamically adjusted to make advanced techs (from the later eras) more expensive and old techs (from past eras) less expensive. It's a pretty easy change... in fact, I'll post it now anyway. The code is actually shorter than the comments I added to explain it :)

In CvTeam.cpp find the CvTeam::getResearchCost(TechTypes eTech) method and change the entire method to:

int CvTeam::getResearchCost(TechTypes eTech) const
{
int iCost;

FAssertMsg(eTech != NO_TECH, "Tech is not assigned a valid value");

iCost = GC.getTechInfo(eTech).getResearchCost();

iCost *= GC.getHandicapInfo(getHandicapType()).getResearchP ercent();
iCost /= 100;

iCost *= GC.getWorldInfo(GC.getMapINLINE().getWorldSize()). getResearchPercent();
iCost /= 100;

iCost *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpee dType()).getResearchPercent();
iCost /= 100;

iCost *= GC.getEraInfo(GC.getGameINLINE().getStartEra()).ge tResearchPercent();
iCost /= 100;

iCost *= std::max(0, ((GC.getDefineINT("TECH_COST_EXTRA_TEAM_MEMBER_MODIFIER") * (getNumMembers() - 1)) + 100));
iCost /= 100;

/*** World Piece Begin ***/
// Skip this entirely for anything other than ancient era starts
if (GC.getEraInfo(GC.getGameINLINE().getStartEra()).g etStartPercent() == 0)
{
int iTechEra = GC.getTechInfo(eTech).getEra();
int iCurrentEra = GC.getGame().getElapsedGameTurns() / GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpee dType()).getVictoryDelayPercent();

// In order to loosely enforce a set number of turns per era modify tech costs
// so that techs from the current era are at 100% cost, the previous era techs
// are at 50% cost and the next era cost is at 200%.

// Turns per era is defined by the iVictoryDelayPercent in GameSpeedInfos.xml
// that value will be the ideal number of turns per era for that gamespeed
// so normal speed games expect 100 turns per era.
if (iCurrentEra > iTechEra)
{
iCost *= 50;
iCost /= 100;
}
else if (iCurrentEra < iTechEra)
{
iCost *= 200;
iCost /= 100;
}
}
/*** World Piece End ***/

return std::max(1, iCost);
}


To avoid having to add a new XML tag at this time I use the VictoryDelayPercent form the GameSpeedInfo file. I also had to increase the number of turns per game speed to make sure there was enough time since there are seven eras (including the future era) I basically made sure I have 7 * VictoryDelayPercent turns for that game speed.

This is temporary code since I'm still testing the effects and trying to sort out exactly what values need to be used per game speed. It's using a few 'cheap hacks' like VictoryDelayPercent for the number of turns and only working for games starting in the ancient era so it needs some work to make it perfect however with this it is fully functional and serves the exact purpose you asked for, it makes sure you have enough time per era to use units before they become obsolete.