AIColosseum: Utility allowing different AI mods to play directly against each other

falconne

meep
Joined
Nov 24, 2005
Messages
204
Location
New Zealand
It's great that Civ4's game logic is completely exposed in a SDK, but I was disappointed the framework tightly couples the game rules and game AI. It doesn't allow pure AI mods to be played directly against each other, with different civs in the game controlled by completely different AI modules.

I was hoping there would be something like Robocode that allows AI modules to compete in a single environment without human intervention. I think the advantages of something like that are obvious. Not only does it provide empirical as to which AI modules are better than others, it allows AI mod writers to test newer versions of their mods against older versions, to check if complex changes didn't make the AI worse due to some bug. This isn't so easy when all AI's in the game a driven by the same code.

So anyway, I thought I'd have a crack at creating a utility that allowed this to happen. I decided to start with the SDK first, as this is where most AI coding is done and work on Python later. My goal was to make something that allowed mods that follow the same game rules, but have different AI logic, to be combined into one CvGameCore.dll with ability for different Civs in a game started from this dll to use different AI modules (so, for e.g., if a dll is created with 2 AI mods, then a game started with that dll will have half the AI's using one module and the rest using the other). By "AI module", I refer extracting just the bits of a mod that define AI logic and packaging it into an "AI module" that can coexist with other "AI modules". Combined with AutoPlay, this would create the simulation environment I want.

Because it would ignore non AI classes, this utility would work just as well for total conversion mods, so long as the mods put the AI logic in the places where it's supposed to go.

I now have an initial version that satisfies the the requirements to a reasonable extent. I've been testing it successfully with the Better AI mod for BTS, by having "Better AI" driven Civs play against those driven by the AI shipped with BTS 3.17. This was a good test mod as all the AI changes were done in the SDK.

I was hoping there'd be other substantial AI mods out there I could test with. If anyone's got one please let me know where I can get the source.

I thought I'd put what I have so far out there hoping someone working on an AI mod would try it out to see how well their improvements are coming along and tell me if they find problems with it.

Download: Build #2

How it Works
The tool (called AIColosseum.exe) takes as input the location of the SDK source for the mods to be added to the "colosseum" and a destination path where the colosseum source will be created. The "colosseum source" is code that can be compiled to create a new CvGameCore.dll with the AI modules form each input mod crammed in there.

The architecture of the SDK is such that all AI logic should go in the Cv*AI classes (i.e. the unit AI goes in CvUnitAI class). I used this fact to make the assumption that only the content of those classes are required to construct the "AI module" for that mod. This isn't strictly true, but it's good enough to start with. For a pure AI mod, any changes that are done to other classes should be about fixing game bugs and adding utility functions to support the AI. I take the non AI classes from one mod and assume that those will be compatible with all the other mods given for the utility.

The jist of what happens is, the Cv*AI classes of the colosseum source are hollowed out and turned into abstract interfaces, with every method being virtual and their implementations stubbed out. This interface is a composite of the interfaces of each input mod (i.e. for each Cv*AI class, every method definition that is in at least one input mod gets represented in the new class). Then, for each Cv*AI class, for every input mod, a new class is created that derives from the Cv*AI class (named with the mod's name appended to the basename) and the content of this class will be the content of the Cv*AI class for that mod. Now all the tool has to do is change every location where an AI object is instantiated for a player to use the specific implementation class that is appropriate for the AI module that player is assigned to and polymorphism does the rest. There's quite a few things that must be changed for things to work after this, but that's all detail.

Most of work is actually in analysing the source classes and shifting methods around, dealing with encapsulation, statics, detecting incompatibilities, etc and because some of the classes in the SDK are tens of thousands of lines long, the utility takes a while to run.

I don't create functionality to auto run the game once it has started. I'll do that in a later version, but for now, to be able to create a "simulation environment", the primary mod (the one from which the non AI classes will be copied from) will need to have AIAutoPlay from mrgenie and jdog5000.

Normally, the game treats the human player differently than AI players. Theoretically, on Noble difficulty, there should be no difference between human and AI. Just in case, I've made it so that the first player slot (which is human by default) be treated as an AI during game setup (it has to be set back to human just before the . When running the game using AutoPlay functionality, the first slot is set to be treated as an AI, so it should be all good.

At the moment, you can't pick which Civ gets which AI module - they get automatically allocated as evenly as possible. If you create a colosseum with 3 mods, then Slot1=Mod1, Slot2=Mod2, Slot3=Mod3, Slot4=Mod1, Slot5=Mod2... and so on. Barbarians get assigned whatever mod happens to align with the slot they're in. I will make this selectable in the future too.

When the leader name is displayed on the interface during the game, the name of the module they are running will be appended (e.g. Alexander (BetterAI)), so you can tell who's who at a glance.

Usage
Simple command line usage:
AIColosseum.exe --dest=<destination path> --source=<source path>,<mod name> [...]

--dest is a folder where the colosseum code will be created. It will be created if it does not exist. NOTE: If it already exists, the source files in there will be overwritten without warning!

--source can be included multiple times, once for each input mod. The <source path> is where to find the SDK source for that mod, and <mod name> is how the module will be identified, for naming its classes and showing against the name of leaders using that module. The first source module given will be used as the "primary" module - all the non AI classes form this mod will be copied as the basis for those classes in the colosseum source. This means, even though it's ok for the input mods to have a few differences in their non AI classes, only the functionality of those classes in the first mod will be available in the colosseum, so it should contain the superset of functionality required for all mods.

The utility does not copy anything other than source code from the primary mod to the destination folder. You will need to copy Boost and Python folders, as well as makefiles over to the destination yourself to build it. There are no new files created, so you don't need to modify your makefiles.

NOTE: When starting a game, make sure you select "Noble" for difficulty of the first slot, so it isn't handicapped.

For example, to create a colosseum with the Better AI mod vs the AI shipped with BTS (which I call Vanilla) on my machine, I use:
AIColosseum.exe --dest=D:\Dev\Civ\Colosseum --source="D:\Dev\Civ\Better AI\Trunk\CvGameCoreDLL,BetterAI" --source="D:\Dev\Civ\BTS-Original,Vanilla"

Typically, I would test this by setting MapRandSeed to a specific value so I generate the same map each time, selecting the same two leaders each game and AutoPlaying to the end of a "Duel" sized balanced map on "Quick". I'd do this first on vanilla BTS 3.17 for 2 or 3 games and record the results. Then I'd open up the built colosseum versio, do the same (same map seed, same leaders and all other options) and see if the BetterAI controlled player does better against the Vanilla controlled player than it did when they were both Vanilla controlled.

Admittedly, I had to do some slight modifications to the BetterAI source before it could be used by this utility. This was because there was a method signature change in the mod that made it particularly difficult to accomodate both the Vanilla signature and the BetterAI signature in the interface class (unfortunate combination of argument default values and implicit conversion), but apart from that everything else combined without a problem.

I should also mention that destination source will not have any comments from the original mods in them, as these need to be stripped while parsing the mod source.

Limitations
I hope to address these soon, but as the first build, there are a number of useful features lacking:

- Ability to manually assign modules to player slots. I'll probably do this through a settings file.
- Automatically splice in AutoPlay component if it doesn't exist in the primary mod.
- Combine non AI classes so the primary mod doesn't have to have the superset of functionality. This is easy when methods exist in one mod and not others, but becomes difficult when existing methods have different content across mods
- Functionality to ease benchmarking. Currently, for benchmarking, you should make use of the MapRandSeed setting in CivilizationIV.ini to make sure you always test with the same starting conditions.

Even with these limitations, I hope someone finds this useful in improving the AI in their mod. There's bound to be a few corner cases of code changes that can't be combined together, but if you notify me of any problems, I'll find a fix for them.
 
Amazing! I think it may take some time until the potential of this utility gets fully used (because as the OP says, there aren't actually any competing AI mods out there yet), but this utility offers a great framework for further AI programming.

One idea for further development: Will it be possible to split the current "normal AI" and the current "aggressive AI" (which gets used when the respective option is switched on) into different modules and so use both in the same game? I've always wondered whether the aggressive AI is actually better, or whether it gets so bogged down in its continuous wars that a non-aggressive AI would finally pull ahead if it manages ro stay out of the fray. Could this be made testable with this utility?
 
I agree Psyringe, there's unlikely to be many competing AI mods out there because whenever there is a good idea, it should get merged into the established mod (in this case the BTS Better AI mod). I'm targeting this tool more at the AI testing purpose - for proving if a new version of the mod is better than a previous version.

Good point about testing the aggressive AI. I should have thought of that as a test scenario. It's quite simple actually - using the Better AI base, I've just gone and created a "mod" where I did a search and replace on all the places where the code checks the aggressive game setting and hardcoded the value to "false" (in effect making all AI's in that mod play non-aggressive regardless of the setting). I'm calling that mod "Calm" and combined it into a colosseum with the base Better AI code.

So now all I have to do is run a simulation with lots of players through with the "Aggressive AI" option on, which means that half the AI's will be on "aggressive" and the other half on normal. Then I'll record the results and rerun the same simulation with the same map and leaders, but with the "Aggressive AI" option turned off. This means all the AI's will be running non aggressive and I can compare how the AI's that were going aggressive in the previous run perform under normal mode.

I'll post the results when I have them - unfortunately we're having a bit of a hot summer down here and my CPU can't take the heat created by running Civ for so long :sad: so I have to wait for the temperature to drop a bit.
 
Since you mention the ability to run this on full conversion mods, you could always see how the AI from base BtS does at playing Fall from Heaven ;) The AI for FfH hasn't been completely re-written as yet, but many aspects have changed up to this point, so they should run quite differently. At the least it should give you a clear difference in AI capability if not much shows up testing against BetterAI.
 
Ideally the python and xml should be the same, or at least, one set has to be the superset of the other.

What this is going to do is combine two AI dlls into one so when you pop that dll into a mod folder you're only going to be able to use the python and xml from one of the source mods.
 
Makes sense. Unfortunately the original mod that I want to compare my modmod to uses python for determining city build priorities whereas I'm trying to keep that functionality in the DLL, so I dont think this will work for me.

Thanks for the quick response. Extremely cool utility!
 
Yeah unfortunately that would require a lot more work - the engine would have to be able to load two independent sets of Python scripts.

The main reason I wrote this was so that I could test if changes I was doing in the dll were making the AI better or worse, so it's mostly for testing between different versions of the same mod.
 
Out of curiosity, did you run the aggressive AI vs. "calm" AI tests and if yes, which were the results?

I didn't have a chance to run enough samples to get a useful result unfortunately. From what I remember, some AIs did better under Aggressive than they were under Normal (starting with the same random seed), but others were worse. I think it was mostly the overly peaceful leaders that benefited from it.
 
Thanks nonetheless for your efforts. Running enough trials to get a "useful" result was a huge task anyway. I'm happy to hear that some trials were run and that you were able to derive a working hypothesis from your observations. Thanks again. :)
 
I'd thought about going back to it and doing it properly, but then Civ 5 was announced so I figured I'd wait and see how that turns out :) I hope they design it this time so that we can put different AI mods into one game without having to hack it.
 
Back
Top Bottom