
Continuing to disassemble Caesar III © (Game mechanics)
The algorithms for obtaining the textures of Caesar III © and drawing the city have been disassembled, there remains the “sweetest” part, which has attracted the “ancient Roman architects” for more than 15 years - the game logic. Using various approaches to the analysis of the game, I bring to your judgment the result of this small study. I apologize in advance for a long article, but as they say, you won’t erase words from a song. In conclusion, there will be a few words about the fate of the sources restored from the executable file of the original game.

A bit of history
The game is written in C, and is available for Windows and Mac. The official release took place in October 1998. Most likely for Windows the game was compiled in Visual Studio 97; studio 6 had not yet gained popularity at that time. In 1999, the game was updated to version 1.0.0.3, already compiled on Visual Studio 6, which was most widely used; patch 1.1 (c3 1.0.1.0) was later released for English-language versions of the game.
Date compiled: Fri, September 3, 1999, 7:31:17 AM
Linker version: 6.0
Machine type: Intel 386 or later processors and compatible processors
PE format: PE32
Subsystem: The Windows graphical user interface (GUI) subsystem
Min OS: Windows 95
Min OS version : 4.0
Subsystem version: 4.0
File version: 0.0
Also, fans of the game have modified executable files to run on high-resolution screens . The game uses the graphic engine of the second part, there are also screenshots from the intermediate (maybe debugging) version, where elements of the old graphic design are visible. Caesar II Caesar III (Alpha) Pay attention to the road, fishing boats and a warehouse. Caesar III (Final) And now, in more detail, I’ll start with the fact that in the game many variables are hardcoded in the code in the form of “magic numbers”, the given code examples are taken from the c3_rev directory








, the sources are compiled and run in debug mode, you can view the logic in steps. Judging by the nickname, our compatriot is engaged in maintenance, who finished the source code to a working state.
Our valiant localizers, when russified the game, edited the binary code of the executable file, replacing c3.eng with c3.rus, simultaneously breaking compatibility with later patches.
Text resources / Localization
Most of the text of the game, except for text data for missions, is located in the files C3.eng / C3_mm.eng The
file C3.eng contains descriptions of buildings, events, residents, etc. It consists of a header, 28 bytes long, and an index table, 8000 bytes long. The index table contains the offsets at which the text for the selected index is located. The algorithm for obtaining text from the localization file is such as to obtain text, for example, for the title of the window of the education adviser with the index TITLE_ADVISOR_EDUCATION (16), you should select the 16th element from the array of indices and read the characters to the final 0 by the obtained offset.
User Interface
The sizes of user interface elements, with the exception of buttons, are specified in the code. Therefore, you cannot drag the info window or help. First, the window background was drawn, and then the elements accompanying it.

The buttons in the game have a fixed height and are drawn using three textures, the middle texture is repeated to fill the body of the button. For example, the button is in its normal state.
+
+ 
Windows are drawn using the following algorithm: drawn window edge spetsalno textures, the center is filled with a seamless texture
+
+ 
+
+ 
+
+ 
Small Parts huge mechanism
The game consists of a large number of subsystems (water availability, building conditions, education, entertainment, etc.), each of which, when examined in detail, turns out to be very simple, and the description of its functioning fits into several paragraphs. The joint work of these "gears" gives an exciting gameplay with good balance. It should be noted that these subsystems practically do not interact with each other (the location of the theater does not affect the neighboring school or market, the doctors do not know anything about the actors passing by). The common point of influence is at home, which accumulate the effects of subsystems: the greater their number becomes available to the house, the higher its level. The level of the house in absolute terms comes down to the amount of taxes paid and the number of workers available.
Routes

The routes of different types of citizens differ, for example, the prefect (engineer) route will consist of the path A1-A2-A1, even if point A2 is in the entrance zone to the prefecture, after which it will return to the base, while the hairdresser will complete the tour of the territory, reaching point B2 . Attendants move exclusively on roads (bridges, gates, barns, northern warehouse tiles, gardens and grounds at forts). Enemies and wild animals cannot pass through the gates. Merchants and mega porters can ride on the road, but prefer to travel on the road to their destination, if possible. Porters cannot walk through gardens and forts.

Buildings have an exit point, which may not coincide with the entry point. The appearance priority is shifted down, the input priority is up, there can be a very long way between the entry and exit points.
Below I have given the maximum length of the routes of the residents of the city, switching between short and long routes occurs under different conditions, I have not yet figured out everything. A merchant, for example, includes a long route if there is a barn near the market.
The bypass route is calculated before entering the area. Before starting the selection of the “optimal” route, a map of possible paths is constructed from the point of exit of the worker in all directions of road distribution. Further, each path obtained is covered in tiles and buildings in the working area of the worker are questioned about the need for his services. For this indicator, the marshout is selected on which the services of the worker are more in demand.

For example, the prefect will go to the area with the highest level of fire hazard. But the difficulty is that he will not go to small clusters of houses, even if there will be a maximum level of fire, but will go to a large area in which the level of fire hazard is still acceptable. This is because the total level in a large area will exceed this figure in a small area. The same applies to other service workers, as the algorithm for calculating the importance of the path is unified for using different types of service.
An exception is the behavior of a trader who, when plotting a route, takes into account goods on the market. The following image shows the possible paths that a trader can take, each intersection increases the number of routes for processing. At the end, a white march will be chosen, since it will sell the maximum amount of goods from the market. When the trader reaches the endpoint of the selected route, if she has no goods left, she will search for the nearest route to the market, and if the goods remain, she will go back along the same route.

House evolution
Houses with a level lower than an insula of one tile can be combined with neighbors, then a house of the same level with a size of 2x2 tiles is obtained. An additional condition for combining houses is the coincidence of the first three bits of pseudorandom numbers from the byte minimap_info array [26244] , which is used to generate minimaps, so not all huts in the city could be combined.
-> 
Further, when a certain level is reached, when the size of the house of the next level is larger than the current one, the neighboring territory is captured.
Medium insula -> Large insula (1 × 1 -> 2 × 2)
-> 
Medium villa -> Large villa (2 × 2 -> 3 × 3)
-> 
Medium palace -> Large palace (3 × 3 -> 4 × 4)
->
The following tiles are available for expansion (empty plot, garden, single house below level or the same level). Expansion of the house is permitted in four directions (north, west, south and east).
City
population. The population in the city is divided by age from 0 to 99 years. Each house contains an array of char peoples [100], which shows how many inhabitants and how old are in this house (the index of the array corresponds to the age of the inhabitants, the value of the element corresponds to the number of inhabitants of a given age). At the beginning of each year, the elements of the array are shifted by one element, thus long-livers are removed and a cell for newborns is added. Functions are invoked that calculate the possibility of the appearance of children in the house and the natural decline in the population of the house from old age.
Consumption of services and resources.
Homes consume resources (food, dishes, oil, furniture, wine) and services (religion, healthcare, education, etc.). Food consumption occurs once a month at the rate of 0.5 units of food per inhabitant of the house, consumption of other resources occurs 2 times a month, 1 unit per house, excluding the number of inhabitants. Consumption of services occurs every day, one 1 unit. service, a house of any level stores no more than 100 units of each service, so they need constant updating. The storage of food and resources, on the contrary, depends on the level of the house: the larger the house, the more resuses of various types it can store, in the game the house purchases goods from the merchant for the next six months.
Religion





The game has five gods (Ceres, Neptune, Mars, Mercury and Venus). The mood calculation algorithm is the same for everyone. Coverage of a city is considered by population, and not by territory, i.e. all temples can stand whatever they like on the attitude of the gods this will not affect. The mood of the houses served by the priests of these temples depends on the location of the temples. Percentage of coverage is calculated using the following formula
Base_value = 100 * (500 * number of oracles + 750 * working_small_churches + 1500 * working_larger) / number_of people.
Under the concept of “working,” those temples fall where there is at least one worker.
Additional factors affecting the attitude of the deity.
Festival_Factor = 12 - max (40, months_from_Last_Fest_For_this_Godhood)
The factor of temples = 50. He will receive the deity whose number of temples in the city is maximum, if there are several, then this factor is reset for everyone.
Non-Respect Factor = -25. He will receive the deity who has the least temples in the city. If there are several such deities, then this factor is reset for everyone.
Venus does not participate in the distribution of bonuses. Probably a bug.
Final_setting = Base_value + Festival_factor + Temple factor + Non-respect factor.
Limitations of the minimum mood values depending on the population of the city.
The mood of the gods
Each game day (25 ticks), the mood of each god is counted. The deity has a current mood and true, with each update, the current mood approaches true by 1 unit. Example, we displeased Mars with something and do not seek to fix it, let the current mood of Mars be equal to 100, and the true one - 0. Every day, the current mood of the god of war will decrease by 1 unit. until it reaches 0. In the gaming month, 16 days, it turns out that our city of Mars will punish through (100/16), somewhere after six months of playing time, maybe because there is still a “sacred random” (before which not every Roman God can resist).






Under the spoiler, I described the calculation of points of anger (they are displayed in the form of lightning next to the mood of the deity in the window of the religious adviser, who played Caesar will definitely remember)
Each game month (16 * 25 = 900 ticks), additional logic is performed that determines the appearance of anger and / or blessing of the gods.
Festivals / Mood in the city

There are 3 types of festivals available in the game: small, medium and large. The festival is dedicated to one of the gods, the festival held affects the attitude of the deity to the city. The formulas for calculating the costs of the festival are shown in the table.
In addition to increasing the mood of the deity to whom the festival is dedicated, after its holding, the attitude of citizens to the ruler also improves. In 12 months you can hold 2 festivals that will bring an increase in mood, the following festivals held will not give an increase in mood in the city. The table shows the values by which the mood in the city increases.
Finance The
maximum debt of the city, under which you can still build something to build is -5000 denarii. This condition is checked with every finance action.
The annual salary for the workers that you set on the screen of the labor adviser is 1/10 of the specified value in denarii. The number 30 means the payment of 3 denarii to the employee per year, this is due to the fact that in the game financial calculations are carried out in whole numbers.

Every month, workers are paid salaries according to a simple formula.
Zp_v_ denarii = (number of employees at the end of the month) * (zp_worker) / 10/12
This amount is taken from the treasury of the city to nowhere, for example, in Tropiko the money went into the wallets of the residents, but this is a completely different story.
If the city is in debt, i.e. the amount displayed in the upper menu is less than 0, then the city begins to pay interest to Rome, a kind of loan.
The interest rate of the loan is 10% and is deducted from the treasury of the city every month.
repayment = (-money_of_request) * 10/100/12
When reaching 5000 debt for the first time, Rome gives a loan (depending on the mission, usually 10000 days), the second time the amount can also be received, but it is already taken into account as a loan.
Taxes

Every month, houses in the city generate a tax, which depends on the level of the house and the number of people living in it. The tax from the house is collected when a tax collector passes by, at the beginning of the new year, the amount for the previous year burns out if it was not collected. The level of taxes is set in the configuration file c3_model.txt, the level of complexity in the city is also affected by the level of complexity:
The final formula for calculating taxes from home looks like this.
Total Taxes (Dn) = (tax_base / 2) * (percentage_city_of_city) / (12 * 100 (
Submit Empire)
At the end of the year, the city sends part of the income to Rome, the payment depends on the profit and the number of inhabitants in the city. In the game, profit is the difference between income and expenses.The tax rate is 25%, if the city is in debt, then the tax is not paid, but the emperor’s good will is reduced.
Also, the minimum value of the tax is determined by the population of the city.
Emperor's favor The emperor’s

attitude to the ruler and city ratings play a big role in the successful completion of the mission. The greatest influence on the emperor’s mood is played by such parameters as “city profitability” and fulfillment / ignoring of the emperor’s requests.
Gifts significantly increase the emperor’s opinion of you, but their influence is seriously reduced with frequent gifts. When calculating the change in goodwill, all gifts made over the past 12 months are taken into account, they are listed in the table.
Fulfillment of requests, at the time set by the emperor, gives a certain increase in favor. If the request is completed later than the time set by Caesar, you will receive only half the reward, and if you ignore it, you will completely lose respect by 8 units: 3 units will be lost if the request cannot be completed within the specified time, another 5 will be withdrawn if the request is ignored within 24 months after deadline.
In addition to the plot requests and gifts, the update of the favor value is performed at the beginning of each year and depends on the following factors:
Base change = -2
Successful payment of tax = +1 if paid successfully, -3, -5 and -8 if one was not paid, two or more two years, respectively.
Salary= +1 if the salary is less than the salary of the current ruler’s level, and -1 for each rank above your level
Events = depends on the missions, for example, +5 upon reaching a population of 1000 inhabitants
Culture

rating The culture rating in the game is a collective rating, by which you can judge attractiveness of the city. It consists of the level of coverage of the city with theaters, temples, schools, academies and libraries. Indirectly, by the presence of the educational component (the level of culture is more than 30), we can understand that there are wealthy citizens in the city.
Culture_ Rating = Theater_ Rating + Temple_ Rating + Library_ Rating + School_ Rating + Academic_ Rating

The rating of the theaters corresponds to the ratio of theater capacity to the number of residents regardless of their location.
Theater_ Rating = 500 * number of working_theaters / population. In accordance with this coverage, a rating is selected.


The rating value of theaters corresponds to the ratio of the capacity of the temples to the number of residents, regardless of their location.
Rating of temples = 150 * Number of small_ temples + 300 * Number of large_ temples + 500 * Number of oracles.
As with theaters, the rating value is selected from the table.
Education



Schools bring a maximum of 15 culture points, the calculation is made for residents of school age, each school accommodates 75 students.
Academies add 10 culture points, the calculation is made for residents of student age, the Academy trains 100 students.
Libraries have 20 points, which are calculated by the total number of inhabitants, one library can serve up to 800 residents.
The dependence of culture points on the level of coverage of the city is shown in the table.
Resources and production






The basis of the game’s economy is resources, some resources require processing, so simple production chains appear, for example, an iron mine -> weapons. The resources in the game are inexhaustible, with the exception of fishing spots that have a finite number of fish.
Wheat is the first resource the game introduces you to. In the central provinces, wheat farms are more effective than other farms, but this does not work in northern and desert regions. Farms are placed on fertile soil, which is shown on the map as yellow shoots. Harvest will be transported to the barn or warehouse. Farms, mining buildings and workshops work according to the same scheme, every 25 ticks (once per game day), production progress is updated according to the following formula:
At the end of production, a porter is created with the goods, which will deliver it to the nearest warehouse. If it is impossible to deliver the goods, he will stand near the production. If the porter is busy and the new product has already been produced, then production stops until the porter is released.
Storage and distribution of resources


Two types of storage are involved in the storage and distribution of resources: barns and warehouses, barns store only products and market traders receive goods from barns, warehouses store goods of any type and can sell them to merchants. Vaults stop accepting goods if the number of employees is less than half, vaults do not participate in the delivery of goods, except for the special “receive goods” mode, in which case the vault starts receiving goods from other vaults, so in the game you can create a chain of movement of goods from one area of the map in another.
The combination of resource extraction, processing and marketing of goods turned out to be quite developed. A small number of goods does not tire the player with micromanagement, and the automation of most of the routine actions, such as choosing storage and distribution locations, leaves the ruler room for strategic planning.
At this point, I will probably finish the article, such topics as trade between cities and military operations remained overboard, each of them is quite large, and there is still not enough material. Thank you for your attention,
ZYAt the end of the article I want to say that fans of the game can certainly add many more points that I did not find or did not pay attention to when restoring the source code of the original game. It was important for me to get general ideas about game logic, so as not to mess up with the balance so carefully polished by the original authors. As for the restored sources, there was not enough patience to bring them to their normal (just to compile) look, but there was a kind person (AntonBaracuda, github.com/AntonBaracuda/opencaesar3/c3_rev ) who completed this really hard work. At the specified address you will find the source and partially structured files and some functions, all this is compiled and launched, you can go through the first functions in the debugger.
References
Site of the Russian-speaking community
English-language site with a lot of materials on the game
Restoring the source code of the original game (compiled, but not launched)
CaesarIA: remake of the game (opensource, c ++, SDL) (Window, Linux, Mac, Haiku, Android)

A bit of history
The game is written in C, and is available for Windows and Mac. The official release took place in October 1998. Most likely for Windows the game was compiled in Visual Studio 97; studio 6 had not yet gained popularity at that time. In 1999, the game was updated to version 1.0.0.3, already compiled on Visual Studio 6, which was most widely used; patch 1.1 (c3 1.0.1.0) was later released for English-language versions of the game.
Date compiled: Fri, September 3, 1999, 7:31:17 AM
Linker version: 6.0
Machine type: Intel 386 or later processors and compatible processors
PE format: PE32
Subsystem: The Windows graphical user interface (GUI) subsystem
Min OS: Windows 95
Min OS version : 4.0
Subsystem version: 4.0
File version: 0.0
Also, fans of the game have modified executable files to run on high-resolution screens . The game uses the graphic engine of the second part, there are also screenshots from the intermediate (maybe debugging) version, where elements of the old graphic design are visible. Caesar II Caesar III (Alpha) Pay attention to the road, fishing boats and a warehouse. Caesar III (Final) And now, in more detail, I’ll start with the fact that in the game many variables are hardcoded in the code in the form of “magic numbers”, the given code examples are taken from the c3_rev directory








, the sources are compiled and run in debug mode, you can view the logic in steps. Judging by the nickname, our compatriot is engaged in maintenance, who finished the source code to a working state.
Our valiant localizers, when russified the game, edited the binary code of the executable file, replacing c3.eng with c3.rus, simultaneously breaking compatibility with later patches.
Main function code (restored)
int main(int argc, char* argv[] )
{
int result; // eax@2
signed int v5; // [sp+4Ch] [bp-20h]@7
struct tagMSG Msg; // [sp+50h] [bp-1Ch]@21
HINSTANCE hInstance = GetModuleHandle(0);
byte_6606BC = 0;
if ( fun_loadSettings() )
{
if ( fun_readLanguageTextFiles("c3.eng", "c3_mm.eng") )
{
fun_loadDefaultNames();
fun_logDebugMessage("OK :Game text loaded.", 0, 0);
if ( fun_setupMainWindow(hInstance) )
{}
.... //some code
}
}
}
Text resources / Localization
Most of the text of the game, except for text data for missions, is located in the files C3.eng / C3_mm.eng The
file C3.eng contains descriptions of buildings, events, residents, etc. It consists of a header, 28 bytes long, and an index table, 8000 bytes long. The index table contains the offsets at which the text for the selected index is located. The algorithm for obtaining text from the localization file is such as to obtain text, for example, for the title of the window of the education adviser with the index TITLE_ADVISOR_EDUCATION (16), you should select the 16th element from the array of indices and read the characters to the final 0 by the obtained offset.
Description of the title and element of the index table
struct C3EngHeader
{
char tag[16]; //описание файла
int numGroups ; //количество групп в файле
int numStrings ; //колическтво строк в файле
int unknown ;
};
struct C3EngIndexEntry
{
int offset; //смещение до строки
int inUse;
};
User Interface
The sizes of user interface elements, with the exception of buttons, are specified in the code. Therefore, you cannot drag the info window or help. First, the window background was drawn, and then the elements accompanying it.

Here's an example of handling clicks in the scrollbar area
int fun_dialogFile_handleScrollbarClick()
{
signed int result; // eax@2
int v1; // ST60_4@15
int v2; // [sp+4Ch] [bp-10h]@5
int v3; // [sp+50h] [bp-Ch]@13
if ( filelist_numFiles > 12 )
{
if ( mouse_isLeftClick )
{
v2 = filelist_numFiles - 12;
if ( mouseclick_x >= screen_640x480_x + 464 )
{
if ( mouseclick_x <= screen_640x480_x + 496 )
{
if ( mouseclick_y >= screen_640x480_y + 145 )
{
if ( mouseclick_y <= screen_640x480_y + 300 )
{
v3 = mouseclick_y - (screen_640x480_y + 145);
if ( mouseclick_y - (screen_640x480_y + 145) > 130 )
v3 = 130;
v1 = fun_getPercentage(v3, 130);
filelist_scrollPosition = fun_adjustWithPercentage(v2, v1);
window_redrawRequest = 1;
result = 1;
}
else {result = 0;}
}else{result = 0;}
}else{result = 0;}
}else{result = 0;}
}else{result = 0;}
}else {result = 0;}
return result;
}
The buttons in the game have a fixed height and are drawn using three textures, the middle texture is repeated to fill the body of the button. For example, the button is in its normal state.



Windows are drawn using the following algorithm: drawn window edge spetsalno textures, the center is filled with a seamless texture









Small Parts huge mechanism
The game consists of a large number of subsystems (water availability, building conditions, education, entertainment, etc.), each of which, when examined in detail, turns out to be very simple, and the description of its functioning fits into several paragraphs. The joint work of these "gears" gives an exciting gameplay with good balance. It should be noted that these subsystems practically do not interact with each other (the location of the theater does not affect the neighboring school or market, the doctors do not know anything about the actors passing by). The common point of influence is at home, which accumulate the effects of subsystems: the greater their number becomes available to the house, the higher its level. The level of the house in absolute terms comes down to the amount of taxes paid and the number of workers available.
Routes

The routes of different types of citizens differ, for example, the prefect (engineer) route will consist of the path A1-A2-A1, even if point A2 is in the entrance zone to the prefecture, after which it will return to the base, while the hairdresser will complete the tour of the territory, reaching point B2 . Attendants move exclusively on roads (bridges, gates, barns, northern warehouse tiles, gardens and grounds at forts). Enemies and wild animals cannot pass through the gates. Merchants and mega porters can ride on the road, but prefer to travel on the road to their destination, if possible. Porters cannot walk through gardens and forts.

Buildings have an exit point, which may not coincide with the entry point. The appearance priority is shifted down, the input priority is up, there can be a very long way between the entry and exit points.
Below I have given the maximum length of the routes of the residents of the city, switching between short and long routes occurs under different conditions, I have not yet figured out everything. A merchant, for example, includes a long route if there is a barn near the market.
Resident Type | Route length long / short (in tiles) |
Prefect, Engineer | 52/43 |
Actor, Gladiator, Tamer, Tax Collector | 43/35 |
Priest, Doctor, Surgeon, Teacher, Tradeswoman, Bath attendant, Hairdresser | 35/26 |
The bypass route is calculated before entering the area. Before starting the selection of the “optimal” route, a map of possible paths is constructed from the point of exit of the worker in all directions of road distribution. Further, each path obtained is covered in tiles and buildings in the working area of the worker are questioned about the need for his services. For this indicator, the marshout is selected on which the services of the worker are more in demand.

For example, the prefect will go to the area with the highest level of fire hazard. But the difficulty is that he will not go to small clusters of houses, even if there will be a maximum level of fire, but will go to a large area in which the level of fire hazard is still acceptable. This is because the total level in a large area will exceed this figure in a small area. The same applies to other service workers, as the algorithm for calculating the importance of the path is unified for using different types of service.
An exception is the behavior of a trader who, when plotting a route, takes into account goods on the market. The following image shows the possible paths that a trader can take, each intersection increases the number of routes for processing. At the end, a white march will be chosen, since it will sell the maximum amount of goods from the market. When the trader reaches the endpoint of the selected route, if she has no goods left, she will search for the nearest route to the market, and if the goods remain, she will go back along the same route.

House evolution
Houses with a level lower than an insula of one tile can be combined with neighbors, then a house of the same level with a size of 2x2 tiles is obtained. An additional condition for combining houses is the coincidence of the first three bits of pseudorandom numbers from the byte minimap_info array [26244] , which is used to generate minimaps, so not all huts in the city could be combined.


Further, when a certain level is reached, when the size of the house of the next level is larger than the current one, the neighboring territory is captured.
Medium insula -> Large insula (1 × 1 -> 2 × 2)


Medium villa -> Large villa (2 × 2 -> 3 × 3)


Medium palace -> Large palace (3 × 3 -> 4 × 4)


The following tiles are available for expansion (empty plot, garden, single house below level or the same level). Expansion of the house is permitted in four directions (north, west, south and east).
City
population. The population in the city is divided by age from 0 to 99 years. Each house contains an array of char peoples [100], which shows how many inhabitants and how old are in this house (the index of the array corresponds to the age of the inhabitants, the value of the element corresponds to the number of inhabitants of a given age). At the beginning of each year, the elements of the array are shifted by one element, thus long-livers are removed and a cell for newborns is added. Functions are invoked that calculate the possibility of the appearance of children in the house and the natural decline in the population of the house from old age.
Hidden text
void fun_gametick_population()
{
...//some code
cityinfo_happiness_immigrationAmount[4517 * ciid] = 0;
cityinfo_happiness_emigrationValue[4517 * ciid] = 0;
if ( cityinfo_populationYearlyBirthsDeathsCalculationNeeded[4517 * ciid] )
{
fun_populationAdvanceAgesOneYear();
fun_populationBirths();
fun_updatePopulationAfterBirthsDeaths(ciid);
}
fun_calculateNumberOfWorkers();
....// some code
}
Consumption of services and resources.
Homes consume resources (food, dishes, oil, furniture, wine) and services (religion, healthcare, education, etc.). Food consumption occurs once a month at the rate of 0.5 units of food per inhabitant of the house, consumption of other resources occurs 2 times a month, 1 unit per house, excluding the number of inhabitants. Consumption of services occurs every day, one 1 unit. service, a house of any level stores no more than 100 units of each service, so they need constant updating. The storage of food and resources, on the contrary, depends on the level of the house: the larger the house, the more resuses of various types it can store, in the game the house purchases goods from the merchant for the next six months.
Religion





The game has five gods (Ceres, Neptune, Mars, Mercury and Venus). The mood calculation algorithm is the same for everyone. Coverage of a city is considered by population, and not by territory, i.e. all temples can stand whatever they like on the attitude of the gods this will not affect. The mood of the houses served by the priests of these temples depends on the location of the temples. Percentage of coverage is calculated using the following formula
Base_value = 100 * (500 * number of oracles + 750 * working_small_churches + 1500 * working_larger) / number_of people.
Under the concept of “working,” those temples fall where there is at least one worker.
Additional factors affecting the attitude of the deity.
Festival_Factor = 12 - max (40, months_from_Last_Fest_For_this_Godhood)
The factor of temples = 50. He will receive the deity whose number of temples in the city is maximum, if there are several, then this factor is reset for everyone.
Non-Respect Factor = -25. He will receive the deity who has the least temples in the city. If there are several such deities, then this factor is reset for everyone.
Venus does not participate in the distribution of bonuses. Probably a bug.
Final_setting = Base_value + Festival_factor + Temple factor + Non-respect factor.
Limitations of the minimum mood values depending on the population of the city.
Population | Minimal mood |
0-99 | fifty |
100-199 | 40 |
200-299 | 40 |
300-399 | thirty |
400-499 | 20 |
400-499 | 10 |
> 500 | 0 |
The mood of the gods
Each game day (25 ticks), the mood of each god is counted. The deity has a current mood and true, with each update, the current mood approaches true by 1 unit. Example, we displeased Mars with something and do not seek to fix it, let the current mood of Mars be equal to 100, and the true one - 0. Every day, the current mood of the god of war will decrease by 1 unit. until it reaches 0. In the gaming month, 16 days, it turns out that our city of Mars will punish through (100/16), somewhere after six months of playing time, maybe because there is still a “sacred random” (before which not every Roman God can resist).






Under the spoiler, I described the calculation of points of anger (they are displayed in the form of lightning next to the mood of the deity in the window of the religious adviser, who played Caesar will definitely remember)
Hidden text
if( god.mood < 50 )
{
god.blessing = 0
god.blessingDone = 0
}
if(god.mood > 50 )
{
god.small_curse = 0
god.smallCurseDone = 0
}
god_id = random( 7 );
if( god_id < 5 )
{
current_god = romeGods[ god_id ] // (Ceres/Neptune/Mercury/Mars/Venus)
if( current_god.mood >= 50 )
current_god.wrathPoints = 0;
if( current_god.mood >= 9 and current_god.mood < 10 )
current_god.wrathPoints += 5;
if( current_god.mood >= 10 and current_god.mood < 20 )
current_god.wrathPoints += 2;
if( current_god.mood >= 20 and current_god.mood < 40 )
current_god.wrathPoints += 1;
}
current_god.wrathPoints = min( current_god.wrathPoints, 50)
Each game month (16 * 25 = 900 ticks), additional logic is performed that determines the appearance of anger and / or blessing of the gods.
Hidden text
if( god_id == [5, 6, 7] )
{
//ищем самого гневливого бога, с максимальным число очков гнева или с настроением менее 40 или случайного, если не нашлось гневных
current_god = find_least_happy_god();
if( current_god )
{
if( current_god.mood > 100 and current_god.blessingDone == 0 )
{
current_god.doBlessing()
current_god.mood = 50
current_god.blessingDone = 1
}
if( current_god.wrathPoints > 20 and current_god.smallCurseDone == 0 )
{
current_god.doSmallCurse()
current_god.smallCurseDone = 1
current_god.wrathPoints = 0
current_god.mood -= 12
}
if( current_god.wrathPoints == 50 and current_god.lastFesivale > 3_months )
{
current_god.doWrath()
current_god.wrathPoints = 0
current_god.mood -= 30
}
}
}
Festivals / Mood in the city

There are 3 types of festivals available in the game: small, medium and large. The festival is dedicated to one of the gods, the festival held affects the attitude of the deity to the city. The formulas for calculating the costs of the festival are shown in the table.
A type | Cost | Wine | Preparation time |
Small | population / 20 + 10 | - | 2 months |
Average | population / 10 + 20 | - | 3 months |
Big | population / 5 + 40 | population / 500 + 1 | 4 months |
In addition to increasing the mood of the deity to whom the festival is dedicated, after its holding, the attitude of citizens to the ruler also improves. In 12 months you can hold 2 festivals that will bring an increase in mood, the following festivals held will not give an increase in mood in the city. The table shows the values by which the mood in the city increases.
A type | First | Second |
Small | 7 | 2 |
Average | 9 | 3 |
Big | 12 | 5 |
Finance The
maximum debt of the city, under which you can still build something to build is -5000 denarii. This condition is checked with every finance action.
For example, when building a road
void fun_drawBuildingGhostRoad()
{
... //some code
if ( cityinfo_treasury[4517 * ciid] <= -5000 )
cannotBuild = 1;
if ( cannotBuild )
{
sub_4D0B70(graphic_fire_almost, v2, v1 - iso_tile_half_height, (ColorMask) -1949);
}
...//some code
}
The annual salary for the workers that you set on the screen of the labor adviser is 1/10 of the specified value in denarii. The number 30 means the payment of 3 denarii to the employee per year, this is due to the fact that in the game financial calculations are carried out in whole numbers.

Every month, workers are paid salaries according to a simple formula.
Zp_v_ denarii = (number of employees at the end of the month) * (zp_worker) / 10/12
This amount is taken from the treasury of the city to nowhere, for example, in Tropiko the money went into the wallets of the residents, but this is a completely different story.
If the city is in debt, i.e. the amount displayed in the upper menu is less than 0, then the city begins to pay interest to Rome, a kind of loan.
The interest rate of the loan is 10% and is deducted from the treasury of the city every month.
repayment = (-money_of_request) * 10/100/12
When reaching 5000 debt for the first time, Rome gives a loan (depending on the mission, usually 10000 days), the second time the amount can also be received, but it is already taken into account as a loan.
Taxes

Every month, houses in the city generate a tax, which depends on the level of the house and the number of people living in it. The tax from the house is collected when a tax collector passes by, at the beginning of the new year, the amount for the previous year burns out if it was not collected. The level of taxes is set in the configuration file c3_model.txt, the level of complexity in the city is also affected by the level of complexity:
Level of difficulty | Coefficient |
Very easy | 300% |
Easy | 200% |
Fine | 150% |
Difficult | 100% |
Very difficult | 75% |
The final formula for calculating taxes from home looks like this.
Total Taxes (Dn) = (tax_base / 2) * (percentage_city_of_city) / (12 * 100 (
Submit Empire)
At the end of the year, the city sends part of the income to Rome, the payment depends on the profit and the number of inhabitants in the city. In the game, profit is the difference between income and expenses.The tax rate is 25%, if the city is in debt, then the tax is not paid, but the emperor’s good will is reduced.
Revenue components | Cost components |
Donations | Construction |
Export of goods | Import of goods |
Loan interest | |
The salary of the ruler | |
Rest | |
Salaries |
Also, the minimum value of the tax is determined by the population of the city.
Population | No profit / There is profit |
0-500 | 0/50 |
501-1000 | 0/150 |
1001-2000 | 100/225 |
2001-3000 | 200/300 |
3001-5000 | 200/400 |
5000+ | 200/500 |
Emperor's favor The emperor’s

attitude to the ruler and city ratings play a big role in the successful completion of the mission. The greatest influence on the emperor’s mood is played by such parameters as “city profitability” and fulfillment / ignoring of the emperor’s requests.
Gifts significantly increase the emperor’s opinion of you, but their influence is seriously reduced with frequent gifts. When calculating the change in goodwill, all gifts made over the past 12 months are taken into account, they are listed in the table.
Gift Number | Modest | Dear | Excellent |
1 | 3 | 5 | 10 |
2 | 1 | 3 | 5 |
3 | 0 | 1 | 3 |
4 | 0 | 0 | 1 |
5+ | 0 | 0 | 0 |
Fulfillment of requests, at the time set by the emperor, gives a certain increase in favor. If the request is completed later than the time set by Caesar, you will receive only half the reward, and if you ignore it, you will completely lose respect by 8 units: 3 units will be lost if the request cannot be completed within the specified time, another 5 will be withdrawn if the request is ignored within 24 months after deadline.
In addition to the plot requests and gifts, the update of the favor value is performed at the beginning of each year and depends on the following factors:
Base change = -2
Successful payment of tax = +1 if paid successfully, -3, -5 and -8 if one was not paid, two or more two years, respectively.
Salary= +1 if the salary is less than the salary of the current ruler’s level, and -1 for each rank above your level
Events = depends on the missions, for example, +5 upon reaching a population of 1000 inhabitants
Culture

rating The culture rating in the game is a collective rating, by which you can judge attractiveness of the city. It consists of the level of coverage of the city with theaters, temples, schools, academies and libraries. Indirectly, by the presence of the educational component (the level of culture is more than 30), we can understand that there are wealthy citizens in the city.
Culture_ Rating = Theater_ Rating + Temple_ Rating + Library_ Rating + School_ Rating + Academic_ Rating

The rating of the theaters corresponds to the ratio of theater capacity to the number of residents regardless of their location.
Theater_ Rating = 500 * number of working_theaters / population. In accordance with this coverage, a rating is selected.
Coating | Culture Points |
0-30% | 0 |
31-50% | 3 |
51-70% | 8 |
71-85% | 12 |
86-99% | 18 |
100 +% | 25 |


The rating value of theaters corresponds to the ratio of the capacity of the temples to the number of residents, regardless of their location.
Rating of temples = 150 * Number of small_ temples + 300 * Number of large_ temples + 500 * Number of oracles.
As with theaters, the rating value is selected from the table.
Coating | Culture Points |
0-30% | 0 |
31-50% | 3 |
51-70% | 9 |
71-85% | 14 |
86-99% | 22 |
100 +% | thirty |
Education



Schools bring a maximum of 15 culture points, the calculation is made for residents of school age, each school accommodates 75 students.
Academies add 10 culture points, the calculation is made for residents of student age, the Academy trains 100 students.
Libraries have 20 points, which are calculated by the total number of inhabitants, one library can serve up to 800 residents.
The dependence of culture points on the level of coverage of the city is shown in the table.
Coating | Schools | Academy | Libraries |
0-30% | 0 | 0 | 9 |
31-50% | 1 | 1 | 2 |
51-70% | 4 | 2 | 4 |
71-85% | 6 | 4 | 8 |
86-99% | 10 | 7 | 14 |
100 +% | fifteen | 10 | 20 |
Resources and production






The basis of the game’s economy is resources, some resources require processing, so simple production chains appear, for example, an iron mine -> weapons. The resources in the game are inexhaustible, with the exception of fishing spots that have a finite number of fish.
Wheat is the first resource the game introduces you to. In the central provinces, wheat farms are more effective than other farms, but this does not work in northern and desert regions. Farms are placed on fertile soil, which is shown on the map as yellow shoots. Harvest will be transported to the barn or warehouse. Farms, mining buildings and workshops work according to the same scheme, every 25 ticks (once per game day), production progress is updated according to the following formula:
Formula for calculating daily production progress
productionRate - количество тележек с товаром в год при 100% загрузке
numberWorkers - число работников на данный момент
12 * 16 - число месяцев * число игрвых дней
maximumWorkers - максимальное число работников на этом производстве
progress += 100 * ( productionRate * numberWorkers) / (12 * 16 * maximumWorkers )
At the end of production, a porter is created with the goods, which will deliver it to the nearest warehouse. If it is impossible to deliver the goods, he will stand near the production. If the porter is busy and the new product has already been produced, then production stops until the porter is released.
Storage and distribution of resources


Two types of storage are involved in the storage and distribution of resources: barns and warehouses, barns store only products and market traders receive goods from barns, warehouses store goods of any type and can sell them to merchants. Vaults stop accepting goods if the number of employees is less than half, vaults do not participate in the delivery of goods, except for the special “receive goods” mode, in which case the vault starts receiving goods from other vaults, so in the game you can create a chain of movement of goods from one area of the map in another.
The combination of resource extraction, processing and marketing of goods turned out to be quite developed. A small number of goods does not tire the player with micromanagement, and the automation of most of the routine actions, such as choosing storage and distribution locations, leaves the ruler room for strategic planning.
At this point, I will probably finish the article, such topics as trade between cities and military operations remained overboard, each of them is quite large, and there is still not enough material. Thank you for your attention,
ZYAt the end of the article I want to say that fans of the game can certainly add many more points that I did not find or did not pay attention to when restoring the source code of the original game. It was important for me to get general ideas about game logic, so as not to mess up with the balance so carefully polished by the original authors. As for the restored sources, there was not enough patience to bring them to their normal (just to compile) look, but there was a kind person (AntonBaracuda, github.com/AntonBaracuda/opencaesar3/c3_rev ) who completed this really hard work. At the specified address you will find the source and partially structured files and some functions, all this is compiled and launched, you can go through the first functions in the debugger.
References
Site of the Russian-speaking community
English-language site with a lot of materials on the game
Restoring the source code of the original game (compiled, but not launched)
CaesarIA: remake of the game (opensource, c ++, SDL) (Window, Linux, Mac, Haiku, Android)