The XL Engine is and will remain free, donations are purely optional but greatly appreciated.

As I was working on finishing the loading code, see the Missing Code topic for more information, I was able to verify a few things about the coordinate systems used in Daggerfall.

Each location has a unique position on the world map – which, as you already know, is 1000×500 pixels in size. Each “pixel” on this map is exactly 32768 Daggerfall units on each side. Given the height of the character, 75 Daggerfall units, the original estimate of 1 inch per unit seems accurate – making the character exactly 6 1/4 feet tall. Thus a pixel is 32768 inches x 32768 inches, making it 51.7% of a mile (832.3072 meters) on each side. Finally “map pixels” are split into 256 unit sub-tiles – meaning each pixel has 128×128, 256×256 unit subtiles – each being 21 1/3 feet on each size. When outside, these sub-tiles are the terrain chunks.

Daggerfall uses an interesting way to determine which locations are near the player. Given the world space coordinates of the player (X and Z), the map coordinates can be calculated as follows:

const int maxWorldSpaceZCoord = 16384000;

mapPosX = playerObj->xPosition / 32768;
mapPosZ = (maxWorldSpaceZCoord - playerObj->zPosition) / 32768;


Then, given the position on the map, an index is computed:

const int mapWidth = 1000;

mapIndex = mapPosZ * mapWidth + mapPosX;


This index corresponds directly to the location ID’s. In other words the location ID is actually it’s map position encoded as shown above. This also means that its map position could also be derived directly from its ID.

Note the code was taken from reverse engineered functions, I just decided to show code snippets this time for brevity. Also Daggerfall used shifts instead of divides, but the divides make the code much clearer for the purpose of showing here.

3 Responses to “Space in Daggerfall”

  • asd:

    will it be out this year?

  • daggerfalluser129:

    I don’t know if this holds true for x86, but wouldn’t that code on an unsigned int compile into fewer instructions than for a signed int? Or perhaps mapPosZ isn’t computed all that often, and/or it’s a tiny optimization?

    • luciusDXL:

      The position values are all signed integers in the code. The main reason is that, in Daggerfall, the “up” axis is -y, i.e. larger negative numbers are higher up. In addition, when computing deltas, you’ll oftentimes get negative values – which means the numbers involved in the computation should be signed.

      So all math on positions is done using signed integers.

      And the assembly, from what I remember, is something like (I don’t have the code open so I don’t remember the exact register names):
      neg r0
      add r0,r1
      shr r0,0F

      So making one of the numbers unsigned, I’m assuming you mean the constant, won’t help at all.

Leave a Reply

The XL Engine is and will remain free, donations are purely optional but greatly appreciated.