Infinite Golden Age and Science Age

Antal1987

Warlord
Joined
Sep 4, 2013
Messages
160
Location
Karelia, Russia
Hello!

Golden Age

In C3C Editor golden age duration can be set up to 100. But in the runtime it can be set to any value. Here how it works.

Golden Age period for a Civlization (Player or AI) is technically prodived only by one variable: Golden Age End. It's 4-byte integer and it represents the exact turn, when Golden Age disables.
The variable is being initialized when the game sees that a Civ has built required wonders.
The Game just calculating End Turn as Current Turn (see Vistory Conditions) + Golden Age Duration (see General Settings in Civ Editor).

The variable has offset 0x3C from a civ class object start.
A Civ clas object can be found by 4-char string "LEAD" which has offset 0x08 from object's start.

In single player mode Player Civ has index 1 (counting from 0).

In C3C v1.22. Player Civ has address: 0x00A54F3C.
It's Golden Age End variable has address: 0x00A54F78.

Therefore, it's enough to change this value to let's say 10000 to have infinite Golden Age.

Science Age

Science Age works a little bit different. It has it's own variable for End Turn but it also has 4-byte integer for status.

When the Game initiates Science Age, it sets Science Age Status to 1 and Science Age End to Current Turn + 20 (hard-coded constant)

Here are offsets of these values is Civ class structure:
000015D0 Science_Age_Status (4 bytes)
000015D4 Science_Age_End dd (4 bytes)

In C3C v1.22 it's addresses are: 0x00A5650C and 0x00A56510 respectively.

Therefore, it's enough to change Status value to 1 ans End Turn value to let's say 10000 to have infinite Science Age.
 
Antal, am I correct that these changes would have to be made to the source code itself?
And that this would require a decompiler to do?
 
Antal, am I correct that these changes would have to be made to the source code itself?
And that this would require a decompiler to do?

No, these changes have to be made in runtime. You need to modify game process memory. It can be made with such tools as CheatEngine or ArtMoney.
 
Perhaps, but for some reason it doesn't work in the game. I just runs down to 1 turn and stops there untill the tech is researched normally. It would be great if you could fix it somehow.
 
But Science Age is broken. It doesn't actually do anything.

I'm not sure what you mean, to me Science age works (a little boost and nothing much but still). It's not that amazing but it still does something, doesn't it ?
 
Perhaps, but for some reason it doesn't work in the game. I just runs down to 1 turn and stops there untill the tech is researched normally. It would be great if you could fix it somehow.

Unfortunately Yoda Power is completely correct. The Age of Science is broken in the way he describes it above. There were many discussions on that theme at CFC, one of them here: http://forums.civfanatics.com/showthread.php?t=112192

If you put Age of Science into the search function in the right Corner of the CFC page, you get many of those discussions without any problems.
The fix of the Science Age would be great, but to have a sense, first that barrier must be overcome that stops the early research in the Age of Science. Than a better rate than 1,25 % and may be a longer age would be nice.

Antal 1987, another important fix for C3C would be the fix of the broken army in C3C. With the changes by the update for armies the AI is not longer able to use them properly.
A highly useful patch would be a patch that allows worker-armies. The micromanagement of workers, especially on big maps, is highly time consuming . If possible it would be really great if many workers could be closed together to do the work with only one command but with the effectivness of the bigger number of workers included in that group (=army).

http://forums.civfanatics.com/showpost.php?p=12349887&postcount=470
http://forums.civfanatics.com/showpost.php?p=12350149&postcount=471
http://forums.civfanatics.com/showpost.php?p=12350822&postcount=473
 
I'm not sure, but there is something weird about Science Age.

To test Science Age I've modified code to have 3.00 multiplier of total science income instead 1.25.

In my current game, default research time was 2 turns (as drown on the right bottom panel)
I set Min Research Time to 1.
Once I changed Science Age Status to 1 and Science Age End to 1000 the Game said it's now 1 turn to complete. "OK", I thought and pressed Skip Turn Button. Advance was still undiscovered. Then I skipped turn again. Only after 2-nd skip, the advance became discovered.

As it turned out calculations of total science income [when game is rendering left bottom panel and when it's processing end of turn] are made separately. In each case the multiplier is used. But somehow incorrect behavior occurs

Here is the test patch with multiplier = 3.00
Civ3Conquests_p2
 
I'm not sure, but there is something weird about Science Age.

Once I changed Science Age Status to 1 and Science Age End to 1000 the Game said it's now 1 turn to complete. "OK", I thought and pressed Skip Turn Button. Advance was still undiscovered.

Yes Antal1987, this is the problem, exactly as Yoda Power did describe it. :yup:
 
Yes Antal1987, this is the problem, exactly as Yoda Power did describe it. :yup:

I've realized what was the matter. Have a look at the code. It's part of the function I called:
void __thiscall class_Leader::Calculate_Research(class_Leader *this)

For test purspose I used a saved game with following results:
- Current Research ID = 0x44 (Space)
- Science Age Activated
- Science_Age_Ratio = 3.00
- Current Total Research Bulbs before skip turn = 0
- Turns to complete research drawn by the game = 1
- Total Research Bulbs calculated after skip turn button pressed but before the following code executes = 6934. It is sum of all cities commerce+improvements bulbs + sum of all scientists bulbs

....
_Total_Science_Income = 0;
for ( i = 0; i <= Cities.LastIndex; ++i )
{
_City = class_Base_List::Get_Item(&Cities, i);
if ( _City && LOBYTE(_City->Body.CivID) == _this->ID )
_Total_Science_Income += class_City::Get_Economy_Component(_City, 1, 0);// +=_City->Get_Science_Income() - its how much scientists get additional bulbs
}
_Total_Bulbs = class_Leader::Calculate_Cities_Science(_this) + _Total_Science_Income;
// class_Leader::Calculate_Cities_Science(_this) calculates total cities commerce+improvements bulbs without scientists bulbs
// class_Leader::Calculate_Cities_Science returns 6934
// _Total_Science_Income = 0 (I have no citizens-scientists)
// _Total_Bulbs = 6934 = _this->Research_Bulbs
if ( _this->Science_Age_Status & 1 && Current_Turn <= _this->Science_Age_End )
_Total_Bulbs = (_Total_Bulbs * Science_Age_Ratio); _Total_Bulbs = 20802 = 6934 * 3
if ( _Total_Bulbs > 0 )
{
_Bulbs = _this->Research_Bulbs; // Research_Bulbs already calculated, = 6934
++_this->Current_Research_Turns;
// And here is the bug: it should be equal to 20802 instead of 6934
if ( _Bulbs >= class_Leader::Calc_Research_Bulbs_Cost(_this, _this->Current_Research_ID, 0) )
{
_AdvanceID = _this->Current_Research_ID;
if ( _AdvanceID != -1 || (_AdvanceID = (_this->vtable->m22)(_this, 1), _AdvanceID != -1) )
{
if ( f_Is_Net_Game() )
class_Net_Game_Data::Set_Advance(&Net_Game_Data, _this->ID, _AdvanceID, 1, 1, 1);
else
// A new advance is discovered here
class_Leader::Set_Advance(_this, _AdvanceID, 1, 1, 1);
}
...

The bug contains the following error:
_this->Research_Bulbs has been already updated. Now it takes into account total civ bulbs income without considering Science Age Ratio.
i.e. _this->Research_Bulbs = Previous_Turn_Research_Bulbs + Current_Turn_Research_Bulbs

And it should be:
_this->Research_Bulbs = Previous_Turn_Research_Bulbs + (if Science Age is active) ? Current_Turn_Research_Bulbs * Science_Age_Ratio : Current_Turn_Research_Bulbs.

But inside this function _this->Research_Bulbs cannot be recalculated because we already don't know previous turn research bulbs value (it hasn't been saved anywhere)

The only fix could be is:
_this->Research_Bulbs += Current_Turn_Research_Bulbs * (Science_Age_Ratio - 1)
and only after that:
if ( _Bulbs >= class_Leader::Calc_Research_Bulbs_Cost(_this, _this->Current_Research_ID, 0) )
...

Now I've no idea how to fix it in assembler mode. There is too little space to add nessesary instructions
 
Fortunately, exe file has direct data and functions pointers. So the problem theoretically might be fixed e.g. by using jumps to unused space within exe-file location space and returning jumps.
Because of direct pointers address in jump command can be specified also directly.

But it's really hard kind of work
 
Try this:
Patch_v3

(it's for C3C v1.22)

I think I did it! Not so graceful as I wanted: I used free space in PE-header block alignment :D

To be guru I should've placed fix insctuctions into the code segment. I already know, what function can be signally shrinked to release the space.
So it's not far off.
Becides, it would also release some space for another assembled patches.

There is also save game to test it. I've already described initial conditions (see).

So, that patch has multiplier from the previous version (3.00).

Having that described conditons it should take only 1 turn to complete current research (Space) with zero bulbs at the start.
 

Attachments

  • Civ3Conquests_p3.zip
    1.2 MB · Views: 464
  • _Test_Science_Age.zip
    335 KB · Views: 342
Fantastic job Antal1987! Thank you for these patches.
I second the idea of Civinator for an army of workers and do you think is it possible to break these limitations of civ3:
- no more than 32 luxuries/strategic resources
- no more than 256 buildings+wonders

An other suggestion: recon aircraft should be intercepted by fighters like bombers are
 
- no more than 32 luxuries/strategic resources
see

It's location-related limitations that's the problem.
I know about at least 1 limitation (see the link above). Theoretically It can be only overpassed, not fixed (like if resource type count > 32 and fist 32 items are strategic and luxury, and the other are unsignificant resources). And this limitation activates only if the city are not in the trade net.

I'm gonna create a tool to add some fake resource types (by copy/paste) in runtime and test it.

- no more than 256 buildings+wonders
see

That limit can neither be fixed nor overpassed. Unfortunately.

An other suggestion: recon aircraft should be intercepted by fighters like bombers are
I've never investigate combat units' commands functions. I suppose there is a function per a command like interception.

And I need prepared saved game to test it fast (for C3C v1.22 of course).
 
Antal, since you are on a roll we will just keep throwing out ideas.

First, it is appreciated that you made versions of the new .exe both with the No-Raze patch and without the no-raze. There are some games it is appropriate for and others that it is not. :goodjob: Also, be advised that the no city-limit patch causes a crash for the player when he accesses the Preferences screen.

A few items come to mind:

-Civinator mentioned the Armies which are not utilized well by the computer in Conquests. The extra movement point that the army receives prevents the computer from loading multiple units with the same movement points (for example, three knights). If the extra army movement could be removed as it was in regular Civ 3, that should help.

-The computer's failure to use artillery well comes from its unwillingness to bring artillery out of their cities, and to always run away when enemy units get close. I wonder if there are clues to this behavior?

Again, thanks for the great work that you are doing.
 
Has anyone checked to see if the patches will work on the Mac as well as a Windows box? Antal is really coming up with a lot of good stuff.
 
Top Bottom