Quick Modding Questions Thread

// Edit
Ok, I've found the answer.
I can either use "<img=%s size=%d></img> %s" % (sButton, 18, "XP") or use setImageButton() together with setTableColumnHeader() and some spacebar tabbing to align the "XP" text like it's 1998.
The button does look better though with the latter version. 🤥




I think you want getButton().
Sorry for bothering you again, but I'm having trouble to merge text with such a getButton() call.
It seems to actually display such a button you need to call setImageButton() resp. setImageButtonAt(), however this appears to need a reference to some sort of screen and X and Y coordinates. What I am trying to achieve is basically "unit icon" + "XP".

Here's my current version of the Domestic Advisor screen to give a bit more context:

1676292324057.png


The icons so far are from the GameFont file and are called by the unichr() function. But I couldn't find a representation for all the classes I wanted to display (e.g. Archers or Throwing).
(For the Archers in this image I tried to just merge a getButton() call with the text, but this way it just displays the path to the art file).

The relevant code in CvDomesticAdvisor.py looks like this:

Python:
self.COLUMNS_LIST = COLUMNS_LIST = [

    [...]

    ("TOTAL_EXPERIENCE_MELEE",    50, "int", None, self.getExperienceForUnit, "BRUTE",         unichr(8525) + " XP"),    # Crossed Swords
    ("TOTAL_EXPERIENCE_ARCHER",   50, "int", None, self.getExperienceForUnit, "ARCHER",        self.getButtonForUnit("ARCHER") + " Archer XP"),
    ("TOTAL_EXPERIENCE_THROWING", 50, "int", None, self.getExperienceForUnit, "STONE_THROWER", "Throw XP"),
]

Is this possible at all? Or do I need to add the logic to display the button later on, when the column header text is actually being processed?
 
Last edited:
How do you indicate that a building is a World or National Wonder?

Bonus question: how do you specify how many times a building can be built by a civ? (I know there is a setting in GlobalDefines.xml that sets how many Wonders can be built in a city, but it does not say how many times a building can be built by a civilization.)
 
How do you indicate that a building is a World or National Wonder?

Bonus question: how do you specify how many times a building can be built by a civ? (I know there is a setting in GlobalDefines.xml that sets how many Wonders can be built in a city, but it does not say how many times a building can be built by a civilization.)
in Assets/XML/Buildings/CIV4BuildingClassInfos.xml I found this:

XML:
        <BuildingClassInfo>
            <Type>BUILDINGCLASS_CHICHEN_ITZA</Type>
            <Description>TXT_KEY_BUILDING_CHICHEN_ITZA</Description>
            <iMaxGlobalInstances>1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>-1</iMaxPlayerInstances>
            <iExtraPlayerInstances>0</iExtraPlayerInstances>
            <bNoLimit>0</bNoLimit>
            <bMonument>0</bMonument>
            <DefaultBuilding>BUILDING_CHICHEN_ITZA</DefaultBuilding>
            <VictoryThresholds/>
        </BuildingClassInfo>
        
        
        <BuildingClassInfo>
            <Type>BUILDINGCLASS_HEROIC_EPIC</Type>
            <Description>TXT_KEY_BUILDING_HEROIC_EPIC</Description>
            <iMaxGlobalInstances>-1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>1</iMaxPlayerInstances>
            <iExtraPlayerInstances>0</iExtraPlayerInstances>
            <bNoLimit>0</bNoLimit>
            <bMonument>1</bMonument>
            <DefaultBuilding>BUILDING_HEROIC_EPIC</DefaultBuilding>
            <VictoryThresholds/>
        </BuildingClassInfo>

So iMaxGlobalInstances = 1 for World Wonders, and iMaxPlayerInstances = 1 for National Wonders.
You could try to set iMaxPlayerInstances to 2 or more, from the name it doesn't look to be a yes/no modifier, but the actual amount of buildings that are allowed.
 
in Assets/XML/Buildings/CIV4BuildingClassInfos.xml I found this:

XML:
        <BuildingClassInfo>
            <Type>BUILDINGCLASS_CHICHEN_ITZA</Type>
            <Description>TXT_KEY_BUILDING_CHICHEN_ITZA</Description>
            <iMaxGlobalInstances>1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>-1</iMaxPlayerInstances>
            <iExtraPlayerInstances>0</iExtraPlayerInstances>
            <bNoLimit>0</bNoLimit>
            <bMonument>0</bMonument>
            <DefaultBuilding>BUILDING_CHICHEN_ITZA</DefaultBuilding>
            <VictoryThresholds/>
        </BuildingClassInfo>
       
       
        <BuildingClassInfo>
            <Type>BUILDINGCLASS_HEROIC_EPIC</Type>
            <Description>TXT_KEY_BUILDING_HEROIC_EPIC</Description>
            <iMaxGlobalInstances>-1</iMaxGlobalInstances>
            <iMaxTeamInstances>-1</iMaxTeamInstances>
            <iMaxPlayerInstances>1</iMaxPlayerInstances>
            <iExtraPlayerInstances>0</iExtraPlayerInstances>
            <bNoLimit>0</bNoLimit>
            <bMonument>1</bMonument>
            <DefaultBuilding>BUILDING_HEROIC_EPIC</DefaultBuilding>
            <VictoryThresholds/>
        </BuildingClassInfo>

So iMaxGlobalInstances = 1 for World Wonders, and iMaxPlayerInstances = 1 for National Wonders.
You could try to set iMaxPlayerInstances to 2 or more, from the name it doesn't look to be a yes/no modifier, but the actual amount of buildings that are allowed.
*smacks forehead*

I was looking in Civ4BuildingInfos.xml, not in Civ4BuildingClassInfos.xml.

Thank you!
 
// Edit
Ok, I've found the answer.
I can either use "<img=%s size=%d></img> %s" % (sButton, 18, "XP") or use setImageButton() together with setTableColumnHeader() and some spacebar tabbing to align the "XP" text like it's 1998.
The button does look better though with the latter version. 🤥

[...]

("TOTAL_EXPERIENCE_MELEE", 50, "int", None, self.getExperienceForUnit, "BRUTE", unichr(8525) + " XP"), # Crossed Swords
("TOTAL_EXPERIENCE_ARCHER", 50, "int", None, self.getExperienceForUnit, "ARCHER", self.getButtonForUnit("ARCHER") + " Archer XP"),
("TOTAL_EXPERIENCE_THROWING", 50, "int", None, self.getExperienceForUnit, "STONE_THROWER", "Throw XP"),
]
[/code]

Is this possible at all? Or do I need to add the logic to display the button later on, when the column header text is actually being processed?

If I was trying to pull a unit's button, this is what I would use: gc.getUnitInfo(gc.getInfoTypeString('UNIT_ARCHER')).getButton(), no self. In this particular context, I don't know if that will work. This is not an area I have worked in very much, but it seems to me like your code would be expecting a particular subtype of icon. At the very least, use UNIT_ARCHER, not just ARCHER.
 
If I was trying to pull a unit's button, this is what I would use: gc.getUnitInfo(gc.getInfoTypeString('UNIT_ARCHER')).getButton(), no self. In this particular context, I don't know if that will work. This is not an area I have worked in very much, but it seems to me like your code would be expecting a particular subtype of icon. At the very least, use UNIT_ARCHER, not just ARCHER.
All good, the self is because the methods are part of a class, and the missing UNIT_ was because I was concentating the string in the getButtonForUnit() method (not anymore though). The game internal functions you've mentioned are the ones I was using to pull the button, the problem was just how to merge the text with the button image then.

Unfortunately using setImageButton() in combination with screen.setTableColumnHeader(PAGE, col, "<font=2> XP", self.columnWidth[key]) just looks better than "<font=2><img=%s size=%d></img> %s" % (sButton, 18, "XP"), so 5 spaces for the padding it is then. 🥲
 
Hello. I am trying to make it so that a Wonder is a prerequisite for building a particular type of aqueduct in this civ. I added the wonder's building class to the PrereqBuildingClasses of the aqueduct, and set the iNumBuildingNeeded to 1, but in the game, it let me build 1 aqueduct, but no more. In Civilopedia it says that I need 2 of the Wonder, which is of course impossible to do. Am I missing something?

Edit: additional info. I created several of these connections between Wonders and buildings. The Wonder required 10 of a different building to build, but when I look at Civilopedia, it says it needs 17. I just don't understand where it is getting these numbers.
 
Last edited:
What does iInitialHappiness do in CIV4CommerceInfo.xml?
According to the wiki:

iInitialHappinessSets the happiness received by this commerce type. Each n% to that commerce type provides a happy face (default is 10 for culture, 0 for all others).
 
Hello. I am trying to make it so that a Wonder is a prerequisite for building a particular type of aqueduct in this civ. I added the wonder's building class to the PrereqBuildingClasses of the aqueduct, and set the iNumBuildingNeeded to 1, but in the game, it let me build 1 aqueduct, but no more. In Civilopedia it says that I need 2 of the Wonder, which is of course impossible to do. Am I missing something?

Edit: additional info. I created several of these connections between Wonders and buildings. The Wonder required 10 of a different building to build, but when I look at Civilopedia, it says it needs 17. I just don't understand where it is getting these numbers.
For the latter, it may be modified by the map size. Larger maps need more buildings:
 
For the latter, it may be modified by the map size. Larger maps need more buildings:
Thanks. I confirmed that after I set that value to 0 for all map sizes, and started a new game, it showed the correct number of prerequisite buildings for each one. Now, however, when I load my existing game, it is still using the old number. Is there a way to force the game to reload the XML values in a saved game?
 
Thanks. I confirmed that after I set that value to 0 for all map sizes, and started a new game, it showed the correct number of prerequisite buildings for each one. Now, however, when I load my existing game, it is still using the old number. Is there a way to force the game to reload the XML values in a saved game?
Some have a "Force recalc" option (BUG based mods?) CTRL+ALT+T IIRC.
 
Is anyone familiar with handling signs and landmarks via Python?

My understanding is that a "sign" is a text marker on the map placed by a player while a "landmark" is not associated with a player and seems to be intended to describe map features. I can place them using Alt+S and worldbuilder respectively. However, if I try to place them via the Python console using CyEngine.addSign and CyEngine.addLandmark, they are not actually displayed. What am I missing?

Also, it seems that only signs can be accessed using CyEngine.getNumSigns and CyEngine.getSignByIndex. Is there a way of iterating landmarks that I'm not seeing?

Edit: also, after placing a sign with Alt+S (and seeing it on the map), running CyEngine().getNumSigns() still returns 0. Does anyone know why?

Edit2: I figured out that my issue was that I used a singleton for CyEngine that for whatever was initialised too early and therefore returned wrong results. Creating it on demand fixed all these unexplained behaviours.

Also, if anyone cares: their API is a bit confusingly named. Landmarks and signs are actually the same thing, and landmarks are simply signs that do not belong to a player. The API to iterate signs also iterates landmarks.
 
Last edited:
1 - Yes, change the iMoves value
2 - Not exactly sure what you are trying to achieve, but try modifying Civ4CultureLevelInfos.xml.xml and see if that does the job
3 - Have you compiled the dll yet? If not then start by doing that and getting it to work before you hit the C++ mods. Don't worry too much about up to date mod components as the game hasn't changed in years so mod components tend to stay current if they are for the base game rather than a modmod

Apologies if you know this, but worth reiterating in case you don't ... If you are new to modding make sure that you create a new mod and never edit the base game files. There are tutorials on doing this here: https://forums.civfanatics.com/forums/civ4-modding-tutorials-reference.177/
Thanks for your help. I've got two out of three done I wanted to reduce the time to culture popping. I spent ages in the BTS XML folder looking for the culturefiles to only realise it was in the base game folder :blush:.

Simply put, I just wanted to balance a very old mod "Neverminds XXL World" mod by a few XML tweaks, more movement, faster culture popping and a few more. Thanks to you I've been able to do it and test, it works brilliantly thanks.
1, Why does it have "i" in the tag, is there a significance it?
2, I'm baffled at the settler not having a production :hammers: value? Id like to reduce the price of settlers a bit but there no xml value.
3, I've tried the all available 3 radius city mods, none are up to date on the 3.19 BTS which is a shame. I assume it would be the same as changing a few few values, but I wouldn't know where to start (other then this forum I've been a member off half of my life).
4, You are more then welcome to tell me if this is out of my wheelhouse for the time being, but i find a the maps at that size produce large plains without hills, thus no production. Is there way I could increase the frequency, of hills I know id have to poke around in the python code.
5, Id like to give scouts an extra visibility range without giving them the promotion outright. Is there an XML tag for this?
 
Thanks for your help. I've got two out of three done I wanted to reduce the time to culture popping. I spent ages in the BTS XML folder looking for the culturefiles to only realise it was in the base game folder :blush:.

Simply put, I just wanted to balance a very old mod "Neverminds XXL World" mod by a few XML tweaks, more movement, faster culture popping and a few more. Thanks to you I've been able to do it and test, it works brilliantly thanks.
1, Why does it have "i" in the tag, is there a significance it?
2, I'm baffled at the settler not having a production :hammers: value? Id like to reduce the price of settlers a bit but there no xml value.
3, I've tried the all available 3 radius city mods, none are up to date on the 3.19 BTS which is a shame. I assume it would be the same as changing a few few values, but I wouldn't know where to start (other then this forum I've been a member off half of my life).
4, You are more then welcome to tell me if this is out of my wheelhouse for the time being, but i find a the maps at that size produce large plains without hills, thus no production. Is there way I could increase the frequency, of hills I know id have to poke around in the python code.
5, Id like to give scouts an extra visibility range without giving them the promotion outright. Is there an XML tag for this?
1. "i" stands for integer, so only full number are allowed (negative as well), "b" for boolean (only 0 or 1).
5. I don't think there is. A possible workaround would be to copy&paste the Sentry promotion, rename it (Eagle Eye or something) and give this as a free promotion to the Scout. You'd have to make sure it wouldn't be available to other units through the regular promotion process though, not sure right now how to do that.
 
You'd have to make sure it wouldn't be available to other units through the regular promotion process though, not sure right now how to do that.
You could make it rely on Future Tech. At least then it would only be available as a promotion very late game.
 
2, I'm baffled at the settler not having a production :hammers: value? Id like to reduce the price of settlers a bit but there no xml value.
It gets set by the DLL based on the start era. The calculation happens in this function. Can be decreased through ADVANCED_START_CITY_COST in GlobalDefines.xml. The cost in Civ4UnitInfo.xml also gets added in the end, so setting a negative cost in that file should also work. Not sure if both of these approaches will be equally affected by the game speed setting (e.g. units being 1.5 times more expensive on Epic speed).
3, I've tried the all available 3 radius city mods, none are up to date on the 3.19 BTS which is a shame. I assume it would be the same as changing a few few values, but I wouldn't know where to start (other then this forum I've been a member off half of my life).
The working radius is hardcoded in a bunch of places, in particular in these arrays. So those would be DLL changes. If and when you set up the development environment for that, you could try locating the source code of those outdated mod components and port the changes to the BtS 3.19 source code. Some large mods for 3.19 also support a 3-tile radius, e.g. RAND2, so the necessary code could presumably also be adopted from there. (I think RAND2 only uses the 3-tile radius for cities with a particular national wonder.)
4, You are more then welcome to tell me if this is out of my wheelhouse for the time being, but i find a the maps at that size produce large plains without hills, thus no production. Is there way I could increase the frequency, of hills I know id have to poke around in the python code.
Unless you use a map script that has no Climate option, you could increase iHillRange in Civ4ClimateInfo.xml (base game XML\GameInfo folder). You could also experiment with this grain_amount parameter. It gets fed into the hillsFrac, peaksFrac elevation generators. I forget whether a smaller grain value results in more clumping or less. This will only have an effect if the map script calls the generatePlotTypes function. Fractal.py e.g. does so here. At that point, the script could also pass a value for grain_amount that will then only apply for the Fractal script.
 
You could make it rely on Future Tech. At least then it would only be available as a promotion very late game.

If you remove all possible <UnitCombats> from the promotion, then it can never be given out normally. This is how the special event-only promotions work. You can use the <FreePromotions> tag to make a unit start with a promotion that would normally be denied to it by its class. For example, Melee units normally can't get Drill promotions, but the Samurai UU starts with Drill I.
 
Vassal agreements don't affect team IDs (permanent alliances do, yes). Team IDs can be assigned arbitrarily on the Custom Game screen and in WB save files. I seem to recall that, upon launch, consecutive player and team IDs get assigned (by the EXE I guess), even if e.g. one team ID had been skipped on the Custom Game screen. But I don't know if this reliably results in player IDs being equal to team IDs. (Assuming that every team consists of just one player – if there are multiple players per team, then team IDs will obviously differ from player IDs.)
Maybe fVisibilityPriority (0? -1? no help if it really just sets a priority) in XML\Buildings\Civ4BuildingInfos.xml or (near?) 0 (negative?) scale values in XML\Art\CIV4ArtDefines_Building.xml. If an empty <NIF/> works at all, then it would also remove the 3D model from Civilopedia. Just things to try, perhaps, until someone can hopefully provide an answer. Edit: I assume that by "campaign" you mean on the main map (in the countryside, campaña), but I'm not quite sure. I also don't recall what Civ 5 does with building graphics. If you actually want to hide all building graphics – well, there's a game option (Ctrl+O menu) "Globe View Buildings Disabled", but that's of course only for Globe view.
Edit2: If you're willing to change (and recompile) the DLL, then it's easy to hide all buildings or specific individual buildings:
CvCity.cpp#L12168
And, no, negative priority is not going to help. Looks like setting GAME_CITY_SIZE_METHOD to METHOD_LINMAP and both GAME_CITY_SIZE_LINMAP_AT_0 and GAME_CITY_SIZE_LINMAP_AT_50 to 0 in GlobalDefines.xml should hide all buildings without the need for a DLL change. Hm, in a quick test, that hides all city graphics, i.e. also the generic residential buildings. Ah, but setting GAME_CITY_SIZE_MAX_PERCENT_UNIQUE to 0 seems to hide only the non-generic buildings.
A almost perfect solution to me was this GAME_CITY_SIZE_MAX_PERCENT_UNIQUE. Obviously putting 0 only the generic residential buildings show up, but setting it between 0.1-0.2 is perfect, apparently walls and aqueducts have a priority over other buildings, so this is how I intended it, mostly generic buildings, walls, some other important buildings (Palace) and at least 1 wonder. In the late game, I can't even distinguish the cultural differences of the cities, because there are almost no generic residential buildings in the cities. So by changing that I managed to get it the way I wanted it, thank you.

(Japanese Renaissance city, with all buildings and wonders available until the Renaissance era)​
1676611908288.png
 
Back
Top Bottom