Excellent! Exactly the test i was thinking about myself, except it'd take me ages to code it - nowadays. Thanks!!... I've run a little Python script (written mostly by a chat AI and relying on the Pythonrandom
module for the PRNG) that starts with a grid of 8x8 "X"s and then successively chooses one at random and flips it to a blank character – until exactly half of the Xs are gone. Here are six of those half-cleared grids:The fifth, for example, has a big (3x5) cleared block in the middle. Several of them have long portions of the outer edge left untouched. Your screenshot doesn't blatantly fall out of this pattern to my eye.Spoiler :Code:X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
Edit3: Let's also go from Chess to a Go-sized grid ...Spoiler :Code:X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
There is certainly one kink in the syncRandPlot function: It does not first collect all valid tiles and then choose one at random, but it chooses a random coordinate ignoring all selection criteria, checks the criteria and tries again until it happens to pick a valid tile – or until it has failed 100 times. That's the iTimeout default value defined in CvMap.h. Once the number of valid tiles becomes very small, especially on very large maps, it may well happen that the timeout is reached before finding any nondesert, noncity land tile. But this should only affect the (very) late stages of GW. It might explain the surprisingly abrupt flattening of the descending crop yield curve that I've observed in my automated test. This timeout mechanism could also be an intentional design decision (rather than just an attempt to save processing time) to generally allow per-tile events to get canceled that can only affect a very narrow set of tiles. Ensures a degree of unpredictability. After rewriting syncRandPlot in my own mod (so that a tile is guaranteed to be found), I ran into the problem that Barbarians kept respawning too rapidly where they had just been killed when very few eligible tiles were left.
Edit2: The GameCore code may also be in your own Civ 4 install folder, in a subfolder CvGameCoreDLL. But I'm not sure if all editions of the game come with the source code. So (maybe) I don't need to be relied on for providing the source code in its correct version. The game updaters, e.g. for v1.74, also used to include the (presumably) latest version of the source code and (presumably) replaced any older existing version of the code with the latest when applying the update.
Good news are: you and me don't need to "compare by eyeballing" your results and my screenshot. We can simply quantify the difference. Oh, but before i do - can't see that "big (3x5) cleared block in the middle" in your 5th pattern. Looked 4 times. Real hard. Just ain't there. Am i that blind today?
Anyhow, to quantify it, lots of methods are possible. Here's one
Spoiler example :
- count how many desert tiles are on my 1st screenshot, except any desert tiles 6 or more distance to the east from Delhi (because few natural-desert tiles were 7 tiles eastwards and further, and we only estimate GW-made deserts, including GW effect on their nearby tiles, hence 6th eastwards tile column is excluded, but still matter as "neighbours" to 5th eastwards tile column). My eyes counted 26 such desert tiles;
- count how many of those 26 desert tiles have half or more of adjucent land non-city tiles - also being deserts. My eyes counted 25 such desert tiles. This gives us "percentage of desert tiles not far from Delhi who love to hang out with other desert tiles", so to say: 25 / 26 = 96.2%. Kinda stunning, ain't it?
- count how many non-desert non-city tiles are in the same area. My eyes counted 18. This gives us "desertification %" for this area: 26 / (26 + 18) = 59.1%. Significantly different than 50% you used in your script, so it'd be best to run it with
something close to 59.1% of symbols removed;
- then count how many of blank symbols in your tests have half or more of adjucent places also being blank. If it'd be anywhere close to 96.2% on multiple attempts - then your doubts are right, and my mind was seeing things; but if it's way lower than 96%, then it'd mean we're onto something indeed, here.
Here's that "5th pattern" you made, with blank spaces replaced by "O" symbols for better geometry in the post - 32 of those and 32 Xs indeed:
X O O O X X O X
X O O X O O O X
O X O O O X O X
X X O O X O X X
O X O O X X X O
O O X O O O X O
X X X O X O X X
O X X X X X O O
And when i count how many "Os" have half-or-more nearby (adjucent) symbols also being "Os" - then i get 16. Out of 32. Exactly 50% such "Os". Far, far less than 96%. Certainly, increasing desertification from 50% to 59% would ramp up the result way closer to 96%, but i guess it'd still be very, very small percentage of tests which by mere fluctuation would produce 96% or more of "buddy-buddy with likes of yourself" Os.
Next, about "intentional design decision ... to generally allow per-tile events to get canceled that can only affect a very narrow set of tiles". This strikes one properly technical revelation into me, man! A little tiny remnant of a tech i once was... Thanks for this!!
It goes: them Firaxis programmers at the time - were quite brilliant. Back in my (very) old coder's days (mainly in 1990s: Pascal and Delphi, i.e. the old strict-programming stuff), i definitely remember writing lots and lots of code which had "secondary purposes" built-in. I.e., things which happened as side effects from running the code which was doing some very different stuff. Akin to that "degree of unpredictability" you've mentioned. And now the fun part: such things, such "secondary effects" - hardly _any_ other coder than the code's author could even figure out from looking at the code. How i know? Well because other young fellas who were looking at my code - hardly noticed any such quirks. And they were good coders, yep. Such things, you only figure out how to do "as a bonus" after running your code this and that way and in a dozen different fashions and circumstances. And it's occasional stuff, too: sometimes it's possible to alter the code to produce such "side benefits", but rather more often - it's not doable. But, such opportunities are not exactly "rare", too. There can be a ton of such things in a program of Civ4 scale, i believe. And, those "little nice extras" are rarely even commented by coders who do have the old honorable habit of commenting their own code - and, of course, lots of coders, even good ones, don't have time for even properly commenting the main ideas their stuff does... %)
Why is that a revelation, here? Because i recognise just-described manner of coding - a bit - in how you described that function's workings, and because any good coder who'd do "how GW works in Civ4" would likely fancy the idea that "any already-existing deserts, naturally, should be expanding overall quite faster than the speed of GW in regions with no deserts at all". And if they would indeed fancy this idea, and then see a way to implement it as such a "nice extra", a little extra feature of their code which is functioning as a far-not-obvious side effect - then, i'm sure, they would. At least, i would, in their shoes. It'd simply be _elegant_, you know?
And about that folder: nope, no such folder in my vanilla Civ4 installation. There is such a folder in my BtS installation alright, but not in vanilla.
// edits: fixing typos
Last edited: