help with changes from 3.5 to 3.6

Joined
Jul 5, 2004
Messages
23,562
Location
Canberra, Australia
Something has changed (duh!) between versions 3.5 and 3.6 which is causing me some headaches. I could not find a deffinative list of changes and given my newbe status with python I am not sure I would recognise the appropriate change if I fell over it.

I merged the Abandon city mod into Rise of Mankind 2.5 which uses BUG 3.5 - every thing worked well. I changed to shortcut to Cntl-A, and pop up appears in the city screen asking which building I want to remove or if I want to raise the city.

In Rise of Mankind 2.6, which uses BUG 3.6 the Cntl-A only works in the city screen, as expected, but the pop up only appears after you exit the city screen and naturally enough it is empty because I am no longer in the city screen.

My question - has anything changed in BUG that may be delaying the "call" to the event?

For clarity here is my CvEventmanager.py in the Assets\Python directory. It has Abandon City before and after each bit that is changed.
 
I can't think of anything in BUG 3.6 that would interfere with this code. Can you post its XML config file?
 
Yes, that's what I meant. I don't see where you are initializing this event manager. How are you hooking it up to BugEventManager?
 
Yes, that's what I meant. I don't see where you are initializing this event manager. How are you hooking it up to BugEventManager?

Ah well, you are well beyond my python knowledge here. I was assuming that the hook to BugEventManager was done via the import stuff at the start of the code. As I said I am learning python by doing this simple merge. The code I am merging into was done by Zappara for RoM and BUG works in it. I have attached the original RoM 2.6 python directory with its code.
 
Um, I don't really want to read all those Python and config files. Can you tell me which files you added and modified for the Abandon City mod?
 
Ahh, you're using that in place of the built-in CvEventManager? That's a no-no, or at least not how BUG is intended to work. Instead, you need to look at the docs for event handling in the Modders' Corner.

This part is a little tricky, but there are a lot of examples in BUG. ReminderEventManager seems the most similar to this mod since it has a popup event to ask the user to enter the reminder.

Feel free to ask questions about the docs or what to do once you give it a try. I'm happy to help you learn to do it, and it will help me improve the documentation for others.
 
Thanks, I have a look at the doc etc.

I have noticed a silly error - I had to change the event id (ABANDON_CITY_DEMOLISH_BUILDING_EVENT) to 7599 from 7900 to get something happening. But I did not notice that on line 1646 the originator of the code had used the number 7500 rather than string. Yes I now know that I should have used ABANDON_CITY_DEMOLISH_BUILDING_EVENT = CvUtil.getNewEventID(<mod-id>.<event-name>) - seems I had just found the docs using google to figure out what the first parameter of PyPopup was.
 
I am getting there. It would help if the example in the documentation matched the released code so I could get the big picture.

For example the doco says put the events or event manager module name in the xml but in Reminder.xml ReminderEventManager has no events in it ie <events/> and yet it has events in the code.

In the example headed "and in ReminderEventManager.py" the doco has the eventManager.addEventHandler lines on ReminderEventManager but in the code they are actually on ReminderEvent.

In the Popup Events section the example is about eventManager.setPopupHandler which is never used in the code although there is something that looks similar in additions to self.events in the ReminderEventManager __init__

Now I need to have one last look at my code, bite the bullet, and try running it.
 
I have noticed a silly error - I had to change the event id (ABANDON_CITY_DEMOLISH_BUILDING_EVENT) to 7599 from 7900 to get something happening. . . .

AFAIK, the actual number you use (as long as it's unique) shouldn't matter. Are you saying 7599 didn't work at all, or only because it didn't match a number used somewhere else? I hope the latter (just a typo).

As you saw, this is why I created CvUtil.getNewEventID(). It removes the need to fiddle around with the numbers yourself. I just want to make sure there won't be problems with certain ranges of numbers.

I am getting there. It would help if the example in the documentation matched the released code so I could get the big picture.

This is always a problem with technical documentation. I write the docs to match the code, but then I change the code later and don't catch all the docs. Thanks for your help here![/quote]

For example the doco says put the events or event manager module name in the xml but in Reminder.xml ReminderEventManager has no events in it ie <events/> and yet it has events in the code.

I added a new feature recently that allows you to specify a module in the <mod> tag. It will be used for any other tags that require a module attribute if none is given there. It is mentioned as the second sentence on the XML Reference page.

I will create some bare-bones working examples that will be easier to follow than the ones in BUG some time this weekend.

In the example headed "and in ReminderEventManager.py" . . . .

Fixed. This is exactly why we need some simple examples. Reminder Mod has no reason to have two separate classes for the event manager--that's just how I found it, and I've modified it as little as possible to make it work in BUG. But that makes it a poor example because it does things you don't need to do.

The other thing I struggle with is that I need examples that will make porting/merging mods easier. The way most mods are built is more work than is necessary. For one thing, no class is needed at all. So I'll create some "easiest way to do this" example as well. :)

In the Popup Events section the example is about eventManager.setPopupHandler which is never used in the code although there is something that looks similar in additions to self.events in the ReminderEventManager __init__

Yes, setPopupHandler is used internally by BUG and CvEventManager. You can use it yourself, but all the mods I merged with BUG were using the method you see in Reminder Mod, i.e. adding to self.Events directly. I'll make sure to use the function in the new example.

Thanks again for pointing these out; it helps a lot! :goodjob:
 
I have a newbe error and as with most error messages it makes no sense to me. At least this time I am getting stuff in the logs.

In the PtthonErr2.log I get
Code:
    CyInterface().getHeadSelectedCity().setNumRealBuilding(iBuildingType, False)                 
                                                                                                ^
IndentationError: unindent does not match any outer indentation level

I went back to basics and tried to merge the original Abandon City Demolish Building mod into the Rise of Mankind mod. This means I have 4 files
- the code in Python\AbandonCityEventManager.py,
- a text file xml\text\Abandon_City_CIV4GameText.xml that I am not yet using,
- Config\init.xml changed to also load this mod - the biggest of all the files here :)
- Config\Abandon City Mod.xml to define this mod
all these are in assets.7z below.

As to the documentation I have been reading http://apps.sourceforge.net/mediawiki/civ4bug/index.php?title=Core_Configuration and at first it makes perfect sense but when I went to look at the Python Configuration stuff in RoM I had no idea where to look nor what to look for. I think part of the problem is the way the word "modules" is used. Sometimes it means a bunch of files in a directory in the Mods directory, and sometimes a Python module which I think means a file of python code. Eventually I figured out these were file names in the Python/ directory. You are probably using language that any experienced python programmer would know and understand.

The Python Configuration intro mentions CvPathOverride but does not document it. It does not mention CvAltRoot and does document it.
 
IndentationError: unindent does not match any outer indentation level

This means that you have a mismatch in your indentation--the whitespace at the front of each line. Make sure you are using tabs exclusively when indenting lines. This particular form of the error (unindent) means that the level of indentation of a line following an indented line didn't match any previous lines.

In this example, line (3) doesn't match lines (1) or (2), so Python can't figure out where it goes.

Code:
# zero-level indentation (sometimes call file-level), i.e. no tabs in front
NUM_PLAYERS = 12    # (1)
...
def giveGold(ePlayer, iAmount):
    # one level of indentation means this line is part of the giveGold() function
    if ePlayer < 0 or ePlayer >= NUM_PLAYERS:    # (2)
        # two levels of indentation, means this line is part of the if test
        return
  gc.getPlayer(ePlayer).changeGold(iAmount)    # (3)

Lines (3) has two spaces in front, but no line before it has that amount. Python was expecting 0 spaces or 4 spaces. Again, use tabs to save you sanity since that's what all the built-in and BUG files use.

However! If you are editing a file that uses spaces for indentation, use spaces. Never mix tabs and spaces or you will age very rapidly.​

I think part of the problem is the way the word "modules" is used.

Yes, a Python module is a single .py file. The problem is that the gaming community uses the term "mod" to mean some set of new/changed features that apply to an existing game. In Civ, sometimes a mod may consist of a single Python module.

I don't think I can change that vocabulary, so in the BUG Core documentation, I strive to use module to mean a Python module and mod to mean your actual mod/modcomp. In the XML files there is the <mod> entity which contains the configuration for your mod, and there are module attributes which refer to Python modules (files).

Please point out any places where I have mixed up the two as I know it can be very confusing, and it won't help if I use the wrong term somewhere. ;)

I added a note about this to the Overview page.

The Python Configuration intro mentions CvPathOverride but does not document it. It does not mention CvAltRoot and does document it.

I renamed CvPathOverride.py to CvAltRoot.py to match the Civ4 /AltRoot command-line option. I have fixed the place you mentioned.
 
This means that you have a mismatch in your indentation--the whitespace at the front of each line. Make sure you are using tabs exclusively when indenting lines. This particular form of the error (unindent) means that the level of indentation of a line following an indented line didn't match any previous lines.

....

However! If you are editing a file that uses spaces for indentation, use spaces. Never mix tabs and spaces or you will age very rapidly.​

The original code did mix tabs and spaces. I thought I had caught all of them but had missed two lines. Unfortunately fixing them has not fixed the problem.

Please point out any places where I have mixed up the two as I know it can be very confusing, and it won't help if I use the wrong term somewhere. ;)

I added a note about this to the Overview page.

I think my problem was actually that on http://apps.sourceforge.net/mediawiki/civ4bug/index.php?title=Core_Configuration you are specific about where the XML goes but don't mention where the Python goes.

I added a new feature recently that allows you to specify a module in the <mod> tag. It will be used for any other tags that require a module attribute if none is given there. It is mentioned as the second sentence on the XML Reference page.

The problem here is that I only read the bit about the <events> tag since this is what I needed to modify and understand at the time :). Don't know how you can fix doco where the people only look at the bit they need to understand and not the whole document they were linked to. Maybe you need to be tedious and say what the default is eg "<events/> defaults to the mod name specified in the <mod> tag."
 
Oops, how embarrassing, I had forgotten to get rid of the old attempt which was in another code file. The code now does not cause any Python errors, but it is still not working. It is not even being activated --- wait I have just had a thought!

Mo it just does not work - it does not recognise or act on the Ctrl-A key which is supposed to start the whole thing.
 
I am getting there. I am at least getting the trace prints out even if the code is not working properly.

It turns out that I did not read the documentation on the <load> tag. Since the parameter was mod= I put the mod name "AbandonCity" as per the definitional "Abandon City Mod.xml". Rather than "Abandon City Mod". So in this case the error was mine for not reading the fine manual and assuming that this "mod" was the same as other references to "mod".

In fact there were a couple of things concerning this xml file I had gotten wrong, just because I assumed rather than read the manual.

I am writing a brief document on what I needed to do to get the mod working with BUG without all the stuff about getting the mod working. I'll give you a copy when it is ready. It will be a "how to" rather than the more technical doco which is there at the moment.
 
OK, now I am completely stumped. I am getting an xml endtag not closed error and I can't see anything wrong with my xml. I changed two things to fix the last python error I was getting. I changed the name of the start event in my mod and in the shortcut part of the config xml for my mod and I changed from hard coding the popup screen text to using a text xml file so I could support the different languages in the future, currently each language use the English text.

I am playing BUG Mod 3.6 the stand alone mod so I know nothing else should be interferring.

Interestingly before I changed the name of the start event I and had python errors I was getting my trace prints in game and the module was being loaded according to the logs. Now it is not being loaded.

I need someone to look at this and tell me where I am going wrong in the link to BUG. Code and Python logs are attached. Note I tried both <shortcut key="Ctrl A" function="StartAbandonCity"/> and <shortcut key="Ctrl A" function="onStartAbandonCity"/>. I had previously called this event "onKbdEcvent" since that is what it was in the original Abandon City Demolish Building mod but since the keyboard stuff is now being handled by BUG felt the name was wrong.

Thanks
 
The <shortcut> entity is designed to call a module-level function--not one in a class. You can, however, get it to work like this:

Code:
#AbandnCityOpt = BugCore.game.AbandonCity
[B]g_modEventManager = None[/B]
g_eventMgr = None
g_autolog = None

[B]def onStartAbandonCity():
	g_modEventManager.onStartAbandonCity()[/B]

class AbandonCityEventManager:
	def __init__(self, eventManager):
		eventManager.addEventHandler("StartAbandonCity", self.onStartAbandonCity)

		[B]global g_modEventManager
		g_modEventManager = self[/B]

		global g_autolog
		g_autolog = autolog.autologInstance()

The <events> entity will create an instance of the AbandonCityEventManager class. It's __init__() function will assign that instance to g_modEventManager so that the module-level function onStartAbandonCity() can access it.

As for the XML problem, it starts with this:

Code:
08:05:00 TRACE: BugConfig - failure parsing Mods\BUG Mod 3.6\Assets\Config\init.xml at line 129
08:05:00   No such module 'SettlersEventManager'

Do you have the SettlersEventManager and CvEnhancedTechConquestEventManager from RoM in your mod? They are being loaded from init.xml as per the error message. I believe the unopened end tag is the </events> tag on the following line which is due to the missing module. Fix that and the tag should be okay.
 
The xml problem was me copying my modified RoM init.xml into BUG rather than my modified BUG init.xml. With that fixed and your code suggestions in place I now get an error saying that onStartAbandonCity does not accept parameters but one is being passed. I guessed argsList and I now have the short cut key showing my trace prints. Now I better look at those logs.

start vent - It is the amount of guess work involved in building mods that I find fustrating. The python manuals don't help much because we use Civ extensions to python which have no documentation. On top of that we have BUG which is wonderful but at times seems like some arcaine magic. Mind you before I retired I was writing generic software which others also compared to the old flowchart box "and magic happens here" :) - end vent
 
Back
Top Bottom