[BTS] Real Random Personalities

Major Tom

Mortal
Joined
Jun 1, 2005
Messages
756
Location
Oslo
The custom game option for random personalities just interchange personalities of existing leaders. Not very difficult to deduct who is who after a while looking at trade tables and bribing opportunities. So is it a mod out there that assign totally random attributes to AI personalities? Or can you do that yourself in xml, perhaps?
 
I took a brief look at this and you are right. Randomize personalities will just shuffle leaders while the individual leaders will still act like that leader in xml. No real randomness there and yeah if you know how a certain leader acts, you can tell.

What seems to be required is modding the DLL. On player creation, copy the leader data from leaderheadinfo to CvPlayer. In CvPlayerAI (and whereever else this applies) change code from
PHP:
GC.getLeaderHeadInfo(getPersonalityType()).getRazeCityProb()
into getting the same value from CvPlayer. This applies to all the leaderhead info data, not just this one specifically.

Doing this will change nothing, but it will allow random personalities to create a random value for each setting for each leader, making leaders, which will be unique to the game in question. Most likely the random numbers should be in a range set in xml. I can't really see this being done in any other way, meaning there is no way to do anything like this without modding the DLL itself. In theory you can hack python to alter the leaderhead xml data at random, but it will be a mess.

Next question is if anybody has done anything like this already? I honestly have no idea.
 
Thanks for reply and looking at it. I have no clue about modding, but what about creating random values in Excel (after converting leaderhead xml to xlsx), then copy values back to original xml file?

Edit: Think also this is a mess as xml is not a nice table with rows and columns.
 
You can change the values in xml manually. Some of them are stored in the savegame while others will apply when loading a savegame. Don't try to convert into another format and then back. Edit the xml file directly with a proper editor like notepad++. However editing new values manually will only allow you to assign new values. What it doesn't do is assign truly random personalities, which you have to figure out during gameplay. It doesn't matter if you change a leader from eager to make sneak attacks to never make sneak attacks. The point is that you know and can predict if he wants to do so. Modding the DLL file is the only real option if you want to not know the leaders in advance.

I fully agree that it's not a trivial task to mod. Not only is it in the DLL (apparently the hardest part to even start modding), what I propose requires some insights in the savegame format as well as requiring code changes whenever the AI relies on some personality setting.

Keep in mind that what I wrote here is meant as assistance/hints to anybody who would want to try to implement this. Writing for any other target audience seems pointless as it would be mostly useless for the chance of anybody giving it a try. If I wrote stuff most people don't get, then so be it. I prefer writing unreadable for 95% of all people and get somebody to implement something than to write for everybody and not get a working implementation. Still even with what I wrote here, I wouldn't hold my breath for somebody to show up and hand over a working implementation.
 
No worries! Appreciate your feedback anyway and also hope that someone one day might give it a try.
 
I'm not aware of any mod with randomly generated personalities. It sounds like an interesting task to design and implement (though I won't do it). One could let the program iterate over all BtS leaders to measure the distribution of each LeaderHead parameter – e.g. RazeCityProb is 0% for 33 leaders, 5% for 2 leaders, etc. Then pick a value at random according to that distribution. However, there should also be some dependencies. E.g. a leader that trains a lot of units should tend to have a low peace-weight. A two-step process could work that first generates a small set of basic personality values that are fully independent of each other and derives the rest of the values from those basics.
[...] In CvPlayerAI (and whereever else this applies) change code from
PHP:
GC.getLeaderHeadInfo(getPersonalityType()).getRazeCityProb()
into getting the same value from CvPlayer. This applies to all the leaderhead info data, not just this one specifically.
That might be a three-digit number of calls to change. This could perhaps be avoided by having CvPlayer create a new CvLeaderHeadInfo object and putting it into m_paLeaderHeadInfo in CvGlobals.cpp (if the random personalities option is enabled). That CvLeaderHeadInfo object would have to be stored in savegames.
[...] It doesn't matter if you change a leader from eager to make sneak attacks to never make sneak attacks. The point is that you know and can predict if he wants to do so. Modding the DLL file is the only real option if you want to not know the leaders in advance.
If you had a script (or perhaps Excel could do it too) that generates a CvLeaderHeadInfo.xml with 52 random personalities (plus the Barbarians as in BtS) and copies that file into the mod's Assets folder, you'd just have to run that script before starting the game – unless you want to continue from a savegame with the current leaders. Inconvenient; though this approach would have the advantage that you could play multiple games with the same set of random leaders.
 
That might be a three-digit number of calls to change. This could perhaps be avoided by having CvPlayer create a new CvLeaderHeadInfo object and putting it into m_paLeaderHeadInfo in CvGlobals.cpp (if the random personalities option is enabled). That CvLeaderHeadInfo object would have to be stored in savegames.
GC.getLeaderHeadInfo(getPersonalityType()) is used:
CvCityAI.cpp | 8
CvPlayer.cpp | 3
CvPlayerAI.cpp | 125
It looks like the first 2 are fairly easy to convert. CvPlayerAI is more work, but remember you can use the this pointer to make all the calls follow the same "template", meaning it should be fairly simple to do a search and replace for each variable from xml. This doesn't look more complex than adding new leaderheads and save those. In fact hacking the existing leaderhead code looks like it will not only be more messy and prone to bugs, it will also be more work if you are to make sure it works in savegames and network games.

Implementing this should search for each tag rather than this "global" keyword as there is a risk the general search can miss some, like getting the personality from the other player in diplomacy. However the search I did is good enough for getting an idea of how many lines, which needs to be modded. Also searching for individual tags takes longer and it's not like I'm starting on actually doing this task right now (if ever). Last, but not least: if one call is missed, it will just make the AI use the default value. Yes it's a bug, which should be avoided, but it won't be crash the game or or cause any other game breaking failure.
 
There are 20 more in CvTeamAI.cpp (e.g. GC.getLeaderHeadInfo(GET_PLAYER((PlayerTypes)iI).getPersonalityType())), but that seems to be about it. I guess I'm already thinking about how easily I could merge the code if someone else were to write it. :)

Another idle thought about probability distributions and dependencies: A more general problem is to synthesize data that resembles a given set of samples (the samples being the 52 BtS leaders in this case). There might be a good off-the-shelf algorithm for this. A quick web search led me to this question on StackExchange. The first two suggested algorithms (SMOTE, MUNGE) are apparently based on mashing similar samples together to create new samples. That sounds like the resulting leaders would be too similar to the original leaders. I suppose it would have to be something more complex that explicitly derives (conditional) probability distributions from the sample data. The last suggestion, synthpop, appears to be in that vein.
 
Last edited:
A quick and "dummy" solution could be to create some (a lot of) non-playable leader personalities that are aligned with the barbarian state or none at all. Than the random dice can also pick one of those.
The upside of this is, that you can have balanced personalities.
The downside is, that it looks "not-so-nice" in the civilopedia, not to mention the possible issues of also using "Unrestricted Leaders" option (they need graphics too).
 
Back
Top Bottom