Quick Modding Questions Thread

Alright, here is some code I've made. I've confirmed that it builds but I did not have the time to properly test it in the game. So feel free to do that and tell me if everything works.

Spoiler CvEraInfo in CvInfos.h :
Code:
    // Arrays

    int* m_paiSoundtracks;
    int* m_paiCitySoundscapeSciptIds;
// Two new lines added here
    int* m_peaceSoundtracks;
    int* m_warSoundtracks;

Spoiler end of CvEraInfo::read in CvInfos.cpp :
Code:
    if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(), "EraInfoSoundtracks"))
    {
        CvString* pszSoundTrackNames = NULL;
        pXML->SetStringList(&pszSoundTrackNames, &m_iNumSoundtracks);

        if (m_iNumSoundtracks > 0)
        {
            //m_paiSoundtracks = new int[m_iNumSoundtracks];

            int j;
            int numberOfPeaceSongs = 0, numberOfWarSongs = 0;
            for (j = 0; j < m_iNumSoundtracks; j++)
            {
                if (pszSoundTrackNames[j].find("WAR") != std::string::npos)
                {
                    numberOfWarSongs++;
                }
                else
                {
                    numberOfPeaceSongs++;
                }
            }

            m_peaceSoundtracks = new int[numberOfPeaceSongs];
            m_warSoundtracks = new int[numberOfWarSongs];

            int peaceCounter = 0, warCounter = 0;
            for (j=0;j<m_iNumSoundtracks;j++)
            {
                if (pszSoundTrackNames[j].find("WAR") != std::string::npos)
                {
                    m_warSoundtracks[warCounter] = ((!gDLL->getAudioDisabled()) ? gDLL->getAudioTagIndex(pszSoundTrackNames[j], AUDIOTAG_2DSCRIPT) : -1);
                    warCounter++;
                }
                else
                {
                    m_warSoundtracks[peaceCounter] = ((!gDLL->getAudioDisabled()) ? gDLL->getAudioTagIndex(pszSoundTrackNames[j], AUDIOTAG_2DSCRIPT) : -1);
                    peaceCounter++;
                }
            }
        }
        else
        {
            m_paiSoundtracks = NULL;
        }

        gDLL->getXMLIFace()->SetToParent(pXML->GetXML());

        SAFE_DELETE_ARRAY(pszSoundTrackNames);
    }

This should give you two lists of songs instead of one, with war and peace songs being separated out based on having the words "WAR" in their name or not. Than you just have to modify getNextSoundtrack to pick from one or the other based on the state of the game.

I'll leave that bit up to you as it's just busywork and I don't have the time to do it right now. But all you have to do is replicate the getNumSoundtracks() function into two clones, one for each of the new arrays and than add an if condition to getNextSoundtrack to pick from one or the other.
 
That looks like it might work - and shouldn't require any change to the XML schema. Maybe changing the schema and generally just copying everything that the original (or AND) DLL does for EraInfoSoundtrack wouldn't be too difficult either – leaving the original EraInfoSoundtracks for tracks that play regardless of war/ peace, and adding two separate lists for war-only and peace-only, e.g. "WarSoundtracks" and "PeaceSoundtracks".

A GlobalDefine would be a cheap way to set a fixed number of tracks through XML (if you need to go down that road after all). A lot easier to add than a new element in Civ4EraInfos.xml.

Dummy eras (or, for that matter, actual additional eras) aren't great for the AI because the AI code, in a bunch of places, determines the overall game progress based on the portion of eras that have passed (e.g. by comparing the current era number with GC.getNumEraInfos()/2).
 
That looks like it might work - and shouldn't require any change to the XML schema. Maybe changing the schema and generally just copying everything that the original (or AND) DLL does for EraInfoSoundtrack wouldn't be too difficult either – leaving the original EraInfoSoundtracks for tracks that play regardless of war/ peace, and adding two separate lists for war-only and peace-only, e.g. "WarSoundtracks" and "PeaceSoundtracks".

A GlobalDefine would be a cheap way to set a fixed number of tracks through XML (if you need to go down that road after all). A lot easier to add than a new element in Civ4EraInfos.xml.
I would just have getNextSoundtrack default to peace songs if no war songs are available. And since my code detects war songs by having "WAR" in their name it would even work just fine with the original XML.:)

I might just finish it up and use it in my own mod and than just upload the rest. But I can't get the time to do that today.
 
Dummy eras (or, for that matter, actual additional eras) aren't great for the AI because the AI code, in a bunch of places, determines the overall game progress based on the portion of eras that have passed (e.g. by comparing the current era number with GC.getNumEraInfos()/2).
Out of curiosity, would you happen to know for which purpose this is done?
 
Here's an example. If the eras are as in BtS, then the AI will add an extra defender to coastal cities upon reaching Renaissance:
Spoiler :
Code:
int CvCityAI::AI_minDefenders()
{
	int iDefenders = 1;
	int iEra = GET_PLAYER(getOwnerINLINE()).getCurrentEra();
	if (iEra > 0)
	{
		iDefenders++;
	}
	if (((iEra - GC.getGame().getStartEra() / 2) >= GC.getNumEraInfos() / 2) && isCoastal(GC.getMIN_WATER_SIZE_FOR_OCEAN()))
	{
		iDefenders++;
	}
	return iDefenders;
}
I guess the idea was to add the defender around the middle of the game and, through the threshold based on the total number of eras, it'll work that way even in mods that have added or removed eras. However, if the reason for giving coastal AI cities an extra defender in the midgame was to secure them against naval landings, then the threshold is unlikely to work well for mods with a different era progression. Nor is it ideal to look at the era of the city owner – the question should be whether (dangerous) rivals have ships. Even then, adding a defender seems like a costly measure for little gain. And of course it's all very coarse – era numbers (rather than specific techs), defender counts (rather than looking at combat strength and defensive modifiers). That's probably much more owed to minimizing the programming effort than to worries about AI turn times. On the plus side, the simplicity is nice for veteran players who want to be aware of AI internals rather than regard the AI as an inscrutable, person-like black box.

On the other hand, the first extra defender – in all cities – gets added in the Classical era, and this threshold (> 0) is not tied to the total number of eras. May or may not work well for mods, seems pretty arbitrary (not to use the era count here, I mean).

Another example: AI will build an Academy only during the first half of the game (if I read that correctly).
 
I would just have getNextSoundtrack default to peace songs if no war songs are available. And since my code detects war songs by having "WAR" in their name it would even work just fine with the original XML.:)

I might just finish it up and use it in my own mod and than just upload the rest. But I can't get the time to do that today.
Wow! That's awesome. I really didn't expect such wonderful news.
:bowdown:

I'll wait for you to finish that code, no matter when that happens.
 
However, if the reason for giving coastal AI cities an extra defender in the midgame was to secure them against naval landings, then the threshold is unlikely to work well for mods with a different era progression.
Exactly why I asked; in my mod, I am usually in the first half of the game, and I have expanded the naval capabilities there. Still, this seems like an innocent enough thing exactly because of all the 'objections' you raise; it's vague enough to not bother with for myself. :)

Thank you very much!
 
Does anyone know how to export an entire unit animation set at once from 3D max? I know how to export individual animations but that's a pain when I am building completely new animation sets.
 
So you assume that combat is just as slow in BtS? Maybe it's related to simultaneous turns. I don't think I've ever tried Stack Attack (we're talking about PLAYEROPTION_STACK_ATTACK, right?) in MP, but I could imagine that there is a deliberate delay, maybe for some fairness reason. Or perhaps the network messages are a bottleneck (but, then, I guess it should be just 1 message per attack). Of course, if Stack Attack is just as slow in SP, something else must be the reason; maybe the processing of killed units. I don't think that this should normally cause a noticeable delay.

More generally, if there's a performance issue in a particular situation, then I would focus only on that. If it's evident that the time is being spent by the DLL, then a profiler will show very specifically how that time is being spent. Overall speed increases – beyond enabling whole-program optimization (/GL compiler option) for releases – I see no easy way. Iirc you distribute your mod as a standalone application (or almost), so this faster version of Python24.dll could be of interest to you. Mods can't generally provide that file because it goes into the BtS install dir. Well, I've only measured a 4% decrease in turn times in a test, so this is a bit off-topic.
Thanks for your quick answer -and apologies for my equally slow comeback
Yes I meant that Stack Option which is, at least for simultaneous turns, pretty much compulsory for MP.
I don't think my MOD actually did make it worst than BTS, but was wondering if something existed to streamline the BTS logic. I appreciate you have to isolate situation indeed, I'll do that eventually. Thanks for the pointers, the pyton24.dll is interesting, I will have a look
 
Real basic stuff. From a basic user.

Working on a basic personal mod to make massive maps easier to play. I wish to change

- Movement points of units - I need to edit the CIV4UNITINFOS.xml right?
- Culture Levels required to expand - is this in the XML files?
- 3 City radius - I know this may be a bit too much for a noob like myself, but do I change this? is an uptodate mod that changes this?
 
Real basic stuff. From a basic user.

Working on a basic personal mod to make massive maps easier to play. I wish to change

- Movement points of units - I need to edit the CIV4UNITINFOS.xml right?
- Culture Levels required to expand - is this in the XML files?
- 3 City radius - I know this may be a bit too much for a noob like myself, but do I change this? is an uptodate mod that changes this?
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/
 
Last edited:
I would just have getNextSoundtrack default to peace songs if no war songs are available. And since my code detects war songs by having "WAR" in their name it would even work just fine with the original XML.:)

I might just finish it up and use it in my own mod and than just upload the rest. But I can't get the time to do that today.
Just out of curiosity: Are you still working on this or gave it up?
I ask it because I have 33 hours of music for Civ4 (including the original ones) and I started sorting them into war/peace/both categories :)
 
Just out of curiosity: Are you still working on this or gave it up?
I ask it because I have 33 hours of music for Civ4 (including the original ones) and I started sorting them into war/peace/both categories :)
I fully intend to do it but it's not going to be done this month. More like end of the next month or something.
I basically can't get the motivation to program right now in my spare time on account of my work eating up my brainpower too much. But once things clear up a bit there I should start working on it. Because honestly it's something I want for my own mod anyway.
 
I fully intend to do it but it's not going to be done this month. More like end of the next month or something.
Oh, I just wanted to know if I can keep on dreaming or should I wake up 😅

I basically can't get the motivation to program right now in my spare time on account of my work eating up my brainpower too much.
I totally understand you. I also feel the need of playing my mod to continue modding it.


Because honestly it's something I want for my own mod anyway.
Great! :)
Actually I have an idea of further improving it. Just let me share it:
If UNIT_ARTSTYLE is there in the track id than check if it is the civ's unit art style.
E.g. If UNIT_ARTSTYLE_SOVIET_HELL_MARCH than it's not played when your civ is a UNIT_ARTSTYLE_ALLIED.

I don't know it's feasible or not but I just felt like telling it so you can decide if you want to do it or not :)
 
Just don't get your hopes up too much. I've not tested if all this works. It's only hypothetical so far. For all I know CIV might decide to throw a wrench into things. But I'll do my best to avoid that.
 
I was trying to figure out if and how it would be possible for corporations not to compete for resources? In CoM there is already a CompetingCorporations tag that allows the setting of competition manually.
 
I was trying to figure out if and how it would be possible for corporations not to compete for resources? In CoM there is already a CompetingCorporations tag that allows the setting of competition manually.
Wouldn't that fundamentally invalidate the balance of corporations? I mean, in theory at least they are very powerful but balanced out by the fact you can't easily stack them. In practice of course some are obviously better than others but that's not the point.
 
Wouldn't that fundamentally invalidate the balance of corporations? I mean, in theory at least they are very powerful but balanced out by the fact you can't easily stack them. In practice of course some are obviously better than others but that's not the point.
No, I wanted to set up competition manually. In CoM there are more corporations than in BtS and I'm going to add even more. So I wanted to have co. groups: Grains, Seafood, Livestock, etc.
So Sid's Sushi wouldn't compete with Gain companies, just because both consume Rice.
But I gave up this idea and started reorganizing resource consumption. It is as tedious as writing a new mechanic but at least more bug free :lol:
 
I'm trying to create a new unit that requires 3 resources to build. So e.g. copper AND iron AND horses.

In Civ4UnitInfos, I believe <BonusType> can only have one value, and then any other values you put into <PreReqBonuses> are OR resources. Meaning that, as far as I can tell, the best I can do is create a unit that requires e.g. copper AND (iron OR horses) rather than requiring all 3. Am I missing something here? Is there a workaround?
 
Not without either modding the dll or having a kludge.
Theoretically, you could define a building that requires the AND bonuses as a prereq for the unit. The difficulty with this is whether the AI would create the building. You could give it a cost of 1 and a high iAIWeight I suppose, but it is all a bit messy. Then there is the issue of the city losing access to one resurce, but the building still existing so the bonus prereq appears to be being met, but isn't actually.
Somone else will hopefully have a better idea :)
 
Back
Top Bottom