Merging BUG with other Mods

The Modders' Corner has all the BUG merging documentation. If anything is lacking, please don't hesitate to ask or suggest something.
 
Thanks EF. That's what I needed. If I may suggest though: On the Configuration page, in the XML section at the bottom, mention there that the XML entry is called through the BugInit module, and that the module referred to in the XML needs to be in a folder called (to use the extant example) NextWarBugUtils, within the Assets\Python\Contrib directory. I had a devil of a time figuring that out.
 
Your Python modules can go in any subfolder of Python. It's the configuration XML files that must be in the Config folder directly (for now).
 
The only time the subfolder matters is when you're trying to override a file with the same name in BTS's core Assets folder. This probably isn't the case given the file name. :) In BUG I put things into folders based solely on my personal organization preference. Are you including the folder hierarchy somewhere, perhaps in an XML configuration file?

Normally in Python only the root (Python) folder would be added to the Python system path. To import a module that's in the Contrib folder you would do

Code:
import [B]Contib.[/B]NextWarBugUtils

But Firaxis decided to add every subfolder to the system paths, making this unnecessary.
 
Hey EF, I took a week or so off, to rest my head :) But I'd still love to get this mod of mine to work. I may be getting closer to isolating the problem in my python files. Right now, here's the experimental python I'm working with:

Code:
# AgrNat
#

from CvPythonExtensions import *
import CvUtil
import CvScreensInterface
import CvDebugTools
import CvWBPopups
import PyHelpers
import Popup as PyPopup
import CvCameraControls
import CvTopCivs
import sys
import CvWorldBuilderScreen
import CvAdvisorUtils
import CvTechChooser
import GodsOfOld
import pickle

# globals
gc = CyGlobalContext()
localText = CyTranslator()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo
PyCity = PyHelpers.PyCity
PyGame = PyHelpers.PyGame


class AgrNat:
	def __init__(self, eventManager):


## Agr & Nat Trait Start ##

		player = PyPlayer(city.getOwner())
		pPlayer = gc.getPlayer(city.getOwner())

		iTrait = CvUtil.findInfoTypeNum(gc.getTraitInfo,gc.getNumTraitInfos(),'TRAIT_AGR')
		iTrait2 = CvUtil.findInfoTypeNum(gc.getTraitInfo,gc.getNumTraitInfos(),'TRAIT_NAT')

		if (pPlayer.hasTrait(iTrait)):
			city.changePopulation(1)

		NBuilding = "BUILDING_NAT_BONUS"
		AgrBuilding = "BUILDING_AGR_BONUS"

		if (pPlayer.hasTrait(iTrait2)):
			city.setNumRealBuilding(gc.getInfoTypeForString(NBuilding), 1)

		if (pPlayer.hasTrait(iTrait)):
			city.setNumRealBuilding(gc.getInfoTypeForString(AgrBuilding), 1)

## Agr & Nat Trait End ##

# Agr & Nat Trait Start #

		pPlayer = gc.getPlayer(iNewOwner)
		iX = pCity.getX()
		iY = pCity.getY()
		pPlot = CyMap().plot(iX +0, iY +0)

		iTrait = CvUtil.findInfoTypeNum(gc.getTraitInfo,gc.getNumTraitInfos(),'TRAIT_NAT')
		iTraitAgr = CvUtil.findInfoTypeNum(gc.getTraitInfo,gc.getNumTraitInfos(),'TRAIT_AGR')
		iBuildingMagLev = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_NAT_BONUS')
		iAgrTraitBonus = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_AGR_BONUS')
		iAqueduct = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_AQUEDUCT')
		iBerber = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_BERBER')
		iKalanBonus = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_KALAN_BONUS')

		if (pPlayer.hasTrait(iTrait)):
			pCity.setNumRealBuilding(iBuildingMagLev, 1)
		else:
			if pCity.getNumActiveBuilding(iBuildingMagLev) == true:
				pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_NAT_BONUS"), False)

		if (pPlayer.hasTrait(iTraitAgr)):
			pCity.setNumRealBuilding(iAgrTraitBonus, 1)
		else:
			if pCity.getNumActiveBuilding(iAgrTraitBonus) == true:
				pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_AGR_BONUS"), False)

		if pCity.getNumActiveBuilding(iKalanBonus) == true:
			pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_KALAN_BONUS"), False)

# Agr & Nat Trait End #

## Agr Trait Start ##

		player = PyPlayer(pCity.getOwner())
		pPlayer = gc.getPlayer(pCity.getOwner())
		iTrait = CvUtil.findInfoTypeNum(gc.getTraitInfo,gc.getNumTraitInfos(),'TRAIT_AGR')

## Temp Disabled ##
#
#		if (pPlayer.hasTrait(iTrait)):
#
#			estiEnd = CyGame().getEstimateEndTurn()
#			if ( estiEnd >= 1000 ):
#				pCity.changeFood( +12 )
#			elif ( estiEnd >= 700 ):
#				pCity.changeFood( +8 )
#			elif ( estiEnd >= 500 ):
#				pCity.changeFood( +6 )
#			elif ( estiEnd >= 300 ):
#				pCity.changeFood( +4 )
#
## Agr Trait End ##

This is from tsentom's stuff, with the intended effect of adding a special building for civs with either the Agricultural or Nationalistic trait, and adding an extra population on city growth for Agricultural civs. All the required special buildings are in the xml files.

But as of now, the error I'm getting is about line 35:
Code:
		player = PyPlayer(city.getOwner())

PythonErr says:
File "AgrNat", line 35, in __init__
NameError: global name 'city' is not defined

Just wanted to check with you how to define this kind of thing, instead of just killing myself trying to figure it out by trial and error. Thanks
 
__init__() is called when BUG first initializes your event manager. There is no city to operate on at this time. It looks like all that code after __init__() is intended to be run for various events such as onCityGrowth() and onCityFounded().

Check out CvEventManager for examples of extracting the city (or pCity as you use later) out of the argsList variable inside an event handler.
 
I've added back in the couple of missing units and buildings from BtS in LoR, so that it'll be easier to use scenarios, and just to normalize things. In order to get these units (and a building) to not mess things up, I made the two of them Barbarian UUs and a UB. The strange thing is the barbarian's can't seem to use them, at least I'm not seeing them appear, or being built in barb cities (and yes I defined them as UUs for both the minors and barbarians proper). That's fine really, not the expected behavior, but it doesn't really matter if they can't be built. The thing is though, since they in effect don't exist, I'd like to simply remove them from the civilopedia. I looked around in the sevopedia unit file, and reviewed how I pulled out Legend Units, but it doesn't really compare. So any ideas on how to remove UUs for a specific civ (in this case the barbs/minors), from the Sevopedia?
 
1. Grab the CvCivilizationInfo for the barbs
2. Loop through all unit classes
3. Get the barb UU for that class
4. Remove that unit type from the list
 
How does BUG load the hover text for the tabs?

I've tried searching for strings like TXT_KEY_BUG_OPT_MAININTERFACE__UNITMOVEMENTPOINTSFRACTION_HOVER and get no hits (other then the text entry itself). So how is this getting loaded and displayed in the BUG options screen?

The reason why I'd like know this is that RevDCM hover text uses the help field, and is set like this:
Code:
      </option>        
			<option id="DCM_BATTLE_EFFECTS" key="DCM_BATTLE_EFFECTS"
				type="boolean" default="False"
				get="isDCM_BATTLE_EFFECTS" set="setDCM_BATTLE_EFFECTS"
				label="Battle Effects"
				[B]help ="Displays battle smoke and reduces battle plot yields for a limited time">[/B]
        <change module="RevDCM" function="changedDCM_BATTLE_EFFECTS"/>
      </option>
I tried this:
Code:
      </option>        
			<option id="DCM_BATTLE_EFFECTS" key="DCM_BATTLE_EFFECTS"
				type="boolean" default="False"
				get="isDCM_BATTLE_EFFECTS" set="setDCM_BATTLE_EFFECTS"
				label="Battle Effects"
				[B]help ="TXT_KEY_MOD_REVCONFIG_HELP_BATTLE_EFFECTS">[/B]
        <change module="RevDCM" function="changedDCM_BATTLE_EFFECTS"/>
      </option>
But it wol't load the TXT_KEY_MOD_REVCONFIG_HELP_BATTLE_EFFECTS values I set in the XML text folder. So then I tried reverse engineering it, by copying BUG's text loading for it's hover text, and I can't figure out how this is done, as none of the text strings are in BUG's assets.
 
Ugh, I haven't put this into the documentation yet! It's automatic. You only need the label and help attributes if you don't put translations into a CIV4GameText XML file. They are ignored if you do.

BUG looks for <Text> elements using the <mod> and <option> IDs. The base key is

TXT_KEY_BUG_OPT_<mod>__<option>​

Both IDs are converted to uppercase. The label key appends "_TEXT" and the help key appends "_HOVER" to the base key. Oh, and if you have a list it appends "_LIST" for the items. Note that there are two underscores between the <mod> and <option> IDs.

Yes, the choice of "BUG" in there was unfortunate now that people are using BUG as a base, but it's too late to change that now.​
 
Thanks that works.

A couple requests:

Please separate the BUGOptions_CIV4GameText.xml file into multiple files. Right now it's huge, and this is a serious PITA whenever you add something, even it's just a minor change (as it usually is). Some mods add different languages, for instance LoR has Finnish in it. This means whenever this file changes a little I have to click through hundreds of "differences" simply because of the added finnish tags. I suppose that's the price we pay for adding new languages, but it's a hassle. This would become a virtual non issue if the text for the different BUG config files were separated into their own Text files, a lot easier.

This is less of an issue, and I don't really care all that much, but it would be nice if you only put modified source in the BULL SDK folder. As of now I have to compare the BULL SDK to the BtS SDK, and remove all the files that aren't different when I compare to the RevDCM SDK. And there is no reason as far as I can figure in leaving in standard BtS files.
 
Please separate the BUGOptions_CIV4GameText.xml file into multiple files.

I've been doing that as I go for the sake of organization, but knowing that it actually makes someone's job easier gives me more incentive.

It would be nice if you only put modified source in the BULL SDK folder.

I thought about this for a while when I first setup the BULL file layout. If there was an easy way to setup the makefile so that it would pull files from two places automatically, I'd do it in a heartbeat. But AFAIK I would need to update the makefile every time I touched a new source file for BULL, and I've done that enough times already that I'm very glad I included all of the source.

While this isn't as easy for non-professional-programmers that haven't been exposed to shell scripting, there are command-line tools that will spit out a list of unmodified files that you could send to the rm command (delete). A two line script could pull down the latest BULL and remove all source files that match the original BTS files. If you're interested, install Cygwin and read up on diff.
 
Hey guys, I want to add BUG to my mod. Is it better to add my mod's stuff to BUG or to add BUG to my mod? Or does it matter?

My mod uses Next War as a base and thus far I have only added new religions (I already have a gamefont that will work with BUG and these new religions made) a few new civs and flavored the units and cities. Those are the only changes that have been made so far.
 
BUG is set up to control a lot of what other mods typically just merge into (event manager, game utils, etc), so it pretty much requires you to BUG-ify your mod. BUG itself has many examples (Reminder, Autolog) of events and options.

There is one place where you'll have to do a little more work: Next War stores a simple list in the script data for the game, but BUG uses Stone-D's Toolkit for storing lots of objects in that same place. There's a thread in this forum that talks about merging Next War and BUG, and Cammagno merged it with an older version of BUG.

Feel free to ask questions when you get stuck. The toolkit is pretty easy to use (get and set operations), and that thread should help.
 
Forgive me of my ignorance, I am a lowly graphics modder.

So you're saying that it shouldn't hard to merge, except one difficult part. Where is this thread? I'd like to try and get this finished tonight if I can.

EDIT: So I checked out the NextWar with BUG thread and found THIS THREAD. I downloaded the attachment. Is this all I need to do? Just throw this into my mod? It doesn't look like I have edited any of these files so I should be able to put them right in, correct? Or is there more to it than that?
 
Like I said, that thread was for an older version of BUG (several back), so it can only be used as a guide to help a Python programmer do the same changes to the latest BUG and Next War. Someone else was looking into creating such a merge; you may want to contact them (last few posts in that thread I think).
 
He was looking to merge BAT and BULL, I only want BUG. And it doesn't look like he was successful, at least it didn't seem that way. I'm going to go ahead and try out what Cammagno said. What is this toolkit you speak of?
 
Back
Top Bottom