K-Mod: Far Beyond the Sword

I've just uploaded yet another bug fix... v1.04d. The bug would sometimes prevent peace deals from being made. (What was happening was that the human player was automatically refusing peace with the same decision making code that is meant for the AI. ie. The K-Mod AI is meant to refuse to make peace when it is aiming for a conquest victory; but this bug was forcing that same decision onto human players when it thinks they should be going for a conquest victory...)


But perhaps more importantly, I've just worked out one of the main causes for late-game slowdown. It turns out that a lot of the slowness is nothing to do with the inefficient code or python callbacks or anything like that. (a lot of the slowness is to do with that stuff, but a lot isn't.) I've discovered that by far the biggest cause of slowdown is that the AI is programmed to only move one group in each game time-slice.

This means that when there are lots and lots of units, lots and lots of time is spent simply waiting for actions to be carried out by AI units before the AI even considers issuing a command for its next unit.

I can change this, and the speed gain will be enormous. I've changed the code so that the AI will move all groups that have the same AI priority level at the same time. (for example, all AI spies will move at once, and then all bombers, or whatever, and so on.) I profiled some late-game turns with and without this change, and the difference is 100%!. The game runs twice as fast with this change. ie. the time between each turn is halved.

That's a pretty attractive speed gain - but I should point out that it could come with some cost to the AI's abilities. Because it is ordering a bunch of units at the same time, it is likely to get a bit confused. For example, two spies might try to sabotage the same building at the same time; or two cavalry might try to attack the same enemy unit. The spy thing isn't a big problem; because the second spy mission will simply not happen if the first succeeds, and the second spy will then get to move again before the AI finishes its turn. But the attacking thing is a problem - because sometimes it will result in a big bunch of AI units all moving to attack a single target, while other potential targets simply get ignored.

To get around this problem, I'm thinking of setting it up to move multiple units only when none of them are doing any non-movement actions. For example, if there is combat, or a spy mission, or an airship recon mission, etc., the AI will wait for the that mission to finish before giving its next command (just as it does currently). But if all the unit does is move, or just skip its turn (for example, a city defender just standing still in a city), then the AI will consider moving another unit at the same time.

This solution might still lead to some slightly degraded AI decision making (for example, the AI might decide to move two city defenders to the same destination at the same time for the same reason, when it only needs one.) - but the potential speed gains might just be too big to ignore.

What do you think?
 
So let me get this straight. In the unmodded AI, when the AI moves groups of units, it idles while the actions of one group are completed, then reassesses the whole situation again, and then decides to move another unit--and so on, ad nauseum?

That's ... blaaaaaah!

I think gaining the speed first (in the way you described) and sorting out the consequences later sounds like a WONDERFUL idea. :3

Adventure! Finally, a chance to actually enjoy playing the late game of Civ4!
 
I think you've pretty much got it straight. The way I found out that this was a problem was that when I ran the profiler on a particular turn, I found that the turn itself took around 12 seconds, but that only 4 seconds were spent inside the dll code... that's just 8 seconds of the game just sitting on its hands. That's the 8 seconds that we are trying to recover.

But I've just looked at it again, and I think it's a bit more difficult to fix than I previously thought. -- It's kind of hard to tell exactly how it works without seeing what's inside the .exe code, but by the look of things it seems to me that moving units and skipping turns already don't cause the AI to wait. -- so... well.. that makes it less obvious what should be done. I still full expect to have some serious speed gains in the next version though.
 
Huh. I guess there's always the possibility of letting the AI go ahead and make lots of decisions at once (and seeing exactly what sorts of train-wrecks of bad decisions ensue) and going from there. I'd be curious to see what that looked like in terms of speed, even if it was kind of inferior AI-wise.
 
Well, if you'd like to see how it plays, I've uploaded the modified dll to this post.

In this version, the AI doesn't move everything at once, but it does move all units with the same priority at once. I don't think the AI will be awful, but I fully expect it to make some dumb moves from time to time. And I expect it to run a lot faster - particularly if you have a fast computer. (I'm pretty sure that the dead-time will be the same regardless of how fast your computer is; and so if we reduce that dead-time, then fast computers will get a proportionally larger speed boost.)

[edit]
(I've removed the attachment, because it is now obsolete.)
 
Going to give it a try now.
 
Hi Karadoc, still very busy I see! That makes me think that it's a bit pointless for me to try to incorporate K-mod with mine since I would need to constantly update the code: since my last note you published three new versions of your DLL!

Personally, I would be prudent in reducing the AI capability in favour of speed. After all, your first goal was to improve the AI. Good luck with it but I wouldn't like more speed for lesser AI.

Yesterday, I spent a lot of time trying to debug my mod because it crashed (it rarely does). So it was the first time for me playing with a debug dll. The game there did not crash but kept breaking in CVPlayerAI in the 'AI_bestTech'. Incredible piece of code. It kept saying that the error comes when dividing a value by zero. But that part is stricly vanilla for me! I was changing the value and turn after the turn the game would progress but the error would come back.

So today, I thought of looking into your file (line 6404 - maybe BBAI change) and it differs from the vanilla formula like this:
iAssaultValue += (800 * (iNewCapacity - iOldCapacity)) / std::max(1, iOldCapacity);
instead of
iAssaultValue += (800 * (iNewCapacity - iOldCapacity)) / iOldCapacity;
I don't know C++ so what's the difference?

To Lenowill: so many values that you were referring to in your analysis of combats can be changed in the XML (for catapults, etc), including reviewing the promotions or even deleting the Medic3 for Great Generals as I did. You're right: I don't think that Napoleon was spending so much time under the chirurgical tent, unless for the morale of his troops...

And lastly, to come back to the Favorite Religion. I thought that the Favorite Civic was working quite well, any leader seeming even very concerned if you don't switch to their favourite one. What could be copied there for the Favorite Religion? One problem of course is that a civilization will finally arrive to their Favorite Civic but not necessarily to their Favorite Religion, if for example it was founded by somebody else on another continent. But there are Python ways to look for that, eventually.
 
std::max returns the higher number of the two parameters, thereby preventing divide by zero because it would pick one instead.
 
std::max returns the higher number of the two parameters, thereby preventing divide by zero because it would pick one instead.

Oh, thanks, exactly what I needed then! And after that you will hear from some people that vanilla code is crap!;)
 
Alright. I've uploaded version 1.05 (with almost no testing... you'd think I'd have learnt my lesson by now, but no; I just really think these changes are worth uploading.)

The new version has the speed improvements that we've been talking about, but without compromising the AI. The AI should be just as strong as before - in fact, it might actually be stronger, because I fixed a bug - and the game will be almost 100% faster.

I'm not exaggerating about the speed boost. On my computer, a 400 turn auto-play game on a standard size map took 26 mins before this change, and now it only takes 14 mins. (Of course, the times vary from game to game, depending on how much war there is and stuff like that.)

In the 14min game I just watched, Montezuma was well on the way to a domination victory at the end of the 400 turns... but Gandhi snuck in a cultural victory exactly on the 400 turn mark. So I'm satisfied that the AI is working correctly - although I haven't played the new version myself... at all.
 
I'm seriously downloading this... tomorrow, I'll see if I can handle this new AI on Monarch, and maybe try integrating my mod into it, of that's ok with you (and I would imagine it wouldn't be). :)

EDIT: How do you get the AI to auto-play? I'd really like to see the leaders in my mod play with each other, but I'd rather not play tons of games.
 
Good lord this is awesome

This has an SVN, right? So I can pick out the changes?

EDIT: I see it doesn't. Do you have the previous version somewhere for comparison's sake? Or can you tell me what was changed? I'd really like this in my mod.
 
I've uploaded the changes to github. The commit with the massive speed difference is this one, but that's probably not very helpful, since it is based on existing K-Mod code. I've just uploaded similar changes to the C2C svn, here. The C2C commit will be easier to port (because it didn't already have K-Mod changes) - but unfortunately, it doesn't have the awesome interface of github to make the code changes easy to read...

Anyway, I just hope this stuff doesn't have any unexpected side effects. As I've said, I've barely tested it...
 
It seems to me that, until now, non-gameplay changes of your mod from the base game can be split into the following categories:
- bug smashing
- speed improvements (sometimes without being 100% sure there is no demerit to the AI)
- improvements of the AI logic

Did you think about releasing separate dlls for these? Basically making forks of the "unofficial patch" and of "Better AI" ? I'm sure lots of people, who do not specifically agree perhaps with your changes to the gameplay (XML and stuffs) would be interested by those.
 
I have thought about releasing modules like that; but I've decided against it. The short reason is that it's too hard.

The longer reason...
Spoiler :
is that lots of the changes that I've made are interrelated. When I make bug fixes and AI changes, I often also make some structural changes to the code. This makes it easier for me to make future changes, but it makes it harder to extract individual changes to use in separate mods. Some of the AI changes involve some of the new gameplay mechanics (for example, the AI takes global warming into account when considering what their cities should build). Some of the bug fixes are not suitable for the unofficial patch, because they would have significant effects on the gameplay. Some bugfixes, in isolation, would actually make the AI play worse, (for example, hypothetically, a bug might prevent the AI from considering a certain action, which might be a good thing for the AI because it massively overvalues that action.) ... so the gist of it is that it would be hard to work out what should be in an AI-only patch, and what should be in a bugfix-only patch. And it would be hard to maintain all of these individual changes because the code would be interrelated... and also, importantly, it would be less interesting for me to work on - because I'd be duplicating code, and duplicating testing, and duplicating change logs and commit logs, and so on. I think my motivation would quickly evaporate.


So.. yes. I've thought about it, and I'm sure some people would appreciate that, but I'm not going to do it.

By the way, I think it's worth pointing out that even the Better AI mod has some gameplay changes. So it is not a pure AI mod either.
 
Woo! That was a blast. Turn times are so delightfully short.

This attached game save was played using the modified DLL you posted, and then (around 1800 or so) transitioned over into the latest version of the mod you posted. I'm 7 turns from winning by space at that point. I figured I'd post it in case there was anything you were wanting to "look for" in a real late-game situation. I didn't notice much in particular being wrong with the AI (apart from the usual stupidity of "Hey! I bet my Knights can take that city of yours with a Crossbowman in it. Oh wait, the Crossbowman upgraded to a Redcoat suddenly. Well, I'll just sit here and wait for them to come kill me then!" -- Suryavarman did that in a war he declared on me. You can see the results of that war in the file. xD)

The only thing questionable was that Cyrus seemed to waver too much about going for his Cultural victory. Like, he's obviously not running very much research (because he's taking like 40 turns to research Radio) but on the other hand he isn't going full-on for a (rather attainable) Cultural Win either. He'd been doing this for some time before the save, even. He tried to get a Diplo win several times as UN secretary, but that proved impossible. Tooooo much war in the world. Way too much, and I was glad I was able to remain neutral (despite ticking a lot of people off) and quietly go to space.

At first I was afraid I'd need to go raze Susa to keep him from the Culture Win, but he ended up not even getting all that close. Very impressive empire he had, though--and first place score.

I over-infrastructured way too much in that game, but it was a lot of fun. Map script was the fan-made PerfectWorld2, and the size was Huge. Normal speed.

Finishing a game on Huge without ever having thought, "Darn, these AI turn times are way too long" feels sooo good.
 

Attachments

I have thought about releasing modules like that; but I've decided against it. The short reason is that it's too hard.

The longer reason... -cut-

So.. yes. I've thought about it, and I'm sure some people would appreciate that, but I'm not going to do it.

By the way, I think it's worth pointing out that even the Better AI mod has some gameplay changes. So it is not a pure AI mod either.

Fair enough. I did not look at your code so I don't realize how much things are changed :)

Does BetterAI have gameplay changes ? First time I hear about it, except perhaps if it's about the gold overflow thing.
 
Karadoc: Thank you for this excellent mod. It is a great improvement on the base game.

I tried 1.05 using autoplay and found it much faster than standard.

One small problem; I noticed that the nation I was watching kept building and (presumably) disbanding workers even when at war. By the end over 200 had been built, but only 10 were in existence.

Keep up the good work!
 
Does BetterAI have gameplay changes ? First time I hear about it, except perhaps if it's about the gold overflow thing.
It a few minor game mechanics changes. Off the top of my head, the air-to-air combat formula has been rewritten in a way that makes air-strength more valuable, so for example, jet fighters are less likely to be shot down by ordinary fighters; the research rate has been slowed down a bit for the later eras; and the (hidden) research rate modifier that you get for knowing other civs with a tech has been changed so that you get a bigger bonus with open borders and stuff like that. I'm not sure if there are any other changes, and I'm pretty sure the changes that I've mentioned can be disabled in the xml.

Oh. and it also has "lead from behind", which is a subtle game mechanics change. LFB changes the way the game chooses which unit will defend first when a stack is attacked. K-Mod has that feature as well, but I've heavily modified it – because in the original LFB code it was basically impossible to have a great general defender, or a medic defender.

Karadoc: Thank you for this excellent mod. It is a great improvement on the base game.

I tried 1.05 using autoplay and found it much faster than standard.

One small problem; I noticed that the nation I was watching kept building and (presumably) disbanding workers even when at war. By the end over 200 had been built, but only 10 were in existence.

Keep up the good work!
Thanks. :) I'm glad you're enjoying it.

About the worker problem though.. that sounds pretty bad.

I've looked through the conditions for when the AI will build / disband a worker, to try to find out the cause of the strange behaviour. I made some minor adjustments, but I didn't spot any serious problems. I've noticed that the AI is pretty reckless with their work boats. Sometimes it will build a fishing boat somewhere that obviously is going to get pillaged by barbarians... and then when it is pillaged, they build another one and do the same thing. :( I've been meaning to try to fix that -- but I've never seen them suicide their workers. Maybe the AI isn't really building lots of workers, but there is a bug in the units-built counter or something like that. Anyway, I've tightened the conditions on deleting workers, and I've decreased the probability of building new workers when they have almost enough already... hopefully that will fix the problem.

I have fixed a bunch of bugs since releasing v1.05 - some of them can cause the game to crash - but I think it would be pretty weird if it caused the AI to mess up their workers.



Lenowill, I checked out the savegame that you posted. I think Cyrus was kind of struggling because he was paying too much maintenance. His total expenses were around 2200 per turn. He was running 50% :gold: just to break even. (and 50% :culture: because he was going for a cultural victory.) I really think he would have been better off if he'd split his empire. ie. liberated a colony. -- So I've revisited the AI's colony decision making code yet again and changed a few things. I've changed that code stacks of times - I guess it's just hard to find a calculation which covers all strategies. With the new code, he still doesn't want to create a colony... but I think it will work a bit better in other games.

He may well have waved in his decision to go for a cultural victory. What probably happened was that he was going for culture, but then decided that he might be better off going for some other kind of victory -- and then switched back to culture when it became apparent that culture was going to be easier. It was probably a strategical error on his part... but I think I can forgive him. After all, choice of victory strategy and stuff like that depends on the AI's personalities and such, and sometimes their personal preference for peace or war or whatnot can make them overlook better strategies. :)
 
Man I created a really long post, then went to submit it, and it erased my post and told me to relog in. Really made me angry.

On emperor difficulty, with k mod...

Sigh, ok

-So I turn off goody huts (ai eats them alive and gets too much early advantage on top of what it normally gets),

-events seems geared towards punishing you (if you join a war between two ais, sometimes a peace events will occur between them and youll be left to 1v1 for yourself or a road will be cut the disconnects your only source of copper at the worst time).

- Barbarians seem to have a code where an axe man or spearman spawns really close to your empire at a certain turn- when you have alot of land to expand to. Wouldnt be a terrible idea for balance, except it is way, way before you could possibly hook up your own bronze/copper.

-I turn off tech trading because the pace of the game whizzes by too fast with it on.

- If I play continents, then an ai on the other continent conquers the rest of his neighbors, way before I can even find out about it and ends up a age ahead of me and almost 100% of the wonders.

So I play 4 teams of 2 (you get a buddy ai), Pangea, emperor, no tech trading or barbs or goody huts or events.

Naval invasion ai still seems underused, poorly executed. Also the invasion ai where if your ally is landlocked behind you, that they have to cross your land to get to the enemy, seems rather disorganized/slow to respond, even if you ask for them to invade a certain city. I wonder if you are thinking about improving those aspects of the ai.

But great mod, and glad your very active. 10/10 rating imo :D

I actually love the fact that the ai is able to take some of my cities, although it still does a sub par job of protecting its newly conquered cities. Does the ai have an ability to realize the war has turned and its starting to lose the war, so it should become more defensive.

Ai took one of my cities, left 3 or 4 units in the city, moved on to the next city, couldnt take it- then kinda hovered there until it was out numbered and eventually destroyed.

In another situation, Spanish were slowly losing cities, and for about half the war, Spain kept a decent sized stack of knights in my allies lands which they were at war with (alot of which were wounded). I dont know if its better for the ai to have the stack in my allies lands on a hill, as a distraction, or whether it would be better if that knight stack were used to destroy my allies's invading stacks.

Ai also doesnt use catapults or seige equipment defensively- it keeps them in the city, yes, but it doesnt attack the stack outside the city, to stop them from taking the city. Ive run into alot of situations where the ai is building up, reorganizing forces, and I have a stack outside a city, and if they would just attack me with the 3 or 4 catapults inside, they could probably live long enough to force me back out of their lands- saving their city.

LoL also, Id love to see an enemy civ mass draft troops (in peace time and in war). Seems like once I get nationalism and mass draft, then the ai is really at a disadvantage or, I should say, an even field.

Edit: one last thing, I dont really ever "feel" a navy is really necessary unless Im invading islands or another continent.Maybe one or two ships to protect crabs or a whale resource for most of the time. Perhaps the Ai could keep a larger navy (complete with production cheats if need be) and use their navy more forcefully in blockaging your coastal cities during wartime, even if its mostly a land battle? Im not very knowledge in mods to forgive me if I seem to mentition too many things.

Like I said 10/10. I actually enjoy losing the first 4 or 5 times I played this mod. Like a elaborate puzzle.
 
Back
Top Bottom