Python Performance and Interface Overhaul (PPIO)

Using PPIO returns me this error once clicking the link.
Code:
Traceback (most recent call last):
  File "CvScreensInterface", line 251, in linkToPedia
  File "Pedia", line 1275, in link
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
ERR: Python function linkToPedia failed, module CvScreensInterface

Without PPIO the link doesn't seem to work. Will have to see why is that.
 
Last edited:
The thing is that supposedly .getType should get what's defined in <Type> (e.g. BONUS_BARK), but it doesn't do this as it only outputs a single letter. The game then tries to link it to said letter and it can't find anything with that, of course.

Type.png
 
Last edited:
The thing is that supposedly .getType should get what's defined in <Type> (e.g. BONUS_BARK), but it doesn't do this as it only outputs a single letter. The game then tries to link it to said letter and it can't find anything with that, of course.

View attachment 513383
Hmm, looks like a text formatting issue.
Here is the string that the pedia python code receives: "\u4f42\u554e\u5f53\u4142\u4b52" for the link. The first one (\u4f42) is a kanji sign from Japanese/Chinese. ^^

Did you make the appropriate change to the xml entry for "TXT_KEY_BUILDING_PROVIDES"?

<English>[ICON_BULLET]Provides %d1_Num [COLOR_HIGHLIGHT_TEXT][LINK=literal]%s2_BonusName[\LINK][COLOR_REVERT] (%F3_BonusIcon)</English>

"[LINK=literal]" need to be changed to "[LINK=%s2_TYPE_KEY]" followed by "%s3_BonusName[\LINK][COLOR_REVERT] (%F4_BonusIcon)"

Edit: {
It may be that you will have to add .GetCString()

GC.getBonusInfo((BonusTypes) kBuilding.getFreeBonus()).getType().GetCString()

I'm not familiar with what getType() returns internally in the dll, I only know what the dll returns to python when python calls getType().
I'm not familiar with what GetCString() returns and why/what or when it's needed either.

Fix up the xml first, then consider if GetCString() or something else is needed.
This is how links that use the TYPE_KEY looks like in text xml: [LINK=LEADER_CYRUS]Cyrus[\LINK] (copied from TXT_KEY_BUILDING_JEWISH_SHRINE_PEDIA). This is what we are trying to replicate.
}
 
Last edited:
@Toffer90 that worked. :)

Ended up using this code:
Code:
CvWString(GC.getBonusInfo((BonusTypes)kBuilding.getFreeBonus()).getType()).GetCString()

EDIT: By the way, do I do the same (replace LINK=literal) for every tag in game?
 
Last edited:
I found a somewhat annoying issue that could have to do with PPIO or not.

When you want to change specialists inside the city view you first click on the arrow down of e.g. Engineer, that reduces the Engineers by one and creates one Citizen. If you now click the arrow up of e.g. Priest then the one Citizen remains, instead one worker from the map is taken away. When you now click on the map where the worker has been taken away he returns and the Citizen's numbers are back to zero - this is what I wanted from the start but why is this extra step needed? This only happens with smaller cities where not every tile on the fat cross is worked on.
My wish is that if I want to add to specialists and if there are "Citizen" specialists available then those should be reduced and not the workers from the map (btw, this works alright with any numbers of Citizens of 2 and higher but not with the last one).
 
I found a somewhat annoying issue that could have to do with PPIO or not.

When you want to change specialists inside the city view you first click on the arrow down of e.g. Engineer, that reduces the Engineers by one and creates one Citizen. If you now click the arrow up of e.g. Priest then the one Citizen remains, instead one worker from the map is taken away. When you now click on the map where the worker has been taken away he returns and the Citizen's numbers are back to zero - this is what I wanted from the start but why is this extra step needed? This only happens with smaller cities where not every tile on the fat cross is worked on.
My wish is that if I want to add to specialists and if there are "Citizen" specialists available then those should be reduced and not the workers from the map (btw, this works alright with any numbers of Citizens of 2 and higher but not with the last one).
I think that's some code stuff that isn't related to the PPIO. It's very tricky to make it behave properly and still get a decent AI out of it because the whole thing tries too hard to be predictive for the sake of the same functions tying into the way the AI makes its selections. This would be very difficult to repair and it freaks me out to be honest because there's so much capacity here for introducing really bad bugs. I might try again to resolve this and improve the functioning at some point - isolating this out for when human players are making selections to entirely different functions would probably be a good place to start.
 
I tried your modmod and i#m still pleased.
One thing i want to ask: you removed idle from the building queue.
Is it possible to reinstall it?
 
Idle is only removed when other processes are available.
Is there any reason to do idle instead of the other processes?
I use building queues and or add multiple buildings to the buildlist.
Once the queue is empty i found myself in the city and have to press enter to continue.
With idle possible it is always the last item in the queue and thus i enter the city at the moment i want to and not
just because there is nothing to build.
This may sound strange but if the addition of idle as selectable build is not to much work i'd like to have it back.
 
PPIO v0.5.9.8.8

Tech splash screen BUG settings aren't being saved between sessions. That is, if you restart you game+save you get the original, not the detailed screen.

Noticed this in my game and in @IdioticUlt1mara stream.
 
PPIO v0.5.9.8.9
SVN rev.10368
  • Made the Idle process always visible as a viable option in all cities.
  • Fixed an issue with initializing the correct tech splash screen as set in BUG options.
    • It was done so early in the game initialization process that the code that reads the ini files was not ready and thus BS data was used to determine which screen to use resulting in the minimalistic vanilla splash screen.
  • Removed the vanilla tech splash screen from the BUG options, who would ever want to actually use that stamp of a screen.
    • Since there was only two options left I changed it from a dropdown to a checkbox.
  • Optimized some code, stripped away a lot of useless code.
 
I have a small project for a dll modder who wants something extra to do.

In my last update I optimized the python code that calculates player scores, only to realize that the call to python has been commented out in the dll and the calculation is done there instead.
The commenting stated that python was too time consuming and that I can believe as it was poorly written. I'm now quite curious how the performance comparison is between my PPIO optimized version of the code and the dll code for it.
Spoiler Relevant Dll code :
Code:
int CvPlayer::calculateScore(bool bFinal, bool bVictory) const
{
    PROFILE_FUNC();

    if (!isAlive())
    {
        return 0;
    }

    if (GET_TEAM(getTeam()).getNumMembers() == 0)
    {
        return 0;
    }
/************************************************************************************************/
/* Afforess                      Start         06/25/10                                               */
/*                                                                                              */
/* Calculating the Score from python is time consuming                                          */
/************************************************************************************************/
/*
    long lScore = 0;

    CyArgsList argsList;
    argsList.add((int) getID());
    argsList.add(bFinal);
    argsList.add(bVictory);
    PYTHON_CALL_FUNCTION(__FUNCTION__, PYGameModule, "calculateScore", argsList.makeFunctionArgs(), &lScore);

    return ((int)lScore);
*/
    int iPopulationScore = getScoreComponent(getPopScore(), GC.getGameINLINE().getInitPopulation(), GC.getGameINLINE().getMaxPopulation(), GC.getSCORE_POPULATION_FACTOR(), true, bFinal, bVictory);
 
    int iLandScore = getScoreComponent(getLandScore(), GC.getGameINLINE().getInitLand(), GC.getGameINLINE().getMaxLand(), GC.getSCORE_LAND_FACTOR(), true, bFinal, bVictory);
 
    int iTechScore = getScoreComponent(getTechScore(), GC.getGameINLINE().getInitTech(), GC.getGameINLINE().getMaxTech(), GC.getSCORE_TECH_FACTOR(), true, bFinal, bVictory);
 
    int iWondersScore = getScoreComponent(getWondersScore(), GC.getGameINLINE().getInitWonders(), GC.getGameINLINE().getMaxWonders(), GC.getSCORE_WONDER_FACTOR(), false, bFinal, bVictory);
 
    return iPopulationScore + iLandScore + iTechScore + iWondersScore;

What I want you to do is to un-comment the python call and run a timer on it and the following code.
Spoiler Something like this :
Code:
    Start timer // I wouldn't know how a timer may look like in c++ code, that's why I need you.

    long lScore = 0;

    CyArgsList argsList;
    argsList.add((int) getID());
    argsList.add(bFinal);
    argsList.add(bVictory);
    PYTHON_CALL_FUNCTION(__FUNCTION__, PYGameModule, "calculateScore", argsList.makeFunctionArgs(), &lScore);

    End Timer and log result.

    Start new timer

    int iPopulationScore = getScoreComponent(getPopScore(), GC.getGameINLINE().getInitPopulation(), GC.getGameINLINE().getMaxPopulation(), GC.getSCORE_POPULATION_FACTOR(), true, bFinal, bVictory);
 
    int iLandScore = getScoreComponent(getLandScore(), GC.getGameINLINE().getInitLand(), GC.getGameINLINE().getMaxLand(), GC.getSCORE_LAND_FACTOR(), true, bFinal, bVictory);
 
    int iTechScore = getScoreComponent(getTechScore(), GC.getGameINLINE().getInitTech(), GC.getGameINLINE().getMaxTech(), GC.getSCORE_TECH_FACTOR(), true, bFinal, bVictory);
 
    int iWondersScore = getScoreComponent(getWondersScore(), GC.getGameINLINE().getInitWonders(), GC.getGameINLINE().getMaxWonders(), GC.getSCORE_WONDER_FACTOR(), false, bFinal, bVictory);

    iPopulationScore + iLandScore + iTechScore + iWondersScore; // return this to void to include the return statement in the timer even though it wouldn't take any time at all really.

    End Timer and log result.
 
    return iPopulationScore + iLandScore + iTechScore + iWondersScore;
So anyone up for this, I would first want you to test it without PPIO, then with PPIO, even if I didn't manage to make python faster than the dll here I would still like to know by how much. ^^

If PPIO didn't outperform the dll in this case then the commented part can be deleted all together (same with the python code I optimized too) as it's close to impossible to make python code perform better at this than what I made it in PPIO.
If PPIO did outperform the dll then I would want to get the PPIO code for it in the SVN and the dll code would then only have the python call.
 
Last edited:
Back
Top Bottom