Merging BUG with other Mods

I meant each mod, but perhaps you've done that already. The US mod probably requires several Python modules, and you can't really import each one separately because they depend on each other.

I was suggesting that, if you don't do this already, get mod X merged and working. Only then try to merge in mod Y, then mod Z, etc.
 
I meant each mod, but perhaps you've done that already. The US mod probably requires several Python modules, and you can't really import each one separately because they depend on each other.

I was suggesting that, if you don't do this already, get mod X merged and working. Only then try to merge in mod Y, then mod Z, etc.


Roger that... that's exactly what I'm doing. One at a time... :cool::crazyeye:
 
BUG will look in several places for the INI files. BugPath shows the order, though I suspect I have let the comments drift from the code. :( If it can't find an INI file, it puts it in the first folder it finds in its list. The System tab of the BUG Options Screen shows the folders it found under Search Paths. Only one set is needed.


Ok, so in BugPath, I would set the ModFolder to this, for example?

Code:
modFolder = MY MOD I'M WORKING ON

Now, what if I wanted all the BUG related INI files created in the <root>/BUG Mod directory of the mod, instead of the <root> directory? How would I set that up? Also, how would I set up BUG to look in the <root>/BUG Mod directory, first?

Would I modify:

Code:
modDir = None

:confused:
 
modName in CvModName.py determines the name of the settings folder now and nothing else. modFolder is figured out from BTS itself and shouldn't be messed with. It's the name of the folder in the Mods folder if a mod is running or None if not.

Any INI files that are found will be used, so if you really want to store the BUG INI files in one folder and the other mods' INI files in another folder, you could create empty files where you want them to go (as long as they're on the search paths).

Here is the code that sets up the search paths:

Code:
if (userDir):
	if (modName):
		addIniFileSearchPath(os.path.join(userDir, modName))
		addIniFileSearchPath(os.path.join(rootDir, modName))
		if (modDir):
			addIniFileSearchPath(os.path.join(modDir, modName))
	if (modDir):
		addIniFileSearchPath(os.path.join(modDir))
	addIniFileSearchPath(os.path.join(rootDir))
if (appDir):
	if (modName):
		addIniFileSearchPath(os.path.join(appDir, modName))
	addIniFileSearchPath(os.path.join(appDir))

  • userDir: "My Games" folder
  • rootDir: location of Civ4BeyondSword.exe
  • appDir: "My Games\BTS" folder
  • modName: from CvModName.py
  • modDir: mod's folder (modFolder above is just the base name of the folder)
 
modName in CvModName.py determines the name of the settings folder now and nothing else. modFolder is figured out from BTS itself and shouldn't be messed with. It's the name of the folder in the Mods folder if a mod is running or None if not.

Any INI files that are found will be used, so if you really want to store the BUG INI files in one folder and the other mods' INI files in another folder, you could create empty files where you want them to go (as long as they're on the search paths).

Here is the code that sets up the search paths:

Code:
if (userDir):
	if (modName):
		addIniFileSearchPath(os.path.join(userDir, modName))
		addIniFileSearchPath(os.path.join(rootDir, modName))
		if (modDir):
			addIniFileSearchPath(os.path.join(modDir, modName))
	if (modDir):
		addIniFileSearchPath(os.path.join(modDir))
	addIniFileSearchPath(os.path.join(rootDir))
if (appDir):
	if (modName):
		addIniFileSearchPath(os.path.join(appDir, modName))
	addIniFileSearchPath(os.path.join(appDir))

  • userDir: "My Games" folder
  • rootDir: location of Civ4BeyondSword.exe
  • appDir: "My Games\BTS" folder
  • modName: from CvModName.py
  • modDir: mod's folder (modFolder above is just the base name of the folder)

Ok, so... in vanilla BUG 3.6, it looks like it searches for the INI files go in Mods\BUG Mod\BUG Mod directory first, then Mods\BUG Mod second. How do I modify the code for BUG to search in, say, Mods\MyMod\BUG Mod first, then in Mods\MyMod second?

Right now, it's set to search in the root directory of Mods\MyMod first, which causes all the INI files to be created there, regardless if I have the exact same INI files in the Mods\MyMod\BUG Mod directory or not.

Basically I'm trying to keep my root directory clutter free. :)
 
How do I modify the code for BUG to search in, say, Mods\MyMod\BUG Mod first, then in Mods\MyMod second?

That should be what is happening. The name of the mod folder (BUG Mod 3.6 or MyMod) is determined by BUG automatically. So your example seems right in line with what BUG does.

Now, if you want to alter the order, you can change the code I posted in BugPath.py. You can remove other paths and leave just the one you want. I have multiple paths to allow people to install multiple versions of BUG and share the settings.

Sorry to be rushed, gotta go shopping. Does that answer your question?
 
That should be what is happening. The name of the mod folder (BUG Mod 3.6 or MyMod) is determined by BUG automatically. So your example seems right in line with what BUG does.

Now, if you want to alter the order, you can change the code I posted in BugPath.py. You can remove other paths and leave just the one you want. I have multiple paths to allow people to install multiple versions of BUG and share the settings.

Sorry to be rushed, gotta go shopping. Does that answer your question?

I figured it out...

Code:
if (userDir):
	if (modName):
		addIniFileSearchPath(os.path.join(userDir, modName))
		addIniFileSearchPath(os.path.join(rootDir, modName))
		if (modDir):
			addIniFileSearchPath(os.path.join(modDir, [COLOR="Red"]modName[/COLOR]))
	if (modDir):
		addIniFileSearchPath(os.path.join(modDir))
	addIniFileSearchPath(os.path.join(rootDir))
if (appDir):
	if (modName):
		addIniFileSearchPath(os.path.join(appDir, modName))
	addIniFileSearchPath(os.path.join(appDir))

I changed the part of code that I highlighted in red, "modName" and changed it to:

Code:
if (userDir):
	if (modName):
		addIniFileSearchPath(os.path.join(userDir, modName))
		addIniFileSearchPath(os.path.join(rootDir, modName))
		if (modDir):
			addIniFileSearchPath(os.path.join(modDir, [COLOR="Red"]modBug[/COLOR]))
	if (modDir):
		addIniFileSearchPath(os.path.join(modDir))
	addIniFileSearchPath(os.path.join(rootDir))
if (appDir):
	if (modName):
		addIniFileSearchPath(os.path.join(appDir, modName))
	addIniFileSearchPath(os.path.join(appDir))


Further up the file, where the imports begin, I put:

Code:
modBug = "BUG Mod"



Now when I fire up the game, the first directory it looks for is Mods\MyMod\BUG Mod.
Where before, it was going to Mods\MyMod\MyMod.


So I got it where I want it now. :crazyeye:
 
I've added a new trait to my mod. It works, and all, no problems, not getting any python exceptions, or even anything in the logs. But for some reason it's not showing up in the Sevopedia. If I hover over a leader with the trait, that works fine, but I mean in the list of traits in the sevopedia, it's not listed. Now I bet this question will lead me to my answer: Where are the buttons for the traits in the sevopedia defined? It's not traitinfos, and I can't find it anywhere. Also looked through the Sevopedia Python to no avail. Could someone point me to what I am missing?

Edit: found it, it's in TraitUtils, hidden back there. But for some reason it don't like this:
gc.getCommerceInfo(CommerceTypes.COMMERCE_SCIENCE).getChar()
Says COMMERCE_SCIENCE is bad, what is science called?
Ahh, It's COMMERCE_RESEARCH

Unfortunately, that still didn't work. It's not showing up in the sevopedia, after adding it to trait utils (no longer throw up a python exception though now that I've used the right words, lol).

So yeah, anyone know why the added trait isn't showing up in the Sevopedia?
 
Calling TraitUtil.addTrait() should be all that you need to do. Can you post what you added to TraitUtil?

If you want it to have a strategy article in the Pedia, you need to add your new trait to XML/BasicInfos/CIV4NewConceptInfos.xml and put the article in XML/Text/TraitsPedia_CIV4GameText.xml.
 
I've done some more doc work here.

  • Overview: Added note about the use of "mod" vs. "module" in the docs.
  • Configuration: Fixed a few errors and clarified some things.
  • Events: Completely reorganized the page and defined normal and popup events and event handlers and how to handle them appropriately.
 
I'm back. :)


Ok, I know this may be beyond the realm of BUG Mod support, but this little bug is really annoying the crap out of me! :lol:


Ok, I have the BUG Mod merged with Kael's Assimilation Mod. It was a fairly straight-foward merging... the only file the two shared wtih each other is CvMainInterface.py.

Well, I did the file compare, and merged accordingly, went to fire up a game, and this comes up:

Code:
Traceback (most recent call last):

  File "CvScreensInterface", line 963, in forceScreenRedraw

  File "CvMainInterface", line 3138, in redraw

  File "CvMainInterface", line 6662, in updateScoreStrings

UnboundLocalError: local variable 'yCoord' referenced before assignment
ERR: Python function forceScreenRedraw failed, module CvScreensInterface


It's just these two mods merged together and nothing else... because I'm trying to isolate this bug and fix it. I know it has something to do with yCoord... but what did BUG Mod do to change this? More importantly, how do I fix this?

I have attached the modified file so you can have a look.
 

Attachments

  • CvMainInterface.zip
    52.5 KB · Views: 93
File "CvMainInterface", line 6662, in updateScoreStrings
Look at line 6662 in your main interface file. It will contain a reference to yCoord. You are trying to use a variable before you have assigned it a value. Find where you give it a value and make sure that you don't (logically) use it before then.
 
I think I may have nipped it in the butt...

All I did was add an extra TAB (indent) to the second grouping of code that Kael added. Fired up the game and no Python errors at all reported in the log.

It looks like the indentation was the culprit (I think).
 
All that code added by Kael actually needs to run whether or not the icons are aligned. These look like additional lines shown above the scoreboard. Also, the two lines after it that resize and show the ScoreBackground panel need to be executed in the else block of the "if bAlignIcons" test above Kael's code, but it depends on the number of lines that Kael's code produces.

Scoreboard.py's draw() function needs to return its final yCoord value (probably named differently, e.g. "y") at the end. The if block above needs to store that value into yCoord.

Then all of Kael's code should run as it is, unindented.

Finally the ScoreBackground panel needs to be resized with iCountSpecial taken into account. Check out Kael's original code (not in this file) that resizes ScoreBackground. This part needs to be out-dented one level.
 
All that code added by Kael actually needs to run whether or not the icons are aligned. These look like additional lines shown above the scoreboard. Also, the two lines after it that resize and show the ScoreBackground panel need to be executed in the else block of the "if bAlignIcons" test above Kael's code, but it depends on the number of lines that Kael's code produces.

Scoreboard.py's draw() function needs to return its final yCoord value (probably named differently, e.g. "y") at the end. The if block above needs to store that value into yCoord.

Then all of Kael's code should run as it is, unindented.

Finally the ScoreBackground panel needs to be resized with iCountSpecial taken into account. Check out Kael's original code (not in this file) that resizes ScoreBackground. This part needs to be out-dented one level.

Sorry for my ignorance, Emperor... but are you telling me there's more to it than indenting (one extra Tab) the second batch of Kael's code? I think I get what you're explaining... you're telling me that Kael's code needs to execute no matter what, and not under "else"?

I noticed that BUG does add an "else" to the code (right above the second batch of Kael's code), where in the vanilla code it does not.
 
Correct.

BUG adds the "if bAlignIcons:" test which checks whether or not BUG needs to draw the scores with the Scoreboard.py module. If so, it also sizes and shows the semi-transparent background behind the scores. If not, CvMainInterface.py has already drawn the scores, and it will size and draw the background.

Kael's code adds up to 3 new lines above the scoreboard that should display whether BUG aligns the scoreboard columns or not, and the background should be expanded to contain them.
 
Were there extensive changes in version 3.6 that would make it harder to merge with other mods? Because I was asked it I had a version of my mod that was already merged with BUG 3.6 and set up to handle Sevopedia. I've been using it with Better AI and mod and BAT 1.1 but I don't know what's different in BUG 3.6 that requires more merging work that before.
 
Were there extensive changes in version 3.6 that would make it harder to merge with other mods?

As compared to BUG 3.5? No. 3.6 makes it a bit easier as you don't need to worry about CvModFolder or CvModName (for the most part) anymore. BUG figures out where your mod is installed automatically. modName from CvModName only determines the name of the folder holding the INI and help files now.

Other than that, 3.6 just has more features that won't make merging any harder or easier such as the Strategy Layer.
 
Hey, is there an easy to way to just disable Advanced Unit Naming, from the Python I mean, just so that that part of the program doesn't work? I'd really rather just get rid of this, due to the python exceptions it throws. I know I could go through and add all the new units from my mod to the list, but that's really a PITA, and not worth it. I also know I can just disable it through the BUG options, but I'd rather just rip it out entirely.
 
You should only have to update Unit Naming if you add new combat types. What Python errors are you getting? Post a few.

You can rip out Unit Naming by removing the <load "Unit Naming"/> line from init.xml.
 
Top Bottom