Skip to content

Anno Fileformats: Island Files

taubenangriff edited this page Mar 13, 2024 · 1 revision

General Explaination of 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:

A7M file

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.

TMC files

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

TMC Interpreter

CTT files

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:

  1. 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); 
    
  2. The game then calculates an RG Tangent Space Normal Map from the Height Map: csComputeNormalMap

Clone this wiki locally