Quick Modding Questions Thread

What would I have to do to replace the graphics (and sound) an existing unit in the base?
For example, let us say I wish to chance the graphics for "Mechanized Infantry" that appears in the game from an APC into an actual group of infantry, like, for example, kine100's Modern Infantry. What would be the simplest method to achieve this, the unit graphics, icon, and sound? Further what would I have to do to change all in game name instances of "Mechanized Infantry" to "Modern Infantry"?
The graphics of a unit are defined in the CIV4ArtDefines_Unit.xml file that can be found in ..\Sid Meier's Civilization 4\Beyond the Sword\Assets\XML\Art\ . I would not recommend modifying the original file though, but copy it into a mod folder, something like ...Sid Meier's Civilization 4\Beyond the Sword\Mods\MyMod\Assets\XML\Art\ for example. In the least I would make a back-up of the file.

Anyhow, in this file, you should be able to find the following entry:
Code:
       <UnitArtInfo>
           <Type>ART_DEF_UNIT_MECHANIZED_INFANTRY</Type>
           <Button>,Art/Interface/Buttons/Units/MechanizedInfantry.dds,Art/Interface/Buttons/Unit_Resource_Atlas.dds,8,8</Button>
           <fScale>0.43</fScale>
           <fInterfaceScale>1.0</fInterfaceScale>
           <bActAsLand>0</bActAsLand>
           <bActAsAir>0</bActAsAir>
           <NIF>Art/Units/MechanizedInfantry/MechanizedInfantry.nif</NIF>
           <KFM>Art/Units/MechanizedInfantry/MechanizedInfantry.kfm</KFM>
           <SHADERNIF>Art/Units/MechanizedInfantry/MechanizedInfantry_FX.nif</SHADERNIF>
           <ShadowDef>
               <ShadowNIF>Art/Units/01_UnitShadows/MechInfantryShadow.nif</ShadowNIF>
               <ShadowAttachNode>BIP Pelvis</ShadowAttachNode>
               <fShadowScale>1.0</fShadowScale>
           </ShadowDef>
           <iDamageStates>4</iDamageStates>
           <TrailDefinition>
               <Texture>Art/Shared/tanktread.dds</Texture>
               <fWidth>0.9</fWidth>
               <fLength>180.0</fLength>
               <fTaper>0.0</fTaper>
               <fFadeStartTime>0.2</fFadeStartTime>
               <fFadeFalloff>0.35</fFadeFalloff>
           </TrailDefinition>
           <fBattleDistance>0.5</fBattleDistance>
           <fRangedDeathTime>0.12</fRangedDeathTime>
           <bActAsRanged>1</bActAsRanged>
           <TrainSound>AS2D_UNIT_BUILD_UNIT</TrainSound>
           <AudioRunSounds>
               <AudioRunTypeLoop>LOOPSTEP_TANK</AudioRunTypeLoop>
               <AudioRunTypeEnd>ENDSTEP_TANK</AudioRunTypeEnd>
           </AudioRunSounds>
       </UnitArtInfo>
The Modern Infantry uses the Navy Seals animation, so it is a good idea to replace most lines with the Navy Seals entry first, like this:
Code:
       <UnitArtInfo>
           <Type>ART_DEF_UNIT_MECHANIZED_INFANTRY</Type>
           <Button>,Art/Interface/Buttons/Units/Navy_Seal.dds,Art/Interface/Buttons/Unit_Resource_Atlas.dds,4,7</Button>
           <fScale>0.44</fScale>
           <fInterfaceScale>1.0</fInterfaceScale>
           <bActAsLand>0</bActAsLand>
           <bActAsAir>0</bActAsAir>
           <NIF>Art/Units/Unique/America/NavySEAL/NavySeal.nif</NIF>
           <KFM>Art/Units/Unique/America/NavySEAL/NavySeal.kfm</KFM>
           <SHADERNIF>Art/Units/Unique/America/NavySEAL/NavySeal_FX.nif</SHADERNIF>
           <ShadowDef>
               <ShadowNIF>Art/Units/01_UnitShadows/UnitShadow.nif</ShadowNIF>
               <ShadowAttachNode>BIP Pelvis</ShadowAttachNode>
               <fShadowScale>1.0</fShadowScale>
           </ShadowDef>
           <fBattleDistance>0.35</fBattleDistance>
           <fRangedDeathTime>0.05</fRangedDeathTime>
           <bActAsRanged>1</bActAsRanged>
           <TrainSound>AS2D_UNIT_BUILD_UNIQUE_UNIT</TrainSound>
           <AudioRunSounds>
               <AudioRunTypeLoop/>
               <AudioRunTypeEnd/>
           </AudioRunSounds>
       </UnitArtInfo>
To put in the new graphics, the <SHADERNIF> line needs to be changed to something like this:
Code:
           <SHADERNIF>Art/Units/ModernInfantry/marine.nif</SHADERNIF>
For this to work, the Modern Infantry files need to be put into the folder ...Mods\MyMod\Assets\Art\Units\ModernInfantry\ .

The icon is defined by the <Button> line, so this could be changed to this:
Code:
           <Button>Art/Interface/Buttons/Units/ModernInfantry.dds</Button>
Of course, for this you also need to put the ModernInfantry.dds file into ...Mods\MyMod\Assets\Art\Interface\Buttons\ . Also make note that there is no comma in the line anymore, this is very important.

To change the name, you will have to change the entry in the CIV4GameTextInfos_Objects.xml file you can find in ...\Sid Meier's Civilization 4\Assets\XML\Text\ . Change the entry
Code:
    <TEXT>
       <Tag>TXT_KEY_UNIT_MECHANIZED_INFANTRY</Tag>
       <English>Mechanized Infantry</English>
       <French>
           <Text>Infanterie m&#233;canis&#233;e</Text>
           <Gender>Female</Gender>
           <Plural>0</Plural>
       </French>
       <German><Text>Schützenpanzer:Schützenpanzers:Schützenpanzer:Schützenpanzer:Schützenpanzer:Schützenpanzer:Schützenpanzern:Schützenpanzer</Text><Gender>male:male:male:male:male:male:male:male</Gender><Plural>0:0:0:0:1:1:1:1</Plural></German>
       <Italian>
           <Text>Fanteria meccanizzata:Fanterie meccanizzate</Text>
           <Gender>Female</Gender>
           <Plural>0:1</Plural>
       </Italian>
       <Spanish>
           <Text>Infanter&#237;a mecanizada:Infanter&#237;as mecanizadas</Text>
           <Gender>Female</Gender>
           <Plural>0:1</Plural>
       </Spanish>
   </TEXT>
to whatever you want to call the unit.

Good luck. :)
 
Hello hello CivFanatics folk,

In the theme of the thread just a quick modding question:



Is it possible to change the Beyond The Sword image that displays when launching the game (I.e. the one that shows up before the game is fully up and looks like the image .../Beyond the Sword/Assets/res/CivIV-INIT.bmp) ?



It seems like editing the image itself in a mod folder (i.e. adding a .../Beyond the Sword/Assets/res/CivIV-INIT.bmp to the mod folder) doesn't seem to change what shows up, and more interestingly changing the base image in the BTS folder doesn't seem to do anything either... very odd...

If this is possible, I'd very much like to know how, it seemed like a simple enough thing but it turns out not, so I figured I'd try to save myself some grief and ask you more experienced folk ^^.


Edit: Well I came back to it with a fresh mind and it dawned on me that it was all in the .exe (knowing that I can actually have a bit more fun with this whole thing). The identical files at the above mentioned location really threw me off on this one ^^'.
 
Last edited:
You know how in ship vs ship combat the game automatically turns the units broadside to one another? Well what if I wanted to have them not do that? I know it's possible because the kraken unit in FFH does that and just attacks enemy ships head on (enemy ships still turn broadside). But I can't figure out how this is achieved. Does anyone have any idea?
 
A more general question, do you know any mods that have redone the victory advisor screen? I'm currently looking into replacing the current one in my mod and would like to see if there are good options around.
 
You know how in ship vs ship combat the game automatically turns the units broadside to one another? Well what if I wanted to have them not do that? I know it's possible because the kraken unit in FFH does that and just attacks enemy ships head on (enemy ships still turn broadside). But I can't figure out how this is achieved. Does anyone have any idea?
My guess would be one or both of these lines in the Civ4ArtDefine_Unit.xml file:
Code:
           <fAngleInterpRate>720.0</fAngleInterpRate>
           ...
           <fExchangeAngle>25.0</fExchangeAngle>
Maybe play with the values a bit or look at the FFH unit art definition for differences.
 
Those defintively seem to do something. Odd thing is the Kraken model just flat out didn't have those entries at all so I newer thought to look at them but the regular ships do. I really wish there was like a complete document on every part of every XML file.
 
Where I can I change how much the AI and/or the automated city governor values culture relative to other yields and commerce types? It seems cities go out of their way to work as little commerce as possible when the culture slider is at 100%
 
Those defintively seem to do something. Odd thing is the Kraken model just flat out didn't have those entries at all so I newer thought to look at them but the regular ships do. I really wish there was like a complete document on every part of every XML file.
Not having those entries is the same as using the default values. You can only tell if an entry is optional by looking at the schema file. It is a pity they did not use the XML to a bigger extent. If I remember correctly it would have been possible to document the entry and its valid values in the schema and therefore make the Modiki directly from it.
Where I can I change how much the AI and/or the automated city governor values culture relative to other yields and commerce types? It seems cities go out of their way to work as little commerce as possible when the culture slider is at 100%
The sliders are how you tell the auto governors what they should be doing. Having culture at 100% means that culture is what you want. You can adjust the values in individual cities eg if you want a :science: city you can set the slider in that city to 100% and still have the nation slider at 100%:culture:
 
Not having those entries is the same as using the default values. You can only tell if an entry is optional by looking at the schema file. It is a pity they did not use the XML to a bigger extent. If I remember correctly it would have been possible to document the entry and its valid values in the schema and therefore make the Modiki directly from it.
I'm not a big fan of the xml implementation either. I mean the setup is good and flexible, but documentation is horrible and hard to make. Also the error handling regarding xml is horrible. You need somebody with a debugger to figure out assert failures because the error messages are useless. If you write UNIT_WARRIOR when it is expecting a UnitClass, then it accepts it and you just have to hope they happen to have the same index. The default values are all available, but hidden inside the DLL file, meaning they aren't easily readable. Listing something like free promotions is lengthy in xml because they add need that extra tag with 1 in it.

All this is fixable (perhaps except for default values), but it requires heavy DLL modding. Ideally speaking I would want a modcomp, which fixes everything mentioned here, but while it's hard enough to come up with something, which actually works, coming up with something, which can be transferred between mods seems nearly impossible :sad:

That should not be an excuse for not making proper documentation though. The We the People issue tracker already has an issue regarding xml documentation. I would say that we would likely not be uninterested if somebody would want to start a cross mod documentation project. Yes I now it's Colonization and not BTS, but under the different graphics, it's still the civ4 engine and can share a lot more documentation that most people expect. For instance I have used the BTS documentation for python and so far the only difference I have found are 2 new functions added to support drag-n-drop of citizens and cargo. The same is true for xml. While there are some obvious differences (like no wonders), the schema files and related DLL code are close to BTS. For instance setting a non-default building to a building class in a civ. BTS does that a lot. Colonization doesn't do that at all, but since they just copied the code from BTS, they left the code for it and just disabled it with xml settings, not schema files or DLL code. While I haven't checked, I will assume the code for "angle of attack" is identical too. It's the same 3D engine and so far I haven't found a single difference in how to control it from xml.

I think it's time to do what we should have done a decade ago: realize that from an xml point of view, vanilla BTS and vanilla Colonization are closer than vanilla BTS and C2C. It hurts all of us that the distance between us is far greater than it should be.
 
The sliders are how you tell the auto governors what they should be doing. Having culture at 100% means that culture is what you want. You can adjust the values in individual cities eg if you want a :science: city you can set the slider in that city to 100% and still have the nation slider at 100%:culture:
What? No I can't, the slider is global!
 
Last edited:
The sliders are how you tell the auto governors what they should be doing. Having culture at 100% means that culture is what you want. You can adjust the values in individual cities eg if you want a :science: city you can set the slider in that city to 100% and still have the nation slider at 100%:culture:
What? No I can't, the slider is global!
Oops. You are right.
 
Last edited by a moderator:
Another quick one,

How fast exactly is .isHasPromotion() ?
I want to put a few in the onCombatResult python event and was wondering how much this might slow down end turn times.

Lets say we are only checking the attacking unit, naturally this will mean a check of one of the units in every combat, what happens then? does each promotion of the unit get sent as a list and then each entry in the list is checked for being the promotion or not, or is it directly ticked off as having the promo or not having it? Also important does the total number of possible promotions in the mod effect the speed of this function? This may all sound negligible but in my current WIP mod there is an equipment system that includes more than 300 promotions in that alone and there are plenty more elsewhere (e.g. another 100+ easily in a class system).

(Note: Everything refers to FFH2, not sure if some of these functions are unique to it)
 
I don't think you need to worry about this. Methods of the pattern isX() or getX() generally (there may be exceptions but not for something so simple as promotions) only return the state of the object (in this case the unit), which is very fast. It also doesn't work like a list, you don't need to go through all promotions the unit has to see if that includes the checked promotion. Instead, the unit keeps track for each promotion individually if they have it or not. So it's simply a matter of looking up the promotion and returning its true/false value.
 
How fast exactly is .isHasPromotion() ?
The code in question (in BTS vanilla, though likely unchanged in all mods)
PHP:
bool CvUnit::isHasPromotion(PromotionTypes eIndex) const
{
   FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
   FAssertMsg(eIndex < GC.getNumPromotionInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
   return m_pabHasPromotion[eIndex];
}
In other words vanilla has an array where it caches the answer. This means you shouldn't worry about performance related to this specific function. The for loop itself could very well take more time than calling this function.

If you really want to boost performance for looping active promotions, I wrote an idea on how to do it really fast here, though I have to admit the C++ coding difficulty probably makes it unrealistic to implement for anybody who aren't familiar with modding the DLL already.
 
I have another bizarre issue. I've been looking at the great prophet highlight effect, in particular changing it's color. But it just won't work. I've even tried repainting all the relevant textures into plain blocks of red and it still just looks like nothing changed. It's as if the effect nif is just refusing to load my custom textures and instead draws on the default ones from the BTS folder. (my work is inside a module)

Does anyone have any ideas?
 
How do I increase the character limit of city names?
 
How do I increase the character limit of city names?
CvEventManager.py

PHP:
    def __eventEditCityNameBegin(self, city, bRename):
       popup = PyPopup.PyPopup(CvUtil.EventEditCityName, EventContextTypes.EVENTCONTEXT_ALL)
       popup.setUserData((city.getID(), bRename))
       popup.setHeaderString(localText.getText("TXT_KEY_NAME_CITY", ()))
       popup.setBodyString(localText.getText("TXT_KEY_SETTLE_NEW_CITY_NAME", ()))
       popup.createEditBox(city.getName())
       popup.setEditBoxMaxCharCount( 15 )
       popup.launch()
I haven't personally tried to increase the max char count, but odds are that nothing else is needed. Do test in network games and savegames just to be sure.

I have another bizarre issue.
I can join in on that statement. WTP displayed the wrong GameFont char in python, but not on city billboards. Same char ID, different characters. I thought I could fix it in 5-10 minutes (must be a glitch in the python file), but so far I have spend 2 days on it. It turns out GameFont adds padding, meaning it adds blocks in chunks of 16, meaning if you add 1, it might add 0 or 16. I knew that. What I didn't know is that the code for the city billboards doesn't do that. They apparently just count blocks, meaning even if both billboard and python reads from the very same GameFont.tga, they can get different results from reading the same int value. I got them back in sync by adding 11 blank boxes. I still need to do some cleanup before committing, but at least one int value will display the same thing in both places.

If somebody is interested in making a BTS version of this, feel free to contact me. The code can be copy pasted, though it needs a new way of opening as it's hooked into a colo only python file. The billboard debug code requires DLL modification, but displaying GameFont (big and small) for non-billboard purposes is pure python.

billboard.jpg
python.jpg
 
Except that the thing I am talking about has absolutely nothing to do with billboards. It's an attachable effect defined as a particle fountain in a separate nif file.
 
Except that the thing I am talking about has absolutely nothing to do with billboards. It's an attachable effect defined as a particle fountain in a separate nif file.
I think you missed my point. I think I looked kind of like you when I realized that I got different icons despite using the same ints. It's like write something in a file and the game does something completely different and there is no clue to why it does it like that.

If I am to make a guess on your problem, the only thing I can think of is that it somehow doesn't use your file, hence doesn't read your modifications. Maybe try placing the unit outside of the module to see if that makes a change. Another possibility is a name clash as in you copied the file, changed some names, but one name is still pointing to the original file. Maybe the mod/vanilla use the same name as you and it takes priority. That would be the direction of investigation I would take if I were to investigate an issue like your problem.
However all this is just guesses based on general civ4 modding experience and not nif specific knowledge.
 
Nightinggale, no way I'm going to try my hands at the headache that is the gamefonts file myself, but I have heard people claim that sometimes you can force the padding to be fixed by adding another icon, even if unused. Didn't get to try that solution myself but it may help.

PPQ_Purple, the only thing I could think of is graphics settings and how they interact with the effect? Depending on your settings, maybe you have high res effects enabled but have edited the low res version or vice versa.
 
Top Bottom