Merging BUG with other Mods

I have begun working on a BUG Modding tutorial on our wiki. It covers some of the common errors you'll experience working with BUG and gives you the basics of building a mod from scratch using BUG.
 
I have a mod that uses Assets\Python\CvGameUtils.py. Are there any special instructions for merging that file into BUG?

Yes, there is BUG documentation, and I wrote a tutorial that is not specific to BUG that described three different methods. BUG's method is very similar to the first method I describe in that thread.

I'm currently writing a step-by-step BUG tutorial, and the section on Game Utils is coming up soon.
 
I'm sorry EF, I don't get it. The CvGameUtils merger I mean...

Here's what my Mods\BUG & BULL Mod\Assets\Config\RichMod.xml file looks like:
Code:
<mod id="RichMod" 
	 name="RichMod" 
	 author="Draco" 
	 version="1.0" 
	 date="10/30/2008"
	 url="">
	 
	<events module="CvRichModEventManager">
		<!--arg type="key" value="Alt Ctrl N"/-->
	</events>

	<gameutils module="RichModGameUtils" class="RichModGameUtils"/>
	
</mod>

And here's Mods\BUG & BULL Mod\Assets\Python\Contrib\RichModGameUtils.py:
Code:
import CvUtil
from CvPythonExtensions import *
import CvEventInterface

# globals
gc = CyGlobalContext()

class RichModGameUtils:
	"Miscellaneous game functions"
	def __init__(self): 
		pass
	
	def getBuildingCostMod(self, argsList):
		iPlayer, iCityID, iBuilding = argsList
		pPlayer = gc.getPlayer(iPlayer)
		pCity = pPlayer.getCity(iCityID)
		
		iCostMod = -1 # Any value > 0 will be used

		pBuildingInfo = gc.getBuildingInfo(iBuilding)
		
		iPalace = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_PALACE')
		iGreatPalace = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_GREAT_PALACE')
		{etc etc etc}
		iPaya = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_SHWEDAGON_PAYA')
		iMoai = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_MOAI_STATUES')
		iPope = CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'BUILDING_APOSTOLIC_PALACE')
		
		aiWonderList = [iPalace, iGreatPalace, iVersailles, iHero, iNational, iGlobe, iPark, iHermitage, iOxford, iWallStreet, iIron, iWestPoint, iRushmore, iRed, iPyramids, iStonehenge, iLibrary, iLighthouse, iGarden, iColossus, iOracle, iParthenon, iWat, iHagia, iItza, iSistine, iMinaret, iNotre, iTaj, iKremlin, iEiffel, iLiberty, iBroadway, iGraceland, iHollywood, iGorges, iPentagon, iUN, iSpace, iArtemis, iSankore, iWall, iZeus, iMausoleum, iCristo, iPaya, iMoai, iPope]	

		pPlayer1 = gc.getPlayer(pCity.plot().getOwner())

		bSphinx = gc.getInfoTypeForString("BUILDING_SPHINX")
		obsoleteTech = gc.getBuildingInfo(bSphinx).getObsoleteTech()
		if ( gc.getTeam(pPlayer1.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
			for iCity in range(pPlayer1.getNumCities()):
				ppCity = pPlayer1.getCity(iCity)
				if ppCity.getNumActiveBuilding(bSphinx) == true:
					if (iBuilding in aiWonderList):
						return 85	# 85% of normal cost
		return -1

		return iCostMod

I tried to follow the instructions on the BUG Wiki, "Core GameUtils", and then I tried to go through your walkthrough, but I don't know where I've messed up...
Thanks... :blush:
 
Yes, you can safely put Fuyu's work into BAT 2.1.1a. Note, however, that you'll need to compile the DLL with the extra options turned on (Sentry Actions especially) or it won't start. I don't recall offhand if Fuyu has any of those turned on.
 
I haven't tested this yet, just try installing BAT and copying my stuff over that install. In theory&#8482; that should do it. I think.

(Sentry Actions, Frac Trade and GovWorkers are on.)
 
Thanks EF. I was so sure I'd done GameUtils wrong that I never even looked at the logs.


To me that means I've probably done something wrong in the XML, and my module isn't being seen for BUG to load it. Should I have two XML's, one for the EventManager mod and one for GameUtils mod?
 
You don't need to split up your XML files, but you do need to add

Code:
<load mod="RichMod"/>

to BUG's init.xml. Make sure to omit the ".xml" file type suffix in the <load> element.
 
Make sure BUG's File Logging Level is set to Debug (see the Logging page for instructions) and start up a game (load or save). Then post PythonDbg.log.
 
Yup, I keep BUG on Debug logging. Never know when I might need it. Tried another game, double-checked everything. Both functions added through the RichMod EventManager work fine, but the GameUtils change fails. I don't get any odd behaviour or errors, the wonder just has no effect.

Here's the log: View attachment PythonDbg.log.txt

And I think this is the part in it you're looking for:
01:40:22 DEBUG: BugConfig - loading mod file RichMod
01:40:22 DEBUG: BugInit - loading mod RichMod...
01:40:22 INFO : BugCore - creating uninitialized mod RichMod
01:40:22 DEBUG: BUG: looking up CvRichModEventManager.CvRichModEventManager
load_module CvRichModEventManager

01:40:22 DEBUG: BUG: looking up RichModGameUtils.RichModGameUtils
load_module RichModGameUtils

01:40:22 DEBUG: BugGameUtils - registering RichModGameUtils.RichModGameUtils
01:40:22 DEBUG: BugGameUtils - getBuildingCostMod - adding RichModGameUtils handler
01:40:22 DEBUG: Timer - load mod [RichMod] took 41 ms
Thanks!
 
Okay, well it's definitely being hooked up by BUG:

Code:
BugGameUtils - getBuildingCostMod - adding RichModGameUtils handler

Did you enable it in the PythonCallbacks.xml file? You must do this for each callback that you use that has an entry in that file. Some are on by default and cannot be turned off.
 
I added a note to the tutorial about the PythonCallbackDefines.xml file. It was just unfortunate that I picked a callback that isn't in that file as an example.
 
While we're on the subject of tutorials, merging, and avoiding medication...

I'm having a problem getting my movie mod to work using the BUG method. I followed the tutorial, and wound up with XML:
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- Movie Mod - Plays new movies for religion and national wonders  Author: Lemon Merchant -->
<mod id="MovieMod" module="MovieMod">
    <event type="BuildingBuilt" function="onBuildingBuilt"/>
</mod>
And the following Python:
Code:
# MovieMod -- Play religion and Nat Wonder movies - Author: Lemon Merchant/Phungus420/Firaxis

from CvPythonExtensions import *

gc = CyGlobalContext()



def onBuildingBuilt(argsList): # Took out arg 'self'
        'Building Completed'
        pCity, iBuildingType = argsList
        game = gc.getGame()
        # Begin Phungus code
        bCoolBuilding = False
        if ( (gc.getBuildingInfo(iBuildingType).getMovie()) or (isWorldWonderClass(gc.getBuildingInfo(iBuildingType).getBuildingClassType())) ):
            bCoolBuilding = True
        if ( (not gc.getGame().isNetworkMultiPlayer()) and (pCity.getOwner() == gc.getGame().getActivePlayer()) and bCoolBuilding ):
        # End Phungus code
            # If this is a wonder...
            popupInfo = CyPopupInfo()
            popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
            popupInfo.setData1(iBuildingType)
            popupInfo.setData2(pCity.getID())
            popupInfo.setData3(0)
            popupInfo.setText(u"showWonderMovie")
            popupInfo.addPopup(pCity.getOwner())
            

        CvAdvisorUtils.buildingBuiltFeats(pCity, iBuildingType)

        if (not self.__LOG_BUILDING):
            return
        
        CvUtil.pyPrint('%s was finished by Player %d Civilization %s' 
            %(PyInfo.BuildingInfo(iBuildingType).getDescription(), pCity.getOwner(), gc.getPlayer(pCity.getOwner()).getCivilizationDescription(0)))

I am now confused. If I plunk the "Phungus" commented section into CvEventManager.py, the events fire every time, and the movies play. If I do it with the BUG method, only the religion movies play like normal. The mod is being initialized and the Python routine is being loaded. I checked the debug logs, and everything seems to be right, but the event will not trigger when a "Cool" building is built.

I'm obviously missing something important, but I can't see what (except for maybe some imports...)

A little guidance S.V.P? :D

Edit: I should mention that all of the other, necessary XML for the buildings and art defines is working correctly.
 
The only thing that jumps out at me is that you have the "if ... :" commented out, but you haven't outdented the code below it. Python is anal about indentation--it uses it instead of C++'s { and } to denote blocks. I would bet that you're getting an IndentationError in Logs/PythonErr.log (where your CustomAssets folder is). If that file isn't empty but isn't this problem, post it and we can go from there.
 
Top Bottom