View Full Version : Dynamic Civilization Names


Dom Pedro II
Jun 06, 2007, 04:15 PM
I've started this thread to post all questions, comments and concerns regarding dynamic civ names as implemented in the Revolution mod.

I will try to collect here some comments made by people in the original Revolution thread to see what has been said, how it was addressed, and if it wasn't addressed due to the high posting rate and huge number of posts in that thread, get those issues and suggestions addressed.

Fosse
Jun 06, 2007, 04:58 PM
Having played for a while with the latest version I can say I love the Dynamic Names.

I wouldn't mind seeing the full names of the Civs on the scoreboard when you mouse over them. The only way to see the names right now without opening the diplomacy window is to hover over a tile that is owned by that civ that is within the fog of war (as otherwise you are told the % of the owning civ's culture).

Since the names only appear when mousing over their length shouldn't matter.

Does an entry appear in the replay at the end? "Elizabeth ascends the throne of the newly styled Royal Kingdom of England," and "The people elect Tokugawa as the first President of The Free States of Japan."

Having those events appear in the turn summary and event log would also be great.

BobTheTerrible
Jun 06, 2007, 06:17 PM
I like them a lot. It adds a really nice touch to the game.

jdog5000
Jun 07, 2007, 02:47 PM
Having played for a while with the latest version I can say I love the Dynamic Names.

I wouldn't mind seeing the full names of the Civs on the scoreboard when you mouse over them. The only way to see the names right now without opening the diplomacy window is to hover over a tile that is owned by that civ that is within the fog of war (as otherwise you are told the % of the owning civ's culture).

Since the names only appear when mousing over their length shouldn't matter.

Does an entry appear in the replay at the end? "Elizabeth ascends the throne of the newly styled Royal Kingdom of England," and "The people elect Tokugawa as the first President of The Free States of Japan."

Having those events appear in the turn summary and event log would also be great.

Glad you like them! I will cause the full names to show over the scoreboard, having to find empty land to see them is kind of annoying.

Currently there is no recording of the names for the replay, but it's a pretty good idea. I worry about overfilling the replay though ...

Aeven
Jun 24, 2007, 03:34 PM
I doubt it would overfill the replay. Also, when you hover over your flag in the UI, it would be nice to see your own name.

jdog5000
Jun 24, 2007, 05:27 PM
The hover over your flag is already done and will be in the next version :)

Dom Pedro II
Jun 24, 2007, 10:15 PM
The hover over your flag is already done and will be in the next version :)

Wait... what flag?

jdog5000
Jun 24, 2007, 10:29 PM
Your flag, down in the right corner next to the minimap. Also shows you your traits and such.

Mohatma
Mar 08, 2008, 11:59 AM
When it changes my civ name, I can't change it back and it changes it only one time, so when I'm on Representation, I'm still "Kindom of ___"

BobTheTerrible
Mar 08, 2008, 12:25 PM
Speaking of dynamic civ names, do you think you can have civilizations start as "The ___ Tribes" or "Tribes of ____" rather than "____ Empire" ?

jdog5000
Mar 09, 2008, 12:32 AM
When it changes my civ name, I can't change it back and it changes it only one time, so when I'm on Representation, I'm still "Kindom of ___"
I'll see what I can do to protect names you've chosen for your civ and allow you to rename your civ midstream too. As for my it's not updating, that's mysterious ... do you have a save you could post?

Speaking of dynamic civ names, do you think you can have civilizations start as "The ___ Tribes" or "Tribes of ____" rather than "____ Empire" ?

Yes, it's totally possible ... when should it switch from Tribes to Empire though? Without any added changes, the switch would happen when you made your first civics change. Other possibilities:
- Found first city (Tribes name wouldn't last long ...)
- Found second city
- Reach some total population
- Meet your first civ
- ???

TheLastOne36
Mar 09, 2008, 08:59 AM
I'll see what I can do to protect names you've chosen for your civ and allow you to rename your civ midstream too. As for my it's not updating, that's mysterious ... do you have a save you could post?


I've had similar problems to...


Yes, it's totally possible ... when should it switch from Tribes to Empire though? Without any added changes, the switch would happen when you made your first civics change. Other possibilities:
- Found first city (Tribes name wouldn't last long ...)
- Found second city
- Reach some total population
- Meet your first civ
- ???

How about when you research Writing?

Founding your second city is also a good one.

BobTheTerrible
Mar 11, 2008, 12:07 PM
Yes, it's totally possible ... when should it switch from Tribes to Empire though? Without any added changes, the switch would happen when you made your first civics change. Other possibilities:
- Found first city (Tribes name wouldn't last long ...)
- Found second city
- Reach some total population
- Meet your first civ
- ???

I was thinking that if you have the minor civs until writing option turned on, then "tribes" should last as long as the civ in question is a minor civ in the ancient era, although if you switch civics there's a good chance you become a kingdom (I'm thinking the civic switch signifies that you have a central government together), and if you have more than, say, 3 cities you become an empire.

Hephaistion
Jul 09, 2008, 06:21 PM
Hi all -- I'd just love it if you could post a how-to on how to add new names to the Dynamic Civ Names python file. For the next version of HephMod I've added a City States government civic, and would like to put this into the files so that civs adopting it be called, "(curAdj) League" or "League of (curShort)." I've monkeyed around in the code, but even when there are no Python exceptions, my additions don't work and render the naming portion of the mod (only) non-functional.

City States is registered as a CanDoElections civic and I gave it a democracy level of 3 so that I could tag it in DynamicCivNames.py. Here's what I did:

elif( RevUtils.isCanDoElections(iPlayer) ) :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - player can do elections")
if( pPlayer.getNumCities() == 1 ) :
if( ' Free ' in curDesc or ('Rep.' in curDesc and capital.getName() in curDesc) ) :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - keeping prior name")
newName = curDesc
elif( 40 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = curAdj + ' Free State'
else :
if( not cityString == None and len(cityString) < 10 and len(cityString) > 0) :
if( cityString in curAdj or cityString in curShort ) :
newName = 'Republic of ' + cityString
else :
newName = curAdj + ' Rep. of ' + cityString
else :
newName = curAdj + ' Free Republic'


if( RevUtils.getDemocracyLevel(iPlayer)[0] == 3 ) :
if( 50 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = curAdj + ' League'
else :
newName = 'League of ' + curShort


else :
if( 'Republic' in curDesc and not 'People' in curDesc and not 'Soc. ' in curDesc and not 'Free ' in curDesc ) :
if( len(curDesc) < 17 and 20 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = 'New ' + curDesc
else :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - keeping prior name")
newName = curDesc
elif( 50 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = curAdj + ' Republic'
else :
newName = 'Republic of ' + curShort

The spacing didn't come out quite right: my "if" is even with "self.LOG" etc., with no indentation errors on load. Any ideas on how I should have done this?

jdog5000
Jul 10, 2008, 02:14 AM
You've got an invisible error! No really ... you've got tabs while all my indents are spaces. It can appear to be in the correct position if you're using an editor that shows tabs as one number of spaces but then Civ/Python may consider them another number. Don't worry, you're hardly along on this ... Firaxis has some mixed files that work by the grace of the Python gods as well. I'd really recommend using a good editor like Notepad++ for Python and setting it to display white space and tabs and replace your tab strokes with 4 spaces (if you like to use the IDLE editor that comes with Python you can do most of these things there as well).

One small thing would be to change your if to and elif ... right now you clause will effectively overwrite the only 1 city logic, if that's what you want then move your clause up and make the other an elif.

Another thing you can do is imitate the logic which keeps the form of "League of ___" vs "___ League" consistent when non-consequential civics are changed ... something like:


if( 'League' in curDesc ) :
newName = curDesc
elif the rest of your code


With that you should be good to go.

Hephaistion
Jul 10, 2008, 12:16 PM
@jdog:

Thanks so much! This is extremely helpful.

EDIT: Leagues are go! Notepad2 made it much easier!

wilcoxchar
Jul 22, 2008, 08:06 PM
Could you perhaps give a list of all the parts of DynamicCivNames.py which do not need to be included if I am not using it with the Revolution modpack? I would like to basically start from scratch adding my own names and classifications. Also, thank you very much for releasing this, I can't wait to start adding my own civ names. :)

EDIT: I've been doing some fiddling with the file, and have made some modifications but the game won't show my changes. Here is my code.

def newNameByCivics( self, iPlayer, bVerbose = False ) :
# Assigns a new name to a player based on their civics choices

pPlayer = gc.getPlayer(iPlayer)
capital = pPlayer.getCapitalCity()
playerEra = pPlayer.getCurrentEra()

curDesc = pPlayer.getCivilizationDescription(0)
curShort = pPlayer.getCivilizationShortDescription(0)
curAdj = pPlayer.getCivilizationAdjective(0)

civInfo = gc.getCivilizationInfo(pPlayer.getCivilizationType ())
origDesc = civInfo.getDescription()
origShort = civInfo.getShortDescription(0)
origAdj = civInfo.getAdjective(0)

if( game.getGameTurn() == 0 ) :
# Not clear if all game data is properly loaded yet
if( playerEra < 3 ) :
newName = curDesc
else :
newName = curDesc
return [newName,curShort,curAdj]

newName = origDesc
if( SDTK.sdObjectExists( "Revolution", pPlayer ) ) :
revTurn = SDTK.sdObjectGetVal( "Revolution", pPlayer, 'RevolutionTurn' )
else :
revTurn = None

if( SDTK.sdObjectExists( "BarbarianCiv", pPlayer ) ) :
barbTurn = SDTK.sdObjectGetVal( "BarbarianCiv", pPlayer, 'SpawnTurn' )
else :
barbTurn = None

if( not pPlayer.isAlive() ) :
newName = curAdj + ' Refugees'
return [newName, curShort, curAdj]

if( not revTurn == None and game.getGameTurn() - revTurn < 20 and pPlayer.getNumCities() < 3 ) :
# Maintain name of rebels from Revolution Mod
newName = curDesc
return [newName, curShort, curAdj]
elif( not barbTurn == None and game.getGameTurn() - barbTurn < 20 and pPlayer.getNumCities() < 4 ) :
# Maintain name of BarbarianCiv created player
newName = curDesc
return [newName, curShort, curAdj]

# Main naming conditions
if( pPlayer.getNumCities() == 0 ) :
if( 'Tribes' in curDesc or 'Peoples' in curDesc ) :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - keeping prior name")
newName = curDesc
elif( 50 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = curAdj + ' Tribes'
else :
newName = carAdj + ' Peoples'
elif( pPlayer.getNumCities() == 1 ) :
if( 'Free' in curdesc ) :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - keeping prior name")
newName = curDesc
elif( 50 > game.getSorenRandNum(100,'Rev: Naming') ) :
newName = "Free City of " + CvUtil.convertToStr(capital.getName())
else :
newName = "Free State of " + CvUtil.convertToStr(capital.getName())
else :
if( 'Kingdom' in curdesc ) :
if( self.LOG_DEBUG and bVerbose ) : CvUtil.pyPrint("Names - keeping prior name")
newName = curDesc
elif( 30 < game.getSorenRandNum(100,'Rev: Naming') ) :
newName = curAdj + " Kingdom"
else :
newName = "Kingdom of " + curShort

return [newName, curShort, curAdj]

This is all that I have put in the newNameByCivics, but when I load up the mod and start the game, it still shows my civ name as the _____ Empire. Please help!

jdog5000
Jul 24, 2008, 02:06 AM
You seem to be doing pretty well in figuring things out, the one catch which is causing your civ to keep the ___ Empire name at the start is an early check for game.getGameTurn() == 0. Remove that bit and then you should start as the Tribes or Peoples.

wilcoxchar
Jul 24, 2008, 06:44 PM
Hmmm, I got rid of this (I think that's what you were referring to), but it still shows it as empire.

if( game.getGameTurn() == 0 ) :
# Not clear if all game data is properly loaded yet
if( playerEra < 3 ) :
newName = curDesc
else :
newName = curDesc
return [newName,curShort,curAdj]

Also, does the game check newNameByCivics every turn? And if it doesn't, is there a way to get it to check every turn?

Thank you for your help, this is a great idea to add more flavor to the game. :)

jdog5000
Jul 25, 2008, 12:20 AM
No, it doesn't run the name checking every turn but that's easy to change if you want ... in the function onBeginPlayerTurn:


if( iPrevPlayer >= 0 and iPrevPlayer < gc.getBARBARIAN_PLAYER() ) :
iPlayer = iPrevPlayer
pPlayer = gc.getPlayer( iPlayer )
if( pPlayer.isAlive() ) : self.setNewNameByCivics(iPlayer)


add the bolded line above and remove all the following clauses.

wilcoxchar
Jul 25, 2008, 05:11 PM
Okay, I've now gotten it to show up as tribes or peoples at the beginning for all civs. However, now it won't change to Free City of ____ or Free State of _____ once I've founded my capital. :(

jdog5000
Jul 25, 2008, 08:17 PM
For you application you'll want to change the code in onCityBuilt and onCityAcquired to:


if( owner.isAlive() and not owner.isBarbarian() ) :
self.setNewNameByCivics( owner.getID() )


by removing some lines.

wilcoxchar
Jul 25, 2008, 10:54 PM
I think the problem might be that it's still not checking in between turns, even with the change to onBeginPlayerTurn. I've played a game about 10 turns in and it still wouldn't change with my city. Not sure what would be stopping it from checking though.

johny smith
Nov 11, 2008, 07:27 AM
Please forgive my ignorance. But wanted to ask is there a way that leaders could determine the name of a civ?

Like say if someone wanted to put HRE and Germany into one civilization. In this example placing all of the leaders into the Germany civilization. And say you begin with one leader and when you swap to Charlemagne you civ could be renamed Holy Roman Empire or whatever based on what leader you have. Then the following civic description would follow.

jdog5000
Nov 11, 2008, 01:22 PM
Definitely possible ... right now if you name yourself:

Description: The Smurf Empire
Short: Smurf
Adjective: Smurfese

Then later in the game you may find yourself ruling the "Republic of Smurf" or the "Smurfese Kingdom".

Basically what needs to happen is that when the leader changes the short and adjective versions of the civ name need to change. The proper way to do this would be to augment each leader XML def with Civ name fields and make these accessible through the SDK. The quick and easy way would be to create a Python-level association (like is currently done in RebelTypes.py) to match leader types with civ name strings.

When the leader changes you'd update the Short and Adjective versions of the civ name based on the new leader and then call the DynamicCivNames civics-based naming function. Right now that's not guaranteed to change the name as I keep the old name if the civics-based parts are similar (ie, don't constantly switch from "___ Kingdom" to "Kingdom of ___") ... I'll add a flag for the next version to force the name to update which will make the new name stick and check that version into WoC.

phungus420
Nov 11, 2008, 02:53 PM
The proper way to do this would be to augment each leader XML def with Civ name fields and make these accessible through the SDK.
Wouldn't this create problems with non default civs? It would be a serious pain if people who merge this mod (of which there are many), had to rebuild the leaderheadsinfos file.

johny smith
Nov 12, 2008, 08:14 AM
Thanks:). I will look at it more when we get all of Revolution in the WoC.

jdog5000
Nov 13, 2008, 07:47 PM
Wouldn't this create problems with non default civs? It would be a serious pain if people who merge this mod (of which there are many), had to rebuild the leaderheadsinfos file.

I wouldn't been this for the main version of the mod, don't worry. That was just for if the WoC team wanted to tackel it the "right" way.

I think I will create the Python style functionality for the main mod though, with a default of having no change to the normal names.

Onionsoilder
Nov 16, 2008, 10:30 PM
Is any way to edit the dynamic civ names through XML? I suck at Python. I've added about 3 new government civics to one of my mods, and I'd like to know how to set those up with dynamic names.

jdog5000
Nov 20, 2008, 12:18 AM
No, sorry ... the renaming is all scripted in Python. Earlier in this thread I helped others add dynamic names for new civics, see the post by Hephaistion in particular. Post questions and eventually you'll figure it out! Python is really sweet.

Dresden
Nov 25, 2008, 12:03 AM
In order to fix a bug in the "normal" game involving spawned colonies reusing IDs of eliminated players one option I'm considering is implementing some of the changes dynamic civ names makes (such as storing a copy of the name string in the player object) in the Unofficial Patch. However, I noticed the component adds the names to the save file. Does that break compatibility with saves from the unmodified game?

jdog5000
Nov 25, 2008, 02:08 PM
Yeah, I'm pretty sure it would break compatibility. Is there a thread describing the particular problem?

You could also consider writing an empty string to CvInitCore::setCivDescription, etc in CvGame::addPlayer perhaps.

Dresden
Nov 25, 2008, 07:11 PM
Yeah, I'm pretty sure it would break compatibility. Is there a thread describing the particular problem?

You could also consider writing an empty string to CvInitCore::setCivDescription, etc in CvGame::addPlayer perhaps.
There's not a thread, just a save that was posted to the solver sticky topic. (Description (http://forums.civfanatics.com/showpost.php?p=7477229&postcount=864); save (http://forums.civfanatics.com/attachment.php?attachmentid=195202&d=1227525538)) The base problem seems to be that CvPlayer::getName() (and related functions) default to using the non-SDK gDLL->getPlayerName() function if it's non-empty. But when a player is eliminated and a colony takes the slot, gDLL->getPlayerName() still returns the name of the now-dead original player.

Will the CvInitCore::set___() methods allow us to clear or change those strings that are returned by the non-SDK functions during a running game? So I could explicitly do a CvInitCore::setLeaderName(), etc. after the CvGame::addPlayer() call in CvPlayer::splitEmpire()? That would be ideal.

But if that doesn't work, I will probably wind up putting an explicit colony bypass in the getName() functions and force it to go from leaderhead info when the player was a colony. So for example the following:

const wchar* CvPlayer::getName(uint uiForm) const
{
if (isEmpty(gDLL->getPlayerName(getID(), uiForm)) || (GC.getGameINLINE().isMPOption(MPOPTION_ANONYMOUS) && isAlive() && GC.getGameINLINE().getGameState() == GAMESTATE_ON))
{
return GC.getLeaderHeadInfo(getLeaderType()).getDescripti on(uiForm);
}
else
{
return gDLL->getPlayerName(getID(), uiForm);
}
}


would change to:
const wchar* CvPlayer::getName(uint uiForm) const
{
if ( (getParent() != NO_PLAYER) || (isEmpty(gDLL->getPlayerName(getID(), uiForm)) || (GC.getGameINLINE().isMPOption(MPOPTION_ANONYMOUS) && isAlive() && GC.getGameINLINE().getGameState() == GAMESTATE_ON)))
{
return GC.getLeaderHeadInfo(getLeaderType()).getDescripti on(uiForm);
}
else
{
return gDLL->getPlayerName(getID(), uiForm);
}
}


That should force a custom name bypass for a colony (since only colonies have a parent defined) without causing any side effects.

jdog5000
Nov 25, 2008, 08:20 PM
I am 99% certain that the CvInitCore::set___("") methods will work. There are a bunch of similar calls in CvGame::addPlayer ... if you remove them you can get some really strange results so they definitely have the intended effect.

If it was me, I'd put the name clearing inside of CvGame::addPlayer with a check to see if the civ type is actually changing ... doesn't really matter for the unofficial patch, but it does make a difference in Revolution where new players show up all the time outside the colony mechanics.

Your fallback solution also sounds reasonable, but I think the CvInitCore methods are the way to go.

Dresden
Nov 25, 2008, 09:47 PM
OK, following that advice, I'm going to try adding the following block to the beginning of CvGame::addPlayer():
LeaderHeadTypes eOldLeader = GET_PLAYER(eNewPlayer).getLeaderType();
CivilizationTypes eOldCiv = GET_PLAYER(eNewPlayer).getCivilizationType();
CvWString szEmptyString = "";
if ( ((eOldLeader != NO_LEADER) && (eOldLeader != eLeader)) || ((eOldCiv != NO_CIVILIZATION) && (eOldCiv != eCiv)) )
{
GC.getInitCore().setLeaderName(eNewPlayer, szEmptyString);
GC.getInitCore().setCivAdjective(eNewPlayer, szEmptyString);
GC.getInitCore().setCivDescription(eNewPlayer, szEmptyString);
GC.getInitCore().setCivShortDesc(eNewPlayer, szEmptyString);
}

Seems to work OK on an initial test; can you think of any problems that might cause or things I should watch out for?

EDIT: And would it be better to separate out the leader name blanking from the civ name blanking like so?
CvWString szEmptyString = "";
LeaderHeadTypes eOldLeader = GET_PLAYER(eNewPlayer).getLeaderType();
if ( (eOldLeader != NO_LEADER) && (eOldLeader != eLeader) )
{
GC.getInitCore().setLeaderName(eNewPlayer, szEmptyString);
}
CivilizationTypes eOldCiv = GET_PLAYER(eNewPlayer).getCivilizationType();
if ( (eOldCiv != NO_CIVILIZATION) && (eOldCiv != eCiv) )
{
GC.getInitCore().setCivAdjective(eNewPlayer, szEmptyString);
GC.getInitCore().setCivDescription(eNewPlayer, szEmptyString);
GC.getInitCore().setCivShortDesc(eNewPlayer, szEmptyString);
}

jdog5000
Nov 30, 2008, 11:41 AM
Sorry for the slow response ... the split version looks good to me. I can't think of any problems this could cause, since you're putting it at the beginning of addPlayer everything should work well.