Holos Dev Diary: getting around integer restraints for random seeds

Posted by
Most of the generation in Holos is based on coordinates. For example the terrain is built with Perlin Noise (x and y are input), town and dungeon locations are based on another formula that takes x and y as input. All these formulas break at some point, when x or y get too large to handle by PHP. However I don’t have to worry about that, because on my server that number is between 10^102 and 10^103. For town name generation however, I rely on a random seed, which has to be an integer (max 2,147,483,647 or roughly 2*10^9). And because I didn’t find a better formula yet, it is: abs($x) . abs($y). Why concatenation? Because both addition and multiplication can easily produce the same seed multiple times – which is bad. For example 110,100 and 100,110 would produce identical seeds. The worst about this is that towns very close to each other would have a decent chance of getting the same name. So in my system, on coordinates (110,100), the seed is 110100 and on (100,110) it is 100110. Two completely different numbers, nice and easy. Except that it doesn’t work for very long: coordinates like (22000,12000) are definitely achievable by any player, which would result in the seed 2,200,012,000 – that exceeds the integer maximum already. I learned this while playtesting, noticing all towns had exactly the same name – PHP simply treated numbers larger than Int-maximum as 0 and took that as seed all the time. Because I’m a fan of modulo I thought using (abs($x) . abs($y)) % PHP_INT_MAX was a good idea (basically simulating an integer overflow). But this kept returning 0 as well. The final solution was to use fmod() (floating point modulo). The complete line for setting my random seed for town names now looks like this, and it works like a charm: mt_srand((int)(fmod((abs($x) . abs($y)), PHP_INT_MAX)));

Leave a Reply