-
Notifications
You must be signed in to change notification settings - Fork 5
Anno Fileformats: Island Files
Island files consist of
- an .a7m file, which is an rda v2.2 archive containing two gamedata.data and rd3d.data that are both in filedb compression.
- chunk-meshes (.tmc) in filedb compression
- an .a7minfo file in filedb compression
- an .a7me file that is in xml.
- a .ctt file that contains heightmap data in multiple resolutions.
You may also be interested in this presentation by BlueByte which explains terrain rendering for Anno 2205:
RDA v2.2 Archive containing
- gamedata.data => data needed for ingame logic and interaction. Gamedata Interpreter
- rd3d.data => general 3d chunk data as well as prop locations (every single tree and bush i.e.)
RD3D Interpreter
Both of these files use filedb compression.
FileDB compressed file that contains a 3D chunk of an island. A 3D chunk is directly stored as vertex and index buffers. For Newcomers, here is a general tutorial on how this works: Microsoft Docs
CTT files contain Detail Height Maps. This file is a little harder to open.
- First, there are 8 magic bytes:
5F 42 54 54 4D B8 05 00 - Following that, there is a zlib compressed datablock using compression level 1
- After decompressing this part, you will end up with a filedb compressed file.
- CTT Interpreter
The data you get are heightmaps with miplevels:
- a downsampled image (lowest of all resolutions)
- multiple miplevels in higher resolutions that are quantized. Each of these miplevels gives you a ScaleFactor and QuantBits.
This still doesn't give you any usable image. Those are computed at runtime in the shader.
You can view the complete shader sourcecode for this in the game files (data1.rda) under data/shaders/fx/terrain_compress.fx
However, this is what happens in the shader:
-
Image Dequantizing (taken from the shader sourcecode):
// e.g. bits = 3 has value range (-4, 3) (two's complement) int totalRange = 1 << QuantBits; int halfRange = 1 << (QuantBits - 1); int minVal = -halfRange; int maxVal = halfRange - 1; // (0, totalRange) --> (minVal, maxVal) float v = (val * 255) + minVal; // (-1, 1) --> (minVal, maxVal) float dequant = (float)v / (ScaleFactor * halfRange); -
The game then calculates an RG Tangent Space Normal Map from the Height Map: csComputeNormalMap