Quick Modding Questions Thread

The player's choice gets processed here in onOkClicked. The button ID is 4 in launchRazeCityPopup, and a diff confirms that this is the code added by AND:
C++:
else if (pPopupReturn->getButtonClicked() == 4)
{
	CvMessageControl::getInstance().sendDoTask(info.getData1(), TASK_RAZE, GC.getGameINLINE().getActivePlayer(), 1, false, false, false, false);
}
How is this different from the simple raze case?
C++:
	CvMessageControl::getInstance().sendDoTask(info.getData1(), TASK_RAZE, -1, -1, false, false, false, false);
So the active player ID and the (boolean-as-int?) value 1 are passed along. In BtS, the raze task does not take any parameters, so those are new. In AND, CvCity::doTask passes them to CvPlayer::raze. And that function ... does nothing with those parameters. Maybe the modder simply forgot to implement this last piece of their plan. Probably should check if iData2 is positive, and, if so, place a Fort for player iData1. Though improvements have no owner, so I don't think passing the ID of the active player along was necessary. Unless that player was also supposed to get a free unit or something like that.
 
Taking out this bit ...
C++:
        int iRazeAndFortifyCost = player.getRazeAndFortifyCost(pNewCity);
        if (iRazeAndFortifyCost > 0 && player.getGold() > iRazeAndFortifyCost)
        {
            gDLL->getInterfaceIFace()->popupAddGenericButton(pPopup, gDLL->getText("TXT_KEY_POPUP_RAZE_AND_FORTIFY_CAPTURED_CITY", iRazeAndFortifyCost).c_str(), NULL, 4, WIDGET_GENERAL);
        }
... in CvDLLButtonPopup::launchRazeCityPopup might suffice.

I've found the code for placing the Fort on SourceForge: r941
By Afforess, it turns out, and apparently somehow inspired by this thread. (Possible that the implementation was revised by later revisions.) A year and a half later, 45deg decided to remove that feature – entirely, by the sound of it. So it seems that you're now cleaning up the spot(s) that he missed.
 
A year and a half later, 45deg decided to remove that feature – entirely, by the sound of it. So it seems that you're now cleaning up the spot(s) that he missed.
Yeah, at one point Pillaging cities was added to AND2, so 45 removed this part. Than again later inthegrave decided to return the original mechanic. So I guess this is why it's so broken :crazyeye:
 
Few different questions.

1. Is there a trick for only allowing an improvement to upgrade when a specific technology has been researched, without touching the DLLs or SDK (I do not have the SDK installed to my knowledge)?
2. Is there a good place to get in-depth info on how to recycle existing animations for new models? (for example, if I wanted to replace worker models in late game w/o changing the animations)
3. Are there any tips y'all have for someone just getting their feet wet with Civ 4 modding? I'm not new to modding in general, but Civ 4 is a different beast from modding for engines like Source or working with Lua modding for things like Factorio.
 
I believe, in the context of Civ 4, the "SDK" really refers to just the source code of the GameCore DLL. Well, plus a Visual Studio project file to organize the compilation process, but no tools are part of this package, so the SDK can't exactly be installed. This might be splitting hairs; it is true that one needs to install some C++ developer tools (not provided by Firaxis) to do anything with the SDK. So I guess I just want to clarify that SDK modding and DLL modding aren't separate things (when it comes to Civ 4).

Quite a lot can also be done through Python scripts; maybe this is not all that dissimilar from your experiences with Lua. (Although, for extensive game rule changes, I think getting over the initial hurdle of recompiling the DLL is smarter than stretching Python to its limits.) You might be able to undo the improvement upgrade through Python code that runs in the onImprovementBuilt event handler. Perhaps a good example of the kind of creatively improvised solutions that Python modding engenders. One problem I can see with this particular idea is that it won't stop the DLL from showing the turns-to-upgrade countdown in help text. XML-only idea: Let the upgrade happen regardless of tech, but grant extra yield only through TechYieldChanges.

Maybe not something to consider first of all, but, before long, you may want to pick some existing mod(-pack) to work from. Civ 4 does not allow multiple mods to be loaded. So, if you at first work based on the original BtS code and later decide to e.g. incorporate the BUG mod, you may need to manually re-apply many of your changes. Python event handling, for one thing, works a bit differently in BUG (and many of the more complex mods are based on BUG).

(@2: I know nothing about animations.)
 
I'm doing a lot of this Python and XML-side, so I may just do the improvement solution, despite it being somewhat messy. Main thinking I've got is to have a space-age farm upgrade (for future reference, I've replaced the Future Era with the "Information Era" and a later era takes the "Future Era" moniker from it) that can be built once its tech is unlocked, on basically any terrain (save for impassable terrain and oceans, which I believe should probably require a different approach), as a way to offset late-game starvation issues, or bad city placement (I'm looking at you, snow-tile cities...).
 
I'm doing a lot of this Python and XML-side,
Ah, then you know the drill already with Python.
I'd be inclined to avoid the upgrade mechanism entirely by giving the regular Farm a TechYieldChange or by making the endgame farm entirely separate from the regular Farm. But I suppose one needs to know more context to make this call, and you've probably thought it through.

Even when not modifying the DLL, the code can be worth a look for figuring out how Python and XML could make a difference. In this case, there doesn't seem to be much to work with: CvPlot::doImprovementUpgrade
Hm, maybe the getImprovementUpgradeRate call ... no. There's a per-player modifier for improvement upgrade rates (affected by the Emancipation civic), but setting that to 0 would also affect the Cottage improvement line.
 
Ironically enough, I was also considering having a tech-locked upgrade for Town improvements which would only show up in lategame as "metropolitan sprawl."

If it helps to know, the general idea I'm working with is an extension of the late-game to allow players to compensate for issues like desertification, mass starvation, etc. as caused by player actions such as nukes or simply not having enough farmland; the game goes from building wide to building tall and making the utmost out of limited space, so every improvement, unit, etc. gets bonuses as you proceed further into late-game; one major change I've got planned is to move the Space Race victory a bit further into the future (since present-day tech is nowhere near advanced enough for that lol).
 
Another question: what's involved in adding new corporations (NOT modifying existing ones)? I've got an idea for film companies, record labels, etc. that provide luxuries and productivity bonuses in exchange for an upfront economic hit (for instance, a media corporation will nix gold from the city it's in while giving an insane amount of tax revenue to the capitol along with an associated luxury, say "Hit Movies" or "Hit Games" or something like that)
 
Hi ,
There are vip corporations and other mods.
I suggest browse in the mod components and different existing mods.
Youll find, that most of the ideas and innovation were already done in the past 20 years of civ4 modding.

Civ4 offers a supreme modding support for wild ideas.
But,cpp and python, are a must.
 
Oh, I'm well aware of the modding scene being this old. I've been playing Civ 4 for the majority of my life lol
I'm just tryna make a mod I'd want to play, and if that means reinventing the wheel, I'm all for it :lol:
 
@spiro9
As @keldath said look around in mods. CoM for example has all the things you mentioned above:
- improvements upgraded automatically or manually by different techs (Farm-> Done Farm, Town-> Suburb)
- I have recently added a lot of new corporations, their number is above 30 now 🙂
 
Would it be fine if I rip some of the XML for that from the files?
For what exactly? If it's corporations, you'd need to adjust fonts a lot. And there's a chance they would still not work without DLL tweak too.
 
Another one team, hopefully you know and possibly it's easy but I've wondered for a while...

Do you know how to put an Icon picture on a string of text in PYTHON ? (would be a nightmare to port the whole thing to C++)
To enrich some of my widgets in CvGameUtils :


I can do it in C++ (done here below for my Madness option, code in CvGameText.cpp)
1732198897229.png


1732198841811.png



For my Python widget I would like the picture of the given (wonder/building) just before the name of the wonder
1732198737044.png


I know how to do characters etc as per the star or any other as below
1732198787498.png


Basicall am asking what is the : u"%c% ... of pictures/icon if it's any possible...
 
I have another one which is much more worrying if you guys can help in any way...

I've got an error thrown out when I launch a new game I would say 1 out of 15 times (which is way too much but difficult to isolate).
Error is major enough that the interface won't display at all (clearly CvMainInterface cannot be processed),
But mega-weirdly if I reload the save Turn 0 it works totally fine each time




This popup is the culprit, only appears Once -
1732494117032.jpeg




it's hidden behind a multitude (way to many to click or count) of this even more generic error)
1732494106294.jpeg




Maybe a lead, the game AFTER I crashed like that, I relaunch the game, if I create new game I get this error...
1732494305214.jpeg

...which looks like a map error so didn't puzzle me at first, but the map is fine (tried many time) it only just appears the LAUNCH after the crashing one...





I'm just at loss of where to look... any idea welcome...
Only think I can do is rebuild step by step everything I have done since last stable built, but I didn't do mid-version saves and I spent tons of time on my 2.40 (last published is 2.39), would take me ages to redo/rebuild all...
 
If I desactivate the python showing of exception, I of course have a screen without interface as expected.

1732495201272.png



I think it has to do with the COMMERCE Type ?
The error clearly indicates it's at that level... I don't know of my touching anythign with any characters

1732495332779.png



And I have this GameFontDisplay screen (from Platyping) and it's of course EMPTY when I doing it on a failed game start save
1732495358145.png
 
It seems to say that it can't encode a description string of one of the commerce types. I guess those descriptions would just be "Gold", "Research" - loaded from TXT_KEY_COMMERCE_GOLD etc. Maybe somehow it can't encode any string and already fails on commerce ID 0 (gold). Would be easy enough to print some more info to PythonDbg.log. Or maybe it's already apparent from the log that the existing print statement in addIconToMap is never reached(?). I also see a line #print FontIconMap. Perhaps interesting to uncomment that for a test. (Not sure if that data structure can really be printed this easily; but it looks like someone found it useful enough to keep it around, so ...) Also wondering if, when you reload on turn 0, will the font icon map be loaded again, successfully this time (perhaps through that 14 in 15 chance of it working correctly in general) or if the map remains unavailable. Log output should shed light on that.

Further wondering if this font icon map is even needed. The only use of the getIcon function that I can find is in cheatTechs in CvDebugTools.py. Looks like most of the code uses FontSymbols and CvInfo::getChar directly instead. So removing the initDynamicFontIcons call could work as a makeshift solution.

The previous question is about inserting DDS graphics in text, I believe? I would assume that the graphic needs to be positioned separately through addDDSGFC. Though there could be some simpler way ... Maybe the <img> tags only get properly processed when they are in help text that the EXE obtains from the DLL.
 
Thanks for your feedback f1rpo, it kept me motivated to look...

I quickly realized that I biased my question too much and put you in a situation to explore the wrong path together...

I rolled back things after things with no success so I went for the bazooka solution and re-started from scratch on the last version (2.39).
Sad for me I hadn't made proper mid-version backup, but good for me I take excellent notes of all changes (every line in C++ is finishing with //2.40a, 2.40b, for example),
So I was happily surprised how quickly I could progress with careful use of WinMerge (still a lot of late nights this week for it...).

In the end the issue was with the last thing I had added (of course) - a new Trait which I'm not quite sure why created this, there were 4-6 files to change at the same time for that particular change so I'm not completely sure. My current guess is there is a dependency on the order in which XML files are loaded which I didn't respect and it didn't understand my string (my trait string?) at all.

I kept pushing and released my new version just now (https://forums.civfanatics.com/thre...etitive-expansion.648750/page-3#post-16719432), I leave the 2 above points to look at eventually in next version/next year

Will enjoy this one for now & thanks a lot for continuous feedback and help
 
Back
Top Bottom