[Development] Code Rewrite

So, taking the list from above, the new priority list is:
  1. Victory.py refactoring
  2. Conqueror events refactoring
  3. Clean up and improve autoplay
  4. Clean up and improve Rise and Fall code
  5. Transition from scenarios to custom games
Updated priority list! The order is still the same.
 
Civ4ScreenShot0223.JPG

Start of 1700AD China Campaign;
Shouldn't the first goal be marked as "Failed" instead of "Not Yet"?
Progressing to the next turn does not update it.
 
So, taking the list from above, the new priority list is:
  1. Victory.py refactoring
  2. Conqueror events refactoring
  3. Clean up and improve autoplay
  4. Clean up and improve Rise and Fall code
  5. Transition from scenarios to custom games
Another progress update: I just pushed a couple of changes related to autoplay that I have detailed in the updates thread. This time it's not just code cleanup (although I also cleaned up a lot of code), but also some new features that I always wanted to do once I have a handle on the code. Fortunately they all worked pretty quickly, I hope you like them as well.

I never talked about it, but I essentially decided to drop/skip item 2 in the list. I still think this needs cleaning up, but the purposes and special cases of the different conqueror events and unit spawns are too different to easily generalise them. At least I couldn't come up with a way that didn't end up being weeks of work and it didn't seem worth that much trouble for something that is more or less working.

So next up is Rise and Fall rewrite. Finally I can start tackling this. I expect this to be a similar act of throwing out a lot of convoluted old code that isn't doing very much that is useful, and replace it with a cleaner reimplementation. Looking into the autoplay code already helped getting a handle on it. But once that is done, I will also expand on it with some mechanical changes and different spawn rules depending on the historical circumstances of a civilisation, which I have talked about a bit already in the past. However, after this burst of activity my development speed will decrease a little again.
 
Just a quick update on this, I have essentially disabled the existing Rise and Fall code and started to replace it from scratch. As of now it does the most important parts with a fraction of the code: place starting units, make sure the starting location is free from culture and adjacent cities, flip a city on the starting location if applicable (now every civ can benefit from this), flip surrounding cities, assign starting techs, reveal surrounding territory.

I already made some changes to these parts of the spawn rules. For example, instead of each civ having an especially designated (usually rectangular) area revealed at the start, it is now their core/birth area (whichever is bigger) and surrounding tiles. This gives more limited revealed territory but makes it easier to control and imo more naturally looking. Once I introduce different spawn types, they can also influence revealed territory. For example, one spawn type is periphery, where a civ arises next to another civ and gains some of their revealed territory as well. Or civs that secede from an existing civ gain vision of the civ they secede from (e.g. Byzantium from Rome). That makes it more organic and will lead to late spawning civs to have more plausible starting maps.

I also changed how starting units work by designating a bunch of unit roles (e.g. city defense, attack, counter etc.) each with rules which units can fulfill these roles. Each civ will then automatically receive their best unit of that role based on their available techs, with unique units etc. being taken into account. This makes it easier to adjust techs and have their units follow suit without much maintenance work. I will later add a way for special rules in case someone needs to be given units they cannot build (e.g. Byzantine legions) or have not researched yet (sometimes used to help the AI).

Of course a lot of things are still missing, like flip popups, and switch popups. The original code spends a lot of effort at keeping barbarians out of the spawn location out of an upcoming civ, I am currently checking without any of that to see how much of an issue that actually is. But I am already considering ways of preventing barbarians from entering tiles that are subjects to an upcoming spawn entirely.

In general, the greatest strength of the new setup is that it is now easily possible to make things happen x turns before or after a spawn. This is useful to prepare the map for the arrival of a civ (but only if it is actually about to spawn), check the spawn conditions for a civ earlier than the turn of its spawn (including adding more ways to proactively cancel some spawns depending on the type), sending a notification to affected players that a spawn is about to happen ("We are receiving news that the Latin city of Rome is on the rise among the Etruscans") etc.

In am also currently thinking about how flips and wars on spawn would work. In general, the "ask to flip and war if refused" rule doesn't seem to work that well, because for most civs both letting flips happen or refusing them feels ahistorical and there are a lot of cheeses around it (such as accept then backstab). Here is where different spawn types would come in the most. In general, I would prefer to take away the option to refuse a spawn from the player (however this would be bundled with a flip protection for owner core cities), but give them the opportunity to declare war and try to retake them. In that case, the AI would be given some advantages to make that a costly option.

However, there would be spawn types that flip the script. I am currently thinking of two: invasion is for civs that take their entire core by force (such as the Ottomans), expansion is for civs that get to flip their core, but then get help attacking further cities in their expansion area through unit spawns and maybe other combat modifiers for a few turns. This is intended for civs like the Mongols or Arabia to help fuel an initial wave of rapid expansion that is implemented as actual combat instead of just flips. Think of it as a "conqueror event" built into their spawn except that I also intend to apply to the player, without the AI bonuses. Part of that concept is that those bonuses are time limited, but may also be momentum based: if they keep having success the time is extended, if you manage to stop them early the bonuses expire early. Of course, all of this is just vague ideas but in general civs that historically rose suddenly and violently will be the most impacted, hopefully for the better.

I'll keep posting more updates here as I experiment with this, but I'll probably have to take care of more boring tedious stuff first.
 
After implementing rebirths again, I also managed to enable autoplay for reborn civilizations: you can therefore play as Iran and Colombia in the 600 AD scenario, and Iran, Colombia and Mexico in the 1700 AD scenario without switching from another civilization. It is still impossible in the 3000 BC scenario, because it's still not possible to select two different civs sharing the same slot in the player selection menu, and the same applies for Mexico in the 600 AD scenario because the Aztecs must still be selectable. Only after transitioning away from scenario files will it be possible to select civilizations entirely freely.

Another exciting mechanic I managed to explore is using Advanced Start mode. In case you are not familiar, Advanced Start is a special game mode, where at the beginning of the game you get a "gold" budget that can be used to immediately buy cities, units, improvements, techs etc. to create an accelerated start. I managed to enable it right after you spawn and flip the surrounding cities instead. I think this can be a great solution to the problem that the first couple of turns are very slow for new civs: you usually spend the time connecting the important resources, expanding your culture, and getting up essential units.

I would limit the abilities provided in that mode to adding population, culture or buildings to cities, and to place routes and improvements, because units or techs could throw the starting situation too far off. I am still unsure how much of a budget to give to specific civs, and if it should be based on the surrounding environment (e.g. to help civs where the surrounding tiles aren't well developed), but some form of this will likely make it into the mod.

Beyond that, there is still a lot to do, but most of it is accounting for all the special cases in the setup of various civilizations which need to be ported to the new implementation.
 
The change that you can start as the civs, Iran, Colombia and Mexico is very welcome.
Finally you get to play the first turn after spawn as well (not having to switch from another civ).

I don't know how much this Advanced start would help. I usually want to raze cities in the core or close by to optimize the core cities.
If money could be used for that as well it would be a nice feature though.
Also it could be nice to get a free settler settled in each flipped city (the current free buildings of the era).
 
Last edited:
I don't think that's needed, custom games essentially serve the purpose that I need. It's just that we need to set up a "map script" for them that produces the RFC scenario map.
 
So, taking the list from above, the new priority list is:
  1. Victory.py refactoring
  2. Conqueror events refactoring
  3. Clean up and improve autoplay
  4. Clean up and improve Rise and Fall code
  5. Transition from scenarios to custom games
We are getting close to completing point 4, which is the case once the riseandfall branch has been merged into develop. While not entirely free of issues and sufficiently playtested, testing can still resume inside the develop branch. For clarity, this is the roadmap:
  • Fix known issues in the develop branch
  • Wait for a few days to avoid other issues arising
  • Create another minor release version for develop
  • Merge riseandfall into develop
That way we hopefully get a relatively stable tag that people can stay at in case they do not want to deal with the rise and fall changes just yet. I hope to reach that point before or just around the holidays.
 
So, taking the list from above, the new priority list is:
  1. Victory.py refactoring
  2. Conqueror events refactoring
  3. Clean up and improve autoplay
  4. Clean up and improve Rise and Fall code
  5. Transition from scenarios to custom games
The new Rise and Fall implementation has been merged into the develop branch.

I actually started working on the fifth and last point in parallel. Some things that I thought would be a problem went without much trouble, but there are other unexpected problems to solve. Still, I currently feel quite positive about it. No idea how long it will take overall.
 
Status report: I entirely recreated the 3000 BC scenario and restored autoplay. From what I can tell, the game proceeds as before even though it is created entirely differently. There may be some smaller pieces still off, but in general I think it is already playable.

Many changes happened under the hood, including more slot/civ untying that turned out to be required. In particular, core, settler value, war value, and culture for each tile are now tracked by civilization, instead of player, so that their value is preserved even if the civilization is currently not around and is not even assigned to a player at the moment. This is important for example to determine respawns and culture percentages, among other things. I also updated and expanded the unit tests to make sure they cover the new way everything works.

Here's what starting a game looks like now:
Spoiler :
Civ4ScreenShot0331.JPG
Civ4ScreenShot0332.JPG
Civ4ScreenShot0333.JPG
Civ4ScreenShot0334.JPG
Civ4ScreenShot0335.JPG

As you can see, it's just one map script and you can select the scenarios in the game settings. Currently only 3000 BC is implemented (choosing a different option makes no difference), and implementing 600 AD and 1700 AD again will be the next step. Even though these scenarios already exist, I want to implement them in a different way, so that only the differences compared to 3000 BC are required to define another scenario, instead of the whole map. That way, it becomes easier to add and maintain additional scenarios in the future (including when the base map is replaced by the large map).

Another thing that I want to address is the order of civilizations and leaders in that selection menu. Yes, you can select your leader now, even though that is a purely cosmetic choice that does not have any real impact on the game. I want to restore the ordering of civs and leaders to their chronological order, but unfortunately the game enforces alphabetical ordering for civilizations. There is maybe a workaround, but it requires further testing.

Likewise, it's not as easy as I would like to exclude certain civs from the selection, which will be important for the other scenarios.

So, there is still a lot to do but I am positively surprised with how far I have come already.
 
Starting civs are now back in chronological order:
Spoiler :
Civ4ScreenShot0336.JPG
 
It looks like the leaders are in chronological order as well -- how did you manage that? Looks great!

(Also, I'm curious if you have any plans, even long-term ones, for making the choice of leader meaningful. This could apply to either the player or to the AI civs -- giving a small bonus depending on what leader you choose, or what leaderhead shows up in that era. Not sure what the bonuses would be -- maybe a smaller version of the traits from the base game? Something like a 'Creative' trait giving +1 :culture:, rather than +2 :culture: and double production for Library/Theater/Colosseum. Not game-breaking, not even game-changing, just a bit of flavor to make the choice meaningful.
 
It looks like the leaders are in chronological order as well -- how did you manage that? Looks great!
They actually aren't yet in that screenshot (Ramesses should come before Cleopatra), but I fixed that since. Leader order was actually easier to fix than civ order because the game just uses the order in the XML file. So I sorted leaders there first by civ and then chronologically, to easily keep track of the desired order.

Another problem that this brought to light is that leaders also have to match scenarios. For example, Qin Shi Huangdi should not be available in the 600 AD scenario. No idea how to solve that yet.

(Also, I'm curious if you have any plans, even long-term ones, for making the choice of leader meaningful. This could apply to either the player or to the AI civs -- giving a small bonus depending on what leader you choose, or what leaderhead shows up in that era. Not sure what the bonuses would be -- maybe a smaller version of the traits from the base game? Something like a 'Creative' trait giving +1 :culture:, rather than +2 :culture: and double production for Library/Theater/Colosseum. Not game-breaking, not even game-changing, just a bit of flavor to make the choice meaningful.
Yes, I have. I think it would be interesting to either tie the UP to leaders, or to give a lesser secondary UP to leaders. Or maybe even different UUs. Another interesting idea would be to have varying UHV goals.

But as you say, that isn't going to happen until later, if at all.
 
I have been working on setting up the 600 AD scenario and decided to attempt improving the graphical location of the Great Wall:
Spoiler :
Civ4ScreenShot0338.JPG
 
Is the Great Wall generation something moddable in general? i am always going into the worldbuilder just before i build it to edit the tiles in my territory and then granting the wonder to make it look less jarring
 
Yeah that's the best you can do. Unfortunately the logic that places the wall graphics itself is not moddable, but you can get control over turning the graphics on and off independently of the wonder they are attached to.

If you know what the hardcoded rules for the placement of the walls are you can work around it a bit. In this case, as you noted, you can temporarily edit the cultural boundaries when it appears to give it the shape you want. It also cuts off when it reaches the the boundary of an "area" (i.e. continent). The intended purpose of this is the boundary between land and water, but I noticed this also had the same effect if two adjacent land tiles were part of different areas. So I put this section of the map into a different area temporarily, turned the wall graphics on, and then restored the actual area in that part of the map.

It's practical for scenario starts, where the exact position is known and you can work purposely around that. When you actually build it in the 3000 BC scenario, it will still surround your entire currently controlled territory.
 
What exactly is the area of effect (of the slowing and the barbarian damage) of the Great Wall?

Is it limited to the cultural borders of your civ at the time it was built, subject to the "area" cutoff?

This creates a motive to delay building the Great Wall, after expanding your cultural borders as much as possible, which is gamey.

Perhaps a better way is to tie the effect to Walls and Castles in cities. E.g. "Walls, Castles and Star Forts in your cities provide extra defense and slow and damage nearby enemy units every turn. Walls have range 1, Castles have range 2, Star Forts have range 3." This would make the Great Wall more realistic and strategically interesting.

For reference:
https://en.wikipedia.org/wiki/Chinese_city_wall#Effectiveness_against_artillery

Quotes:

Chinese walls were bigger than medieval European walls. In the mid-twentieth century a European expert in fortification commented on their immensity: "in China … the principal towns are surrounded to the present day by walls so substantial, lofty, and formidable that the medieval fortifications of Europe are puny in comparison." Chinese walls were thick. Ming prefectural and provincial capital walls were 10 to 20 metres (33 to 66 ft) thick at the base and 5 to 10 metres (16 to 33 ft) at the top...

The Chinese Wall Theory essentially rests on a cost benefit hypothesis, where the Ming recognized the highly resistant nature of their walls to structural damage, and could not imagine any affordable development of the guns available to them at the time to be capable of breaching said walls. Even as late as the 1490s a Florentine diplomat considered the French claim that "their artillery is capable of creating a breach in a wall of eight feet in thickness" to be ridiculous and the French "braggarts by nature."
 
Yes, it affects all tiles of your territory at the time it was built.
 
Will you rework cores? Cause it seems weird seeing civs like China not having even half of it's "country" cored in later eras.
 
Back
Top Bottom