Overview
In this tutorial we'll be taking a look at how we can create a 3D terrain from the aion online game files.
What is a terrain mesh?
What is a terrain mesh in Aion?
A terrain mesh in aion is a flat plane of points stitched together with polygons. each vertex is adjusted to resemble mountains, peaks, hills, ponds and more. Check out the picture below for an example.
Where are the terrain files located?
In your Aion folder there is a Levels folder, within the Levels folder there are many other folders representing each level within the game.
Here are some of the folder names and the what maps they represent:
- dc1 - pandamonium(main)
- dc2 - rest of pandamonium
- df1 - ishalgan (asmo starting map)
- df1a - altgard (asmo)
- df2 - morheim (asmo)
- lc1 - sanctum (elyos)
- lf1 - poeta (elyos starting map)
- lf1a - verteron (elyos)
- lf2 - eltnen (elyos)
- lf3 - heiron (elyos)
- tiamat_down - tiamat ring (contested)
- ab1 - abyss(upper, lower and core)
Pick a folder, inside you will find a level.pak file, this is an archive file specific to the cryengine. You can extract this using an extractor tool, Ragezone downloads section might have one or you can google one and download it.
You should have these files and folders once the pak is extracted.


You only need to focus on the terrain folder for this tutorial. Inside you will find a file called land_map.h32 this is the file that has all of the terrain mesh data in it specific to the level you choose.
CryEngine coordinate system.
Before we dive into the code, I want to touch on the coordinate system used in the CryEngine.
CryEngine is the engine that aion was made in and NCSOFT didn't change the world coordinates.
The default cryengine world coordinates have z pointing upwards as apposed to the traditional y coordinate we're used to seeing. When we look at the code, we will understand why z is in the typical y position for the vector3 going upwards.

You can read more about the coordinate system here: https://docs.cryengine.com/display/C...dinate+Systems
Code implementation.
I wasn't sure which language to program this in at the time, eventually I went with python as it's easy for newcomers and I want this to be as simple as possible to understand. Full code is uploaded on my github page.
First we want to import two libraries, os for getting the file size in bytes and math for the square root function.
Then we get the file size in bytes. this is used to determine how many polygons to render and how wide the map is.
Code:
#file size in bytes.
FILE_SIZE = os.path.getsize("land_map.h32")
After this we open the file in read bytes mode, calculate how many polygons there are and setup placeholders for x and "y" coordinates.
Code:
#open land_map.h32 in read bytes mode.
f = open("land_map.h32", "rb")
#total polygons
w = math.sqrt(FILE_SIZE / 3)
#x and y coordinates.
x = 0
y = 0
Here we loop through the file, incrementing by 3 bytes. the first two bytes are combined into an int16 and divided by 32 to give us the new height value of that vertex. The byte order is little endian, opposite of network byte order of big endian.
Read more about endianess here: https://en.wikipedia.org/wiki/Endianness
The x coordinate is increased until it has reached the edge of the map where it is reset to 0.
The y is then increased by one to move to the next column.
It does this until the grid is complete.
Code:
#loop through each byte in the file.
for i in range(0,FILE_SIZE, 3):
#read each byte.
r1 = f.read(1)
r2 = f.read(1)
r3 = f.read(1)
#convert each byte into an int with little endianess.
b1 = int.from_bytes(r1, "little")
b2 = int.from_bytes(r2, "little")
b3 = int.from_bytes(r3, "little")
z = int.from_bytes([b1, b2], "little") / 32
#here are the final values you can use when rendering the vertices, we can see the z value is in the typical y position for the vector 3.
print("Vertex {index}: x={xpos}, z={zpos}, y={ypos}".format(index = i, xpos = x, zpos = z, ypos = y))
x = x + 1
#if x is equal to the edge of the map, reset x for the next row of polygons.
if x == w:
x = 0
y = y + 1
Closing thoughts.
That's all there is to rendering a terrain mesh for aion. Pretty cool huh? Some famous applications of this are geodata viewers or geo engines to detect collisions with mobs, attack through walls etc.. This is the first step to building that sort of system.
Below is what it looks like when you render these points in 3D space, it's a custom engine I'm building. The map is lshalgen, the asmodian starting area. I haven't rasterised the polygons, it consists of straight lines for now.
