Does anyone know how MoO1 calculates distances between stars?
My own reverse engineering efforts (starmap-offs 0x227cd, adr 0x1eed:0xfd for those who must know :-) brought the following (essentially an average between maximum norm and the L1 Manhattan Distance Metric):
Code:
int pdist_tenths(int i,int j) {
int x=abs(planet[i].xpos-planet[j].xpos);
int y=abs(planet[i].ypos-planet[j].ypos);
return max(x,y)+(min(x,y)>>1);
}
It is however unclear to me, how these values are converted (rounded) to parsec-distances. In the current RBO39 e.g. we have
and thus pdist_tenths(Kakata,Vulcan) = 65 and pdist_tenths(Reticuli,Vulcan) = 55, however in-game, the parsec distances are 7 pc and 5 pc. Does it do round-to-odd? Or does it use a completely different method? Any ideas?
It might be using the reverse of the non-biased rounding rule: round to the nearest whole number, if at .5, round to the even.
Merovech's Mapmaking Guidelines:
0. Player Requests: The player's requests take precedence, even if they contradict the following guidelines.
1. Balance: The map must be balanced, both in regards to land quality and availability and in regards to special civilization features. A map may be wonderfully unique and surprising, but, if it is unbalanced, the game will suffer and the player's enjoyment will not be as high as it could be.
2. Identity and Enjoyment: The map should be interesting to play at all levels, from city placement and management to the border-created interactions between civilizations, and should include varied terrain. Flavor should enhance the inherent pleasure resulting from the underlying tile arrangements. The map should not be exceedingly lush, but it is better to err on the lush side than on the poor side when placing terrain.
3. Feel (Avoiding Gimmicks): The map should not be overwhelmed or dominated by the mapmaker's flavor. Embellishment of the map through the use of special improvements, barbarian units, and abnormal terrain can enhance the identity and enjoyment of the map, but should take a backseat to the more normal aspects of the map. The game should usually not revolve around the flavor, but merely be accented by it.
4. Realism: Where possible, the terrain of the map should be realistic. Jungles on desert tiles, or even next to desert tiles, should therefore have a very specific reason for existing. Rivers should run downhill or across level ground into bodies of water. Irrigated terrain should have a higher grassland to plains ratio than dry terrain. Mountain chains should cast rain shadows. Islands, mountains, and peninsulas should follow logical plate tectonics.
It might be using the reverse of the non-biased rounding rule
Well, this would be round-to-odd. But not, the truth is much much more horrible ...
@Vanshilar
Thanks for the link. This was most helpful, esp. kyrub's hint. I've already found the routine he spoke of (starmap.exe:0xd4d6) but for reasons that will become clear very soon, I refused to believe that this was part of the core game mechanics, but considered it an (extremely poorly written) part of the fleet-movement animation code.
What they do: they call a version atan2 (yes, that's arcus tangent - a trancendental function, about the most expensive stuff you can come up with, even if you don't implement it with a braindead sequential reverse lookup in a tangent table) and then compute sine and cosine (again with sign handling and table lookup) - and all this, just to normalize a fscking vector! And they don't do it once - they do it for every warp factor - twice! Once with length 5 and once with lenght 6, the components of which get rounded down for all values except 0°, 90°, 180° and 270°, which doubles the error and explains the 11 vs. 9 starlane effect.
But somehow they managed to still get it wrong. I logged all actual fleet movements which happed during my RBO39 game and noted some really strange things:
Code:
dx dy x y x/y y/x
+6 -7 8 -9 0.8889 1.1250
-7 -7 -17 -19 0.8947 1.1176
-6 -7 -9 -10 0.9000 1.1111
-7 -7 -22 -24 0.9167 1.0909
the x,y are the coord. of the target planet and dx,dy is the resulting warp1 movement. As you can see the steepness dy/dx of the movement is not even monotonic.
kyrub, if you are reading this, maybe you could have a look at the following piece of code in starmap.exe:
Hmm I don't have a background in coding but...maybe they were pretty enamored with math regardless of the computation after all, sin(arctan x) = x/sqrt(1+x^2) etc. -- there's a variety of trigonometric relationships that you can use there (from wikipedia). I wouldn't be surprised if they had some weird math going on though; when I was looking into combat damage here, I got some weird results too (although Zygot might be right that they calculate in tenths of a HP even if they only display full HP values).
Well, the best way for a game of this era and comp. speed would have been to stick with the non-Euklidian (L_1+L_inf)/2 metric and use it consistently for all distance computations. Anyway, I solved the problem in the meantime using the game internal tanget-table to come up with a numerically exact algorithm. Here is the code, in case anyone is interested:
Code:
bool move_parsec(int& x,int &y) {
int rx=abs(x),ry=abs(y);
if(rx>255||ry>255) { rx>>=1; ry>>=1; }
int dx=0,dy=0;
I've tested the code with some 8000+ fleet movements form 6 different games and it seems to work. I'm not sure, however, if this also gives the same results for all player relevant game-internal distance and reachability computations.