Merging BUG with other Mods

@Ninja2 - Your XML file looks fine. The file PythonDbg.log will show you what's happening as BUG initializes. Open that file and search for the names of those Python modules above to see if they're being loaded.

Post the contents of PythonErr.log after running your mod and I'll take a look at the error. If that file is empty, post a zip of PythonDbg.log and those two modules.
 
Thanks - the two modules aren't loading, according to PythonDbg.log. Those two modules are not anywhere in the log. Bug loads fine, OTOH. PythonErr.log is empty.
 

Attachments

  • PythonDbg.zip
    4.1 KB · Views: 168
Thanks - the two modules aren't loading, according to PythonDbg.log. Those two modules are not anywhere in the log. Bug loads fine, OTOH. PythonErr.log is empty.

It sounds like your modified init.xml is not being used. Where are your mod's files installed? One thing to try is to turn on full debugging output for BUG. Modify "BUG Core.ini":

Code:
# Selects which logging messages get printed to the PythonDbg.log file. Each level includes messages of all levels below it.
# Default: 1

[B]File Level = 0[/B]
 
Mod and BUG are merged into a subfolder in the mod directory. The init.xml is placed in the config folder in the assets directory. Could BUG load without incident, if the init.xml was not used? The expanded Dbg.log attached.

EDIT: I just found out that even though I have placed all of the BUG files inside the Merged Mod folder, and configured the xml as shown, BUG still looks in the BUG Mod folder (shown in the systems tab in-game). I suspect this happens via the CvModName.py file. Editing that file from
Code:
#CvModName.py

modName = "BUG Mod"
displayName = "BUG Mod"

to
Code:
#CvModName.py

modName = "Merged Mod 0.85"
displayName = "Merged Mod 0.85"

didn't help. If I do this, I get plenty of errors (mostly about stuff already loaded, initialized, etc).
 

Attachments

  • PythonDbg.zip
    4 KB · Views: 153
modName = "Merged Mod 0.85"

Yes, you must change this to be the name of the folder containing your mod. Can you post the PythonErr.log when you run it this way? BUG needs this folder name to find the XML config files.

I added this part to the docs under Configuration. I still need to add a more tutorial walkthrough of getting your mod up and running (creating your own <mod>.xml and adding it to init.xml).
 
Sure thing! And thanks for your time. I hope you can use this to improve the merge guide. :D
 

Attachments

  • Logs.zip
    7.8 KB · Views: 157
@Ninja2 - BUG is complaining about your XML files.

Code:
11:53:07 INFO : BugCore - creating uninitialized mod FavoriteCivicDetector
11:53:07 BugConfig - [B]failure parsing C:\Privat\CIV4\Beyond the Sword\Mods\Merged Mod 0.85\Assets\Config\MergedMod.xml at line 2[/B]
11:53:07   error parsing XML: <?xml?> declaration not at start of document
11:53:07 BugConfig - [B]failure parsing C:\Privat\CIV4\Beyond the Sword\Mods\Merged Mod 0.85\Assets\Config\init.xml at line 113[/B]
11:53:07   error parsing XML: <?xml?> declaration not at start of document

Can you post those two XML files?
 
...and that's the key!

Stupid python!!!!! :mad::mad::mad:

I had a blank line as line 1 in MergedMod.xml, and that was enough to cause the init.xml to reject the file. The modules now loads correctly! :goodjob:

Thanks a bunch for this.
 
I've added two sections to the page about BUG Core Options.

Storing Options tells you how to create INI files and store your options in them across gameplay sessions.

Parameterized Options are used to provide easier access to multiple related options in Python.

For example, say you have one option setting per Combat Type. To get the setting for a particular unit, you convert the unit's combat type into a string:

Code:
eCombatType = unit.getUnitCombatType()
info = gc.getUnitCombatInfo(eCombatType)
type = info.getType()

Parameterized options allow you to replace this ugly manual code

Code:
if type == "UNITCOMBAT_AIR":
    value = MyMod.getCombatAir()
elif type == "UNITCOMBAT_ARCHER":
    value = MyMod.getCombatArcher()
...
elif type == "UNITCOMBAT_SEIGE":
    value = MyMod.getCombatSeige()

with this easier code

Code:
value = MyMod.getByCombatType(type)

and let BUG sort it out. :)
 
EF, got a knew one, and I think it's related to my mod merging. The logs were inconclusive for me (see, I was a good boy! :lol:), as they seem to be referencing parts I haven't made changes to...

When building a certain Wonder, I can't get into the City Screen, but only for that city. All the rest work fine. Upon completing the wonder, the game crashes out. The python log is referencing CvScreensInterface & CvMainInterface, but not in places I ever touched them. I've included them both, and the log, and the CvEventManager, which is what I think is causing the trouble... The changes made to CvEventManager for this Wonder are bracketed with RichMod - The School of Confucius.

Thanks EF. Hope it's not something obvious this time... :blush: :D
View attachment Log & Python files.rar
 
@draco - When reading Python stack traces (PythonErr.log), always go backwards.

Code:
Traceback (most recent call last):
  File "CvScreensInterface", line 947, in forceScreenRedraw
  File "CvMainInterface", line 2993, in redraw
  File "CvMainInterface", line 3386, in updatePlotListButtons

RuntimeError: unidentifiable C++ exception
ERR: Python function forceScreenRedraw failed, module CvScreensInterface

The error occurred on line 3386 of CvMainInterface in its updatePlotListButtons() function. Looking at your file I see that part is the standard (non-BUG) code that draws the building graphic for the first item in the build queue.

My guess is that the wonder you've added isn't set up correctly--most likely its art file isn't correct. What happens if you open the Sevopedia and select that wonder in the list? Do you see it in the 3D area?
 
OK, so, now that I've run screaming :eek: :cry: from NifSkope, any suggestions?

Seriously, that program doesn't make any sense at all. I finally got it to recognize the DDS files for the two Wonders that didn't show up properly in the Civilopedia (by doing nothing more than renaming them. Even that didn't work on one of them, I had to futz around a bit, I don't what I did to finally make it work...), so now the 3D constructs in the Nif viewer has colour instead of just being a solid white shape. But they still don't show in the Civilopedia, and loading a game from after one of them was built causes an insta-crash... :wallbash:
 
You're bang-on EF, but how the heck did you figure that out?

The key is to start at the bottom of the stack trace. I didn't explain it as I was heading off to bed, but the way a stack trace works is that it shows you the call chain of where the program (Python) was when it encountered the error.

Here's a real world example. "When I went to the supermarket, I broke my leg. I went to the supermarket, but they didn't have any beer. So I went to a liquor store, but they didn't have any good wine. So finally I went to a winery, and while taking their tour I fell down the stairs and broke my leg."

That would be shown by Civ4 like this:

Code:
Traceback (most recent call last):
  File "Supermarket", line x, in buyGroceries
  File "LiquorStore", line x, in buyBeer
  File "Winery", line x, in buyWine
  File "Winery", line x, in takeTour

RuntimeError: broke leg
ERR: Python function buyGroceries failed, module Supermarket

Okay, that was a little contrived, but hopefully it helps while reading the following.

ERR: Python function forceScreenRedraw failed, module CvScreensInterface​

This is Civ4's generic indicator that it caught an error that was not handled by the Python code. It tells you the module and function that it called initially, but that's not where the error actually happened. Above, I didn't break my leg at the Supermarket, but I broke it sometime during my trip to the Supermarket

RuntimeError: unidentifiable C++ exception​

This is the error it encountered. "unidentifiable C++ exception" means that Python made a call to the DLL or EXE (both C++ code) that failed an assertion. An assertion (or assert statement) is code that enforces a logical constraint, e.g. x is non-negative, by "dying" if the constraint is violated.

File "CvMainInterface", line 3386, in updatePlotListButtons

This is where you should start your investigation. This line must have called a C++ function in the DLL or EXE that failed. Looking in your file we see

Code:
[B]screen.addBuildingGraphicGFC[/B]( "InterfaceUnitModel", 
        [B]CyInterface().getOrderNodeData1[/B](i), 
        175, yResolution - 138, 123, 132, 
        WidgetTypes.WIDGET_HELP_SELECTED, 0, -1,  
        -20, 30, 0.8, False )

The two bold parts are C++ calls. The second one is asking the interface for the ith item in the build queue. This could fail (I'm guessing) if there isn't a city currently selected, but you can see a few lines above that this was checked already, so it's probably safe.

The only other culprit is addBuildingGraphicGFC(). What other information do I have? You've added a new wonder, and only the city that is building that wonder is getting this problem. It may not be a smoking gun, but I'd say there's GSR on your hands. ;)

File "CvScreensInterface", line 947, in forceScreenRedraw
File "CvMainInterface", line 2993, in redraw​

These are breadcrumbs along the way to the error. You use the lines above the line where the error occurred to walk back through the Python code that got you to the error. You can use them to find more context or evidence to determine the actual problem.

They are helpful because you can call any function from any other place in Python, so these lines show you the trail that lead you to failure.

And now that I know the NIF is garbage, I guess I can't avoid NifSkope anymore, huh? :sad:

Can't help ya there, but it sounds like you know where to start. :)
 
OK, so, now that I've run screaming :eek: :cry: from NifSkope, any suggestions?

Same suggestion: post in the graphics modding forum as much detail (with files) as you can. I'm not a graphics guy, so I have no idea what the problem is.
 
I've added information about the three Python configuration files used by BUG and BugPath: CvModName, CvModFolder, and CvPathOverride. The last two are new to BUG.

Check out the Configuration section.
 
Not on every system the following path is the correct path to my documents.

"C:/Documents and Settings/[UserName]/My Documents/My Games/Beyond the Sword"

For me, for example, this is:
"E:\Eigene Dateien\My Games\Beyond the Sword"
 
I'll add a description of how BugPath works in detail soon, but for now . . .

BugPath uses the Windows registry and the path to the Civ4 executable to attempt to locate the CustomAssets folder.

When that fails, you need to use the CvPathOverride.py file. It is up to the player to modify the file and type in the path for their system. I cannot provide the correct path, and the path in that file is the default so they have an example.

Does that make sense?
 
I've added a new <shortcut> element to the XML configuration files for binding a keyboard shortcut to a Python function.

The <mod> element now has a module element that will be used as a default for any child elements requiring one.

See Reminder.xml for an example of these new features in action.
 
Top Bottom