Advanced Civ

hey,

there is a python err when cchanging options in the splashtech screen ,
looks like missing vars.

def deleteTechSplash(option=None, value=None): # called when parsing TechWindow.xml
import CvScreensInterface
CvScreensInterface.deleteTechSplash(option,value)
 
And this is not just something that happens when editing Python code at runtime? How can I reproduce the error? Switching between the three BUG settings for the Tech Splash screen doesn't seem to do it.
 
odd,
though i changed python,
i traced it and compared to advc.

ill try more
spllash.png


i did this which seems to be ok now:
def deleteTechSplash(option=None, value=None): # called when parsing TechWindow.xml
import CvScreensInterface
CvScreensInterface.deleteTechSplash(option, value)
 
Last edited:
Oh, I'm sorry, you're right – and I agree that this is a good way to fix it. I didn't have exception popups enabled; and then there is no sign of any problem.
 
hi hi
well, i still think there is some issue with python and your details button:
got an assert when clicking on it.
here are the debug call stack. maybe youll see something,
 

Attachments

  • yourdetails_5.png
    yourdetails_5.png
    240.2 KB · Views: 19
  • yourdetails_4.png
    yourdetails_4.png
    203.5 KB · Views: 14
  • yourdetails_3.png
    yourdetails_3.png
    200.3 KB · Views: 12
  • yourdetails_2.png
    yourdetails_2.png
    189.2 KB · Views: 13
  • yourdetails_1.png
    yourdetails_1.png
    153.1 KB · Views: 11
I don't think this button (or Alt+D) should result in a BUTTONPOPUP_PYTHON_SCREEN. I'm getting BUTTONPOPUP_DETAILS, which is one enumerator above BUTTONPOPUP_PYTHON_SCREEN. Seems to be up to showDetails in the EXE which popup type gets launched. I'm guessing that 21 is hardcoded there. Do you have BUTTONPOPUP_DETAILS defined as 21 in CvEnums.h?
 
ok i did some deep dive,
first sorry to again come with a none advciv issue,

i found that the dll (did a search with agent ranseck), which did not contain the addition i did to the enum:


Spoiler :

BUTTONPOPUP_TEXT,
BUTTONPOPUP_MAIN_MENU,
BUTTONPOPUP_CONFIRM_MENU,
BUTTONPOPUP_DECLAREWARMOVE,
BUTTONPOPUP_CONFIRMCOMMAND,
BUTTONPOPUP_LOADUNIT,
BUTTONPOPUP_LEADUNIT,
BUTTONPOPUP_DOESPIONAGE,
BUTTONPOPUP_DOESPIONAGE_TARGET,
BUTTONPOPUP_CHOOSETECH,
BUTTONPOPUP_RAZECITY,
BUTTONPOPUP_DISBANDCITY,
BUTTONPOPUP_CHOOSEPRODUCTION,
BUTTONPOPUP_CHANGECIVIC,
//doto 115 goverment screen
BUTTONPOPUP_CHANGEGOVERMENT,
BUTTONPOPUP_CHANGERELIGION,
BUTTONPOPUP_CHOOSEELECTION,
BUTTONPOPUP_DIPLOVOTE,
BUTTONPOPUP_ALARM,
BUTTONPOPUP_DEAL_CANCELED,
BUTTONPOPUP_PYTHON,
BUTTONPOPUP_PYTHON_SCREEN,
BUTTONPOPUP_DETAILS,
BUTTONPOPUP_ADMIN,
BUTTONPOPUP_ADMIN_PASSWORD,
BUTTONPOPUP_EXTENDED_GAME,
BUTTONPOPUP_DIPLOMACY,
BUTTONPOPUP_ADDBUDDY,
BUTTONPOPUP_FORCED_DISCONNECT,
BUTTONPOPUP_PITBOSS_DISCONNECT,
BUTTONPOPUP_KICKED,
BUTTONPOPUP_VASSAL_DEMAND_TRIBUTE,
BUTTONPOPUP_VASSAL_GRANT_TRIBUTE,
BUTTONPOPUP_EVENT,
BUTTONPOPUP_FREE_COLONY,
BUTTONPOPUP_LAUNCH,
BUTTONPOPUP_FOUND_RELIGION,
// <advc.706>
BUTTONPOPUP_RF_CHOOSECIV,
BUTTONPOPUP_RF_DEFEAT,
BUTTONPOPUP_RF_RETIRE, // </advc.706>


maybe its hard coded in the exe or that the
OnOkClicked
is in the exe and gets the index position from the hard coded list in that case.

so , i guess i need to move BUTTONPOPUP_CHANGEGOVERMENT, to the bottom.

WDYT?

i see you did not define these:

BUTTONPOPUP_RF_CHOOSECIV,
BUTTONPOPUP_RF_DEFEAT,
BUTTONPOPUP_RF_RETIRE, // </advc.706>

in the cyenuminterface,
should i do the same for my added?

and yes, i miss spelled :)

--
ok i moved it to the bottom, worked :)
 
Last edited:
Yes, one should probably only append to the end of the ButtonPopupTypes enum to be on the safe side. I'll add comments about that and also explicitly set BUTTONPOPUP_DETAILS = 21 and BUTTONPOPUP_ADMIN = 22. (I think that one also gets used by the EXE.) I think there's no harm in not exposing (all) new enumerators to Python. If you expose BUTTONPOPUP_CHANGEGOVERMENT to Python after my gap (left by not exposing the RF_... enumerators), your enumerator in Python will still correspond to the position (and int value) in CvEnums.h, and that value shouldn't change even if I later decide to expose my enumerators after all.
 
I don't know what exactly
C++:
python::enum_<ButtonPopupTypes>("ButtonPopupTypes").value("BUTTONPOPUP_TEXT", BUTTONPOPUP_TEXT)
does (CyEnumsInterface.cpp). Apparently the callee gets returned, which allows the next call to be chained afterwards (.value("BUTTONPOPUP_MAIN_MENU", BUTTONPOPUP_MAIN_MENU)), but that's just a pattern for compactness. I think Python does distinguish between enum types from C++ and integers in some contexts. But, probably, for the most part, one could just use e.g. 0 instead of ButtonPopupTypes.BUTTONPOPUP_TEXT in Python. Or 21 instead of ButtonPopupTypes.BUTTONPOPUP_DETAILS. That seems like a pretty bad idea because it'll break if the enum is reordered in C++. (Although this particular enum apparently shouldn't ever be reordered because that'll break the EXE.) So I do think that enums should be properly exposed to Python if they're going to be used there. But I don't generally expose stuff that I won't use. Or do you just mean that the ButtonPopupTypes enum is already exposed? Yes, but I don't think that means that all enumerators that a mod adds to this enum ought to be exposed as well. Having just some enumerators exposed should work fine.
 
hey,
saw your commits, nice work.
--
new issue,
when autoplay till end game (started the game in modern era,
tiny , 1 ai.
when domination is won by my autoplayed civ,
after one more turn question,
clicking exit to main menu, bit manual access to the option from the menu and both from the one more turn question,
crashes the game. i reproduced it:

wincrash.png
 
Autoplay with just one player into Dom victory, then the whole vicotry/ HoF sequence and return to menu (also also One More Turn) – didn't get any crash when I just tried it. So you get this each time you load one of the autosaves and run AI Auto Play again into victory? I didn't check in the debugger just now, but shouldn't CvEventReporter::victory get called long before the One More Turn popup?
Spoiler CvGame::setWinner :
C++:
void CvGame::setWinner(TeamTypes eNewWinner, VictoryTypes eNewVictory)
{
	if (getWinner() == eNewWinner && getVictory() == eNewVictory)
		return;
	m_eWinner = eNewWinner;
	m_eVictory = eNewVictory;
	// advc.707: Handled by RiseFall::prepareForExtendedGame
	if (!isOption(GAMEOPTION_RISE_FALL))
	{	// AI_AUTO_PLAY_MOD, 07/09/08, jdog5000:
		CvEventReporter::getInstance().victory(eNewWinner, eNewVictory);
	}
 
still not clue of that above issue.

got an error i get sometimes, checked the python log:


CvAltRoot

import failed

load_module _winreg

load_module WidgetUtil

07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Config.xml at line 37
07:44:00 TRACE: unidentifiable C++ exception
load_module BugGameUtils

07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Config.xml at line 44
07:44:00 TRACE: unidentifiable C++ exception
07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Config.xml at line 44
07:44:00 TRACE: Error while looking up function or class 'GameUtilsHandler' in module 'BugGameUtils': 'module' object has no attribute 'GameUtilsHandler'
07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Config.xml at line 48
07:44:00 TRACE: 'NoneType' object has no attribute 'addText'
07:44:00 ERROR: BugInit - failed to parse module BUG Config
07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\init.xml at line 13
07:44:00 TRACE: 'NoneType' object has no attribute 'addText'
load_module BugUpdateChecker

07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Core.xml at line 49
07:44:00 TRACE: unidentifiable C++ exception
07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Core.xml at line 55
07:44:00 TRACE: Error while looking up function or class 'onLocalRootChanged' in module 'BugUpdateChecker': 'module' object has no attribute 'onLocalRootChanged'
07:44:00 TRACE: BugConfig - failure parsing E:\games\civ4\Beyond the Sword\Mods\DotoDev\Assets\Config\BUG Core.xml at line 64
07:44:00 TRACE: Error while looking up function or class 'onRepositoryUrlChanged' in module 'BugUpdateChecker': 'module' object has no attribute 'onRepositoryUrlChanged'

CvAltRoot - > i looked for it, couldnt find it.
 
Is CvEventReporter::victory even on your call stack as the crash happens? Not sure that's visible in the screenshot. For me, I've confirmed, that function gets called only directly upon victory.

CvAltRoot.py can be created for specifying some custom local path. It's normal that it doesn't exist, and I think the failed import (without uncaught exception) is normal. That's in my logs too. I get none of the other errors. "Failure parsing E:\...\BUG Config.xml at line 37" – what would there be to parse? In my version it's:
XML:
<config tag="widget" parents="mod" module="WidgetUtil" class="WidgetHandler"/>
But your log says that load_module WidgetUtil is already done. I don't suppose you've changed anything in BUG Config.xml; no reason to. Is the E:\... path in the log correct? At any rate, this being related to your crash after AI Auto Play seems like a long shot.
 
weird stuff are happening in my mod, crashes on random stuff.

i havent touched the config file.

--
i now cleaned my code , python xml and dll. removed plenty.
--

cleaned lots, mod loads instantly (once i told you mine takes some time. i think due to xml load changes).
i got this error, which i got before , randomly.
compress.png


-----
another one that i had for a long time:

int gpturn = GPTurnsLeft();
FAssert(GPTurnsLeft() > 0)
int const iTurnsLeft = GPTurnsLeft() < 0 ? 0 : GPTurnsLeft();

GPTurnsLeft() returns a -1,
when a civic that has produce military units with food.
start a game , switch to such a civic and it wil pop up.

-----
another:
1740090621446.png


when saving after domination win, clicking one more turn, and right then a save.
i didnt pass the turn after the one more turn button.
 
Last edited:
i got this error, which i got before , randomly.
That's apparently the initial autosave failing. The "randomly" part sounds challenging. A quick test showed that attempting to write a negative number of values (count < 0) to a data stream immediately causes a crash in the EXE (which only aborts the autosave; no crash to desktop and no breakpoint in the debugger) and shows the "Failed to compress game data" error popup. Can't really think of other ways to arrive there. So I expect that your code somewhere writes a container size incorrectly, which, with a Debug build, might always result in a size of 0 getting written, while, with non-Debug builds, it could usually write 0, sometimes positive numbers (which perhaps mean that the save can't be loaded), sometimes negative, resulting in a crash upon saving. Can you generally load the saves that get successfully created?

Scattering some log output in the write functions could narrow the problem down (the next time it occurs). Maybe a simpler attempt is worth a shot: I already have wrappers for the Write functions in FDataStreamBase.h. One can easily add assertions there to catch negative element counts. If the error doesn't occur with a Debug build, an Assert build will be good enough for this. This seems like a useful addition in any case as such errors are apparently difficult to debug. Actually, an upper limit also seems prudent – to make sure that we don't attempt to write hundreds of MB to disk. (Though that can also happen through loops that write one value at a time.) Git commit
GPTurnsLeft() returns a -1,
when a civic that has produce military units with food.
When a city has accumulated GP points, then there should be a GP bar on the city screen even if the city is not currently generating GPP. Hovering over that should cause CvCity::GPProjection to be called, and then GPTurnsLeft -1 indicates that the next GP is currently projected to take infinitely many turns. So far not an error. But are the calculated birth probabilities then accurate? The total pool of projected GP points is:
int iProjectedTotal = iTotalUnitProgress + iTurnsLeft * getGreatPeopleRate();
Then each GP type's share gets calculated through division by that. If iTotalUnitProgress is 1 and iTurnsLeft -1, that'll be a division by 0. A National Wonder could've provided exactly 1 point but then the rate would've stayed positive. But it could crash in a mod with specialists that generate only one GPP. Probably just a silent Python crash and a missing tooltip. Using 0 for an infinite turn count should be correct (and so -1 is also not far off, most of the time, but not correct) except for the case when iTotalUnitProgress is also 0 – but if there are neither accumulated GPP nor a positive GPP rate, then the progress bar shouldn't get shown at all. Still better to also handle this case explicitly. Git commit, might fix your issue.
when saving after domination win, clicking one more turn, and right then a save.
i didnt pass the turn after the one more turn button.
And what's on the call stack?
 
oh my seems i fell into a complicated issue.

what does the size means: "So I expect that your code somewhere writes a container size incorrectly"?
how can i check the source?

i can load saves yes, the whole thing is very random.
but happened for a long time.
now i have leaner code base though.

the gp, i added a check < 0 and made it to 0 a long time ago.
but its not a real solution, so i removed that and its back . i wanna get to the source.

ill follow up on your commits, thanks.
--
the victory, is there a chance its related to 1 of the 2 victory conditions i added ? (only xml).
cause when i auto played some games now with only the vanilla vic's, i still didnt see this exit / one more turn crash.


thanks

--
edit here fresh from a load try:
1740161201762.png


the repeated module that fails is this: "updateColoredPlots" , had it in all the times i debugged.

in :
void CvPythonCaller::call(char const* szFunctionName, long& lResult,
char const* szModuleName, bool bAssertSuccess, bool bCheckExists) const
{
if (bCheckExists && !m_python.moduleExists(szModuleName, true))
m_bLastCallSuccessful = false;
else
{
m_bLastCallSuccessful = m_python.callFunction(szModuleName, szFunctionName,
NULL, &lResult);
}
FAssert(!bAssertSuccess || m_bLastCallSuccessful);

calls:
def updateColoredPlots(self):
return False

so, i dont get it, its always false
going nuts here.
 
Last edited:
Back
Top Bottom