Quick Modding Questions Thread

What if a player switches civics, the city changes owner (with different civics), or the building is removed again (e.g. conquest).

Doing it in the DLL would be less complicated. Harder, only if you are unfamiliar with DLL modding.
 
What if a player switches civics, the city changes owner (with different civics), or the building is removed again (e.g. conquest).

Doing it in the DLL would be less complicated. Harder, only if you are unfamiliar with DLL modding.
Oh yes there are quite a few problems I just found out now. If the player switches to Serfdom the city doesn't get 1 extra :) even if it has a Forum, this can easily be fixed by moving the code to def onBeginGameTurn so the game checks at the beginning of the turn if any cities have the Forum and awards them 1 :) (of course the code will also have to be modified a bit).
Making the happy citizen be removed if the building is removed via conquest could be done by writing a very short code under def onCityAcquired.
The city changing owner won't make a difference because if the building is kept then the happy citizen remains anyway and if it is removed then it will be removed with the code under def onCityAcquired.
I'll write a code as soon as I can that removes the citizen if the building is removed via conquest.
DLL modding is more complicated for me because I hardly ever mod in the DLL, so if something is possible with Python as well I do it with Python.
 
Yes but sadly there is no other way. You could do it in C++ but that would be more complicated and harder to do.

Thank you very much for sample code! I'll hold off on anything for until I see what the removal code looks like, but it's really nice to know it can be done. Out of curiosity, what would doing it in C++ involve - I actually do have more experience in that than XML and Python from Paradox modding.

What if a player switches civics, the city changes owner (with different civics), or the building is removed again (e.g. conquest).

Doing it in the DLL would be less complicated. Harder, only if you are unfamiliar with DLL modding.

What would the DLL involve?
 
What can I expect to see if the loop is in the exe instead?
Function addresses I expect. Attaching another screenshot (no infinite loop in this one). Apparently, the profiler has access to debug symbols for some of the Microsoft DLLs. Here's a screenshot of an infinite loop in d3d9.dll (from this post in the Tech Support subforum).
 

Attachments

  • function addresses (Very Sleepy).jpg
    function addresses (Very Sleepy).jpg
    474.7 KB · Views: 48
Thank you very much for sample code! I'll hold off on anything for until I see what the removal code looks like, but it's really nice to know it can be done. Out of curiosity, what would doing it in C++ involve - I actually do have more experience in that than XML and Python from Paradox modding.
What would the DLL involve?
I'll do the Removal code tomorrow since it's getting late here for me.
The DLL is made up of many C++ and H files. To find the decompiled DLL go to Leoreth's guide on how to compile a DLL and you can download the source code there but after you edit the specific file you will need to recompile the DLL as well.
Editing the DLL files can be done in just about any text editor and still work, unlike Python which might not work if you edit it with Notepad.
 
What would the DLL involve?
First step is being able to compile a DLL. You can find guides on that in the tutorials forum.

Function addresses I expect. Attaching another screenshot (no infinite loop in this one). Apparently, the profiler has access to debug symbols for some of the Microsoft DLLs. Here's a screenshot of an infinite loop in d3d9.dll (from this post in the Tech Support subforum).
Thanks again.
 
Spoiler :
verysleepyloop.png

Not sure what to make of this. Some of it seems to suggest that we are locked in a fight (getCombatUnit), but what is initCvPythonExtensions? Is it likely it is stuck in some Python code?
 
Going by the profile from the last screenshot I posted, normally, most of the calls to initCvPythonExtensions come from BaseThreadInitThunk in kernel32.dll, which, according to a quick web search, "starts a Win32 thread," (source) so initCvPythonExtensions appears to be a thread entry point. That could make it difficult to tell what the call structure is. Have you taken a look at the "called from"/ "child calls" list and "call stacks" tab for initCvPythonExtensions? (I don't think initCvPythonExtensions is selected in the screenshot.) I guess it could be a Python loop; if so, then I don't think I've ever had to debug such a case. I could still try to load your profile and browse around if you save and upload it and think it might help.
 
Does anyone here have any experience making new effect from scratch? There does not seem to be a good tutorial.
 
Going by the profile from the last screenshot I posted, normally, most of the calls to initCvPythonExtensions come from BaseThreadInitThunk in kernel32.dll, which, according to a quick web search, "starts a Win32 thread," (source) so initCvPythonExtensions appears to be a thread entry point. That could make it difficult to tell what the call structure is. Have you taken a look at the "called from"/ "child calls" list and "call stacks" tab for initCvPythonExtensions? (I don't think initCvPythonExtensions is selected in the screenshot.) I guess it could be a Python loop; if so, then I don't think I've ever had to debug such a case. I could still try to load your profile and browse around if you save and upload it and think it might help.
Yeah, should have taken the screenshot with that call selected, although its stack didn't seem helpful to me. Will come back with more info when I have it on hand.
 
Spoiler :
verysleepyloop2.png

Here's the called from/child calls. Doesn't seem to be very informative, call stack also only contains memory addresses from the exe. I have attached the sleepy file.
 

Attachments

Thanks ... I agree that the initCvPythonExtensions call graph isn't helping.
If there were simply some non-terminating while loop in Python, then I don't think so many different functions would get called. Looks like part of the graphics keep getting updated. As for getCombatUnit, the call originates from CvPlot::isFighting. It seems that the EXE calls that function all the time when the game is just idle. That said, there are also calls to CvMissionDefinition::getUnit – that function doesn't normally get called while idle (at least it didn't just now when I tested it). Might be interesting to set a breakpoint there to see which unit (or NULL? :undecide:) is being returned. Or maybe some other DLL functions could provide clues in the debugger.
 
Thanks for looking into this. CvMissionDefinition doesn't mean anything to me, is that a mission in the sense of a unit order, e.g. building improvements or healing etc.? Because I actually have implemented a couple of custom missions that may potentially have an implementation error.

It's really weird how this manifests in the game too. It's not really frozen, your choice of idle is a much better way of describing it. It's more that the game is in a state where it did not correctly process to where the player can take an action, or in this case receive a popup window.

I will try to dig some more into the mission code and try to catch it with a breakpoint.
 
Last edited:
CvMissionDefinition doesn't mean anything to me, is that a mission in the sense of a unit order, e.g. building improvements or healing etc.?
Looks like it's only for combat animations (CvBattleDefinition) and air mission animations (CvAirMissionDefinition). Those are the two derived classes in CvStructs.h, and I saw the EXE call CvMissionDefinition::getUnit only in those circumstances in my test yesterday; e.g. unit movement and worker missions did not result in a getUnit call.
 
Yeah, I tried the debug the getUnit call but wasn't very successful because the EXE calls it a lot, all of the ones I have seen were MISSION_AIRPATROL, which makes sense. It's late in the game and there are probably a lot of air units on defensive patrol everywhere. So I guess that accounts for those calls in the profiling. The game was idle but animations were still displayed.
 
Ah, sorry! I totally forgot about writing this code @Pretentious Username!
I tried now but it is a bit more complicated then I thought. My plan was to put a code under def onPlayerSwitchCivics to make the happy citizen be removed if the player switches civics but I realized that there is no function called def onPlayerSwitchCivics :lol:!
Anyway you shouldn't worry about the building being removed because if the building is a unique building then it will automatically be replaced by the original kind of building it the city is conquered. For example if someone conquers Rome and Rome has a roman Forum then the Forum will disappear and a market will replace it.
Well I think here it would actually be better and take less time if you try to do it in the DLL. With Python it is not that great to make actual building effects because of all the other things you need to check on but it is good for making Wonder effects because wonders are not built more then once.
Something you could do if you don't know where to start is check the source code of the DLL from a mod that has this effect (with the civic building happiness) and inspire yourself from that code.
Good luck!
 
Anyway you shouldn't worry about the building being removed because if the building is a unique building then it will automatically be replaced by the original kind of building it the city is conquered.
. . . unless you also have the Assimilation modcomp ;)
 
Back
Top Bottom