K-Mod: Far Beyond the Sword

I could use C, though something easier might be better if we can find it.

Although, I'm not up-and-up on what all of the existing keyboard shortcuts do. What would be overlapped if you made the suppressor be Ctrl or Alt?

(Is one of those used for push to talk Voice chatting ingame for multiplayer? I know Space is cycle unit and Shift is used to queue commands.)

EDIT: Actually, thinking about it, C might be better for me than I thought. Anyway, we should look at options I guess.
 
Add a clickable button next to Filed of View slider ingame?
 
There's the Pendragon + K-Mod mod, but the dll hasn't been updated in a while (should be a drag and drop though). But that's only for if you like the Pendragon book series by D.J. MacHale
 
Regarding this cycling-suppressor key; one of the tricky things about reusing a button like 'c' or ctrl is that I have to find some way to disable the existing functionality. That's often not an easy thing to do, because a lot of the control are implemented inside the .exe, and so aren't accessible for modding. Sometimes it's possible to 'intercept' the command to stop it before it takes effects, but that can cause other problems. (For example, to change double-click from "select all" to "wake all", I basically changed the game so that whenever anything tried to use select all, it would instead wake all - and then I changed everything I could find to use a slightly different method of selecting all. So, double-click still does the same thing in the exe, but I've hijacked the old select all code to do what I want.

Anyway, the crux of the matter is that for any given key, it may or may not be easy to disable the original functionality. I suspect <ctrl> might be easier than 'c'; but I haven't looked into it yet.

By the way, 'c' does not have the same functionality as <enter>. <enter> apparently cycles through units, just like 'w', but also, if all your units have been moved, <enter> will end the turn. Meanwhile, 'c' doesn't cycle through units nor end the turn. It just centers the screen on whichever unit is currently selected.

Holding <ctrl> while issuing a move order will automatically select all units of the same type, and then do the move order. I don't like that functionality, and I never use it - but I'm still reluctant to change it because I don't want to mess it up for anyone who actually does use it. (I often use <ctrl> when selecting units, to select all units of the same type; but I only do this when explicitly selecting units. ie. clicking the plot, or clicking the unit icon at the bottom of the screen. I never use <ctrl> when actually issuing a move order - and that's the only thing we're talking about possibly changing.)

I'm thinking about putting a poll on the general forum to ask if anyone uses ctrl in this way. (Such a poll would need to be very carefully worded so that people would understand the subtle distinction between explicit select-all and the implicit select-all before they answered the question. Most people probably wouldn't know the implicit select-all functionality even existed, and so they'd assume I was taking about the explicit thing.)

I love every single change of patch 1.30
Good! :) By the way, I'm pretty sure that the peace treaty alert problem that you mentioned is also fixed. I didn't put it in the changelog because I didn't actually test it properly, but my guess is that the problem was caused by BUG not having accurate info about when leaders "refuse to talk"; and so by restoring the "!" thing on the scoreboard, I expect that the peace treaty problem is probably fixed as well.


--

A few versions back, I made some change to the tech rate of the barbarians. How's that going for everyone? I've been pretty happy with it in the games I've played. The barbarians are now a bit less likely to get axemen before the real civs get them; but they are still pretty fast; and seems to me that they longbows at a decent time, and so on. But I haven't been monitoring it very closely, so I'd be interested to hear other feedback if anyone has noticed any differences.
 
Good! :) By the way, I'm pretty sure that the peace treaty alert problem that you mentioned is also fixed. I didn't put it in the changelog because I didn't actually test it properly, but my guess is that the problem was caused by BUG not having accurate info about when leaders "refuse to talk"; and so by restoring the "!" thing on the scoreboard, I expect that the peace treaty problem is probably fixed as well.


--

A few versions back, I made some change to the tech rate of the barbarians. How's that going for everyone? I've been pretty happy with it in the games I've played. The barbarians are now a bit less likely to get axemen before the real civs get them; but they are still pretty fast; and seems to me that they longbows at a decent time, and so on. But I haven't been monitoring it very closely, so I'd be interested to hear other feedback if anyone has noticed any differences.


Yes the peace bug is finally Fixed ;)

About barbarian, when we have riflemen and send ships to colonize the new world, barbs always are 1 era behind and sometimes 2 eras (in prince/noble difficulty). That's a proper difference imho, also i like playing with raging barbs, so before riflemen it is very hard to enstablish a safe colony. Also love that, simulates the native tribes :lol:

About the "!" alerting the non disposition to talk of AIs, i've seen you added it in the diplomacy advisor, but i also meant adding it in the scoreboard which still misses it, it should be near the "crossed swords" simbol when at war, or just before the name when at peace. Would be good to add it there as well for more intuitive diplomacy management!

Well done with the updates, you are taking huge efforts to really improve the game like no other mod did so far while preserving (actually improving) stability, performance, balance and lore :goodjob:
 
The "!" is available for the scoreboard, and it is enabled by default - but since you've played previous versions of K-Mod, the K-Mod settings you have saved will not have the "!" enabled. You can fix it by either completely deleting your K-Mod settings (in "My Games\Beyond the Sword\K-Mod"), or by just changing the scoreboard string in the BUG options screen. Just put a "!" at the start of the scoreboard order string. (The current default is this: "!?2WSZVC6EPTUNBDRAHQ*LO".)
 
The "!" is available for the scoreboard, and it is enabled by default - but since you've played previous versions of K-Mod, the K-Mod settings you have saved will not have the "!" enabled. You can fix it by either completely deleting your K-Mod settings (in "My Games\Beyond the Sword\K-Mod"), or by just changing the scoreboard string in the BUG options screen. Just put a "!" at the start of the scoreboard order string. (The current default is this: "!?2WSZVC6EPTUNBDRAHQ*LO".)


thanks, didn't notice that :lol:
 
karadoc, quick question.
i was thinking of merging some stuff with kmod for my own use and was just wondering about interfaceDirtyBits.inl. it's just about the only sdk file you don't include in your source and i was wondering was there a specific reason for it not being there or can i/should i include the stock file in my build anyway?
 
karadoc,

Thank you for the Kmod, it seems good. The one thing I really miss from BAT 3.0 (not sure if it is BUG) is the ability to have workers pre-chop by default. Any chance of implementing this?

In my game, I found some questionable AI behavior. Note that there is a fort on the silk instead of a plantation (I checked Toku has Calendar).

Spoiler :

Fort0000.jpg


(The pigs are unimproved, because they were recentlly pillaged)
 
karadoc,

Thank you for the Kmod, it seems good. The one thing I really miss from BAT 3.0 (not sure if it is BUG) is the ability to have workers pre-chop by default. Any chance of implementing this?

In my game, I found some questionable AI behavior. Note that there is a fort on the silk instead of a plantation (I checked Toku has Calendar).

Spoiler :

Fort0000.jpg


(The pigs are unimproved, because they were recentlly pillaged)


Did you install Blue Marble textures? if so, how?? ::mischief:
 
karadoc,

Thank you for the Kmod, it seems good. The one thing I really miss from BAT 3.0 (not sure if it is BUG) is the ability to have workers pre-chop by default. Any chance of implementing this?

In my game, I found some questionable AI behavior. Note that there is a fort on the silk instead of a plantation (I checked Toku has Calendar).

Tokugawa may have chosen to use a fort rather than a plantation because he wants the +1:hammers: from the forest more than the +3:commerce: from the plantation. You might notice he is also using watermills rather than cottages, so apparently he wants that city to be focused on productivity. Maybe later he'll decide to go for the plantation later, but I don't think it's a bug.

As for the pre-chop BULL option: someone asked about that some time ago, and I think I disappointed them by saying that I didn't intend to work on it in the near future. I probably should include it one day; but it's a bit of a pest because the implementation that BULL uses is not multiplayer compatible. ie. it will cause OOS errors. So, I'd have to design some other implementation before I add it. It certainly can be done, but the other thing is that I don't really like the feature anyway. I'd never use it myself; and although I can see that it is certainly useful for some people, I feel like the feature is kind of 'ugly'... ... ... Look, the upshot is that I'll probably add it one day, but I'm not in any hurry to do so. I'm just not feeling the motivation to work on that particular feature. I'd rather work on other stuff. I'm sorry about that.

[edit]
I just started a kind of "todo list" (here), and I put the pre-chop thing on the list just to remind me about it if I can't think of something cooler to do. ;)
You guys are free to post your own stuff on that list as well if you'd like. (although I can't guarantee I'll ever look at it...)
 
[edit]
I just started a kind of "todo list" (here), and I put the pre-chop thing on the list just to remind me about it if I can't think of something cooler to do. ;)
You guys are free to post your own stuff on that list as well if you'd like. (although I can't guarantee I'll ever look at it...)


LOL, the war request thing is something i was going to suggest and i've noticed its already in the todo list. Amazing :cool:

I think you should focuse on refining/improving the diplomacy aspect, and some UI issues. With the better AI K-Mod introduces, we need a deeper diplomacy indeed, but you should add the same options also for the AI: why player can ask the AI to attack a specific city or to prepare a war, but the AI will not make such a request as well?

The thing i like with k-mod, is that your philosophy is very resolute and polished, you will never add something just for the sake of content.
 
An easy way to make the promotion more distinctive would be to give it a different background color, red for example.

Agreed on this. Just like the HA in Warlords had -10% against city, it should red as a negative modifier.


Oops. Too late.
 
Fibonacci1123:
In my game, I found some questionable AI behavior. Note that there is a fort on the silk instead of a plantation (I checked Toku has Calendar).

karadoc
Tokugawa may have chosen to use a fort rather than a plantation because he wants the +1:hammers: from the forest more than the +3:commerce: from the plantation. You might notice he is also using watermills rather than cottages, so apparently he wants that city to be focused on productivity. Maybe later he'll decide to go for the plantation later, but I don't think it's a bug.

You are right he seems to have decided it is a production center. Wow! a reasoned decision by an AI. Well done sir :goodjob:. I am not sure I agree with the decision (part of why I took the city was to stop AI mismanagement ;)), but I am proud of Toku for making it.
 
I would certainly use the pre-chop option if it was implemented. If nothing else, I'd use it in single player fairly often. I like to pre-chop.

In the event that you can't find a graceful way to implement it, there's always the option of including the option anyway and leaving a note on it that it can cause OOS in multiplayer.
 
@sjodster, I'd be happy enough to talk about the pathfinder sometime...

At first I was very surprised to see that you replaced the built-in pathfinder with your own (for some functions anyway). I guess I've always just assumed that Firaxis did a good job with their implementation, and it's a lot of work to implement A* and get it both correct and fast, so I was intrigued to see that you had taken on this work. Of course, we don't have the code for the built-in version that's tucked away in the game core so it's hard to say "yeah that code could be improved". What was it that led you to think "huh, maybe I should rewrite this thing"?

I assume that you have somehow compared the performance of the built-in pathfinder with your own; what have you found in terms of performance gain? Do you have a good method of benchmarking the pathfinding code?

+1 for using the STL :)

If I understand your code correctly, it looks like you are using a hash table (node_map) to find adjacent FAStarNodes. Even though it's theoretically O(1), that hash table must have some cost. Couldn't we pre-allocate an array of FAStarNode*[mapWidth * mapHeight] and find the nodes by looking them up in the array by plot index? Do you see any drawbacks to such a change?

Are you able to successfully reuse the cached path across multiple calls to GeneratePath? If so, are you completely confident that the cache isn't stale when it is reused? It looks like it verifies that it's the same group/settings and destination, but what if other conditions change (units get promoted or an enemy steps on the path)? I think you've got a whole system for handling resets though, so you might acount for this outside of the pathfinder itself.

A small amount of staleness or inaccuracy in the pathfinder may be acceptable if it brings great gains in speed and the inaccuracies are minor over large distances. Also, it might not be worth worrying about changing conditions that are 20 moves away.

Have you thought about replacing FAStarNode with your own implementation? Does anything in the game core prevent us from using our own class/struct?

Have you read Patrick Lester's excellent articles on pathfinding? (you probably have but I figured I'd ask to make sure)
http://www.policyalmanac.org/games/aStarTutorial.htm
http://www.policyalmanac.org/games/twoTiered.htm
http://www.policyalmanac.org/games/binaryHeaps.htm

What do you think about using a binary heap or D-heap for the open list instead of a linked list? Inserts would be more expense, O(log n) instead of O(1), but the search for the best node would be O(1) instead of O(N).

A heap would also save a bunch of mallocs and theoretically it would make better use of the CPU's memory cache. It could be allocated in one shot when the pathfinder is initialized.

The STL has a binary heap implementation (make_heap, push_heap, etc.), and there is also this thing for D-heaps: https://github.com/valyala/gheap

What do you think about implementing a two or three tier path finder? I am kind of boggled by the thought. On large maps it would really help to break the problem down into chunks. Theoretically it would be great, but getting the heuristics right for the larger chunks could be a nightmare. If the hueristics could be pre-computed to some extent that would be very helpful (ie this chunk has water, this chunk has mountains). Then the real problem would be changing conditions. Hrm, it sounds rather complicated...

Anyway, I look forward to your thoughts.

-Josh
 
The main reason I wrote my own pathfinder was speed. The original pathfinder was taking up about one third of the total AI turn time, and so I figured that it was the area that I should focus on the speed things up. I don't think there was anything majorly wrong with the original pathfinder; but the thing is, I knew it was taking up a lot of time, and I had no way of understand what all that time was being used for. I don't think the pathfinder was intrinsically slow; but rather it was just very hard for me to tell how it should be used to get the best performance. With my rewritten version it is easier to use it in a way that doesn't slow things down. The main big advantage of my pathfinder is that it is possible to set a maximum path length after which the pathfinder will stop looking. In the original pathfinder, even if you just want to know if you could get somewhere in 1 move, it would search the entire map just to tell you that you can't get there at all. Also, with my pathfinder I have finer control over when it should reset, and when it shouldn't. For example, in CvUnitAI::AI_load I create a new pathfinder instance to use for the boat so that I don't have to clear path results we've already found for the unit itself. That way, the unit can use the unit's cache, and the boat can use its own, new, cache. That's the type of stuff which gives the new pathfinder its speed increase. Aside from those type of things, I don't think the core of the new pathfinder is actually a bit improvement. The current pathfinder uses around 1/9 of the turn time (as opposed to 1/3). (To measure that, I'm just using the in-game profiler thing; with various functions flagged with PROFILE_FUNC().) But as I said, I suspect most of that speed improvement actually comes from better use of the pathfinder rather than from improvements in the pathfinder itself.

I've always just assumed that Firaxis did a good job with their implementation...
I use to assume that as well. I don't anymore. There's a heap of Firaxis code in the game which is complete trash. And I don't just mean poor AI or whatever, I mean poor programming. A couple of examples that come to mind are the original implementation of CvUnit::planBattle, which worked by trying random combinations of combat events until it found one with the correct end conditions (ie. the correct team winning the battle with the correct amount of sub-units left.) And the implementation of anything which involved sorting a list, which they always did it by looping through the list to find the smallest (or largest) element, extracting that to put in the new list, and repeating that process until they've done the whole list - kind of like an inside-out version of insertion-sort. Those kinds of things are not good...

Sometimes I think Firaxis programmers must have been paid per-line or something. I just don't know why else they'd want to nest so many if statements and so on. ... Anyway, the crux is that I no longer assume that the original Firaxis code is good.


Are you able to successfully reuse the cached path across multiple calls to GeneratePath? If so, are you completely confident that the cache isn't stale when it is reused?
[...]
Have you thought about replacing FAStarNode with your own implementation? Does anything in the game core prevent us from using our own class/struct?
One tricky / annoying thing about making this new pathfinder is that it does not replace the pathfinder used by the UI. (ie. the paths that are highlighted when the human player is trying to issue a move command.) As far as I can tell, it isn't possible to use my new pathfinder for the UI, because that's handled somewhere inside the .exe. -- So, because of that, the new pathfinder had to be programmed so that it gives exactly the same results as the original pathfinder; so that the path shown by the UI will accurate represent the path that the unit actually uses when ordered to move. (There are still some rare cases where the unit doesn't go where it said it was going to go; but that isn't my fault, believe it or not; that's a separate problem.) So, that's basically the reason why I'm using the same FAStarNode structure - it's allows me to share code between the UI pathfinder and my pathfinder.

As for reusing cache; absolutely yes. That's a core part of getting good performance from the pathfinder. You're right that I don't check for every possible way the cache could become invalid; but I'm pretty confident that it works correctly anyway, because:
  • The cache is not used for the actual move itself. That's done using an isolated instance of the pathfinder. (See CvSelectionGroup::groupPathTo).
  • The UI doesn't use my pathfinder anyway, and so any bad-cache problems you might see on the screen are not the fault of my pathfinder anyway.
  • No game events can take place during the AI's decision making process. So nothing can move or whatever to block the AI's path while it is still using its cache.
That said though, the cache clearing system is not rock-solid. There could potentially be some obscure cases which cause the AI to reuse an invalid path which I haven't thought of; but hopefully that kind of stuff will be picked up by asserts in debug mode or something. (For example, originally the pathfinder was not cleared when the AI declared war - but some combinations of defensive pacts and so forth would confuse the AI into trying to move somewhere it wasn't allowed to go anymore... that was picked up in debug mode, and thus fixed.)

If I understand your code correctly, it looks like you are using a hash table (node_map) to find adjacent FAStarNodes. Even though it's theoretically O(1), that hash table must have some cost. Couldn't we pre-allocate an array of FAStarNode*[mapWidth * mapHeight] and find the nodes by looking them up in the array by plot index? Do you see any drawbacks to such a change?
That sounds fine; and it would probably be a bit faster. It would use more memory though. In particular, the memory usage would scale badly on big maps. (But there are many many things in this game that scale badly on big maps...) I'm not really sure how much the hash function costs, but I expect it would be pretty cheap.

What do you think about using a binary heap or D-heap for the open list instead of a linked list? Inserts would be more expense, O(log n) instead of O(1), but the search for the best node would be O(1) instead of O(N).
I reckon that would probably be worth doing. I was originally going to try to speed up the open list search thing, but I decided to just leave the pathfinder alone for awhile to work on other stuff, because I was already satisfied with the speed of the pathfinder. But I do think there are probably some decent gains to be made with something like that. (Although, I dont' know what a D-heap is! :blush:)

What do you think about implementing a two or three tier path finder? I am kind of boggled by the thought. On large maps it would really help to break the problem down into chunks. Theoretically it would be great, but getting the heuristics right for the larger chunks could be a nightmare. If the hueristics could be pre-computed to some extent that would be very helpful (ie this chunk has water, this chunk has mountains). Then the real problem would be changing conditions. Hrm, it sounds rather complicated...
Yeah, I don't think we need that. I don't think even the very biggest civ4 maps are big enough for a two-tier system to make a significant speed improvement. ('Huge' maps are around 128x80; which is significantly smaller than the examples they were talking about in Patrick's tutorial.) I'm sure it would make it faster, but I don't think it would help so much that it would be worth spending a day of programming on.


[edit]
It just occurred to me what a "d-heap" is. I don't know why it sounded so foreign a few minutes ago... :crazyeye:

By the way, I hadn't read those articles. The first one looks familiar; so might have read that some time ago, but I'm pretty sure I haven't seen the others before. I don't actually remember how I learnt about A* in the first place.
 
Back
Top Bottom