Log in

View Full Version : Reading .jjm map file format



chaos_thunderstorm
06-19-2025, 18:56
Hi

Continuation of my mtw3dviewer project https://github.com/tomi-l/mtw3dviewer
I got a collaborator and we are working on it together now

I created a new branch for reading map format and we managed to get a working prototype now. There are very few clues about how map format works and pretty much the only source is this ancient thread https://forums.totalwar.org/vb/archive/index.php/t-5259.html. Regardless we managed to reverse engineer vertex data part so far. I'll write a more robust documentation later but here's a short description how it works.

I have a custom flat map. Let's start with the header which is 9 bytes:

14 00 05 00 00 7C 6A 00 00

1400 is ushort which is the dimensions of the map. In this case 20, which makes the map 20x20
0500 is ushort which is the number of "subdivisions" per tile, we'll come to this later
00 is unknown but seems to always be the same
7C6A0000 is the size in bytes of the vertex data + texture data block

Now that we have the header parsed we can start parsing vertex data. Vertex data is arranged so that main nodes come first, and then each main node has additional 4 vertices of "control nodes". Number of control nodes refers to the subdivisions information (1+4=5)

Each node is a vertex of 12 bytes with following structure:
00 00 00 00 | 34 E3 FF FF | 00 A0 00 00
uint XCoordinate
int Height
uint YCoordinate

Since we established from the header that dimensions are 20x20 we know that the next 21*21 blocks of data are main nodes.

Next comes the control node part for each main node, they are of same structure but behave differently.
For each main node there are 4 control nodes:
00 08 00 00 | 34 E3 FF FF | 00 A8 00 00
00 10 00 00 | 34 E3 FF FF | 00 A0 00 00
00 08 00 00 | 34 E3 FF FF | 00 98 00 00
00 00 00 00 | 34 E3 FF FF | 00 A0 00 00

These nodes refer to the coordinates of the main node's neighboring tiles. In order:
Top left neighbour, up neighbour, left neighbour and the parent main node itself
Some of these coordinates can be out of bounds (for example for the first tile) so they are not actually used. There may be additional uses for this in mtw's smoothing algorithm.

With this information we can form a quad consisting of main node and 4 control nodes. This quad is a single tile:
26890

Parsing the heights from the control nodes we deduced that each main node can manipulate vertices from it's neighboring quads.
In the illustration there are 2x2 tiles. Other main nodes are marked red, but the one we are currently parsing (marked green) can manipulate vertices from it's neighbours and it's own tile (marked purple):

26891

The whole structure is confusing and remains a mystery why it's done this way but it must have something to do with the game's smoothing algorithm. Speaking of smoothing algorithm, I pretty much deem it impossible to reverse engineer so it'll probably just be easier to write own one.

Here's a picture of Bannockburn:
26892

chaos_thunderstorm
06-19-2025, 19:34
After height data, the next one is Textures (id and orientation).
Textures are arranged in Dimensions*Dimensions array of 2 bytes like this:

04 | 00
First byte is textureId (this one refers to texture file 004.tga in Textures/Ground/*terrain*/ folder).
Second byte tells the orientation of the texture.

TextureId is straightforward but orientation byte actually has only 3 significant bits.
0b11100000

Last 2 bits tell the rotation of the tile, this is a number between 0-3. The texture is rotated 90 degrees counter clockwise given times.

Third last bit tells if the texture is flipped horizontally.


As an additional note: I also slapped on a basic smoothing for vertices. More on this later once I can verify the heights are still correct and respect water level.

Here is a textured and smoothed Bannockburn:
26893

After textures there is an unknown block after that (maybe army data)
Trees and models after that.

drone
06-20-2025, 13:32
Good stuff! Not much of a modder myself, but I do find the file formats interesting. Tried to make a GIMP plugin for something (unit textures I think) waaaay back in the day. Looking forward to more. :bow:

chaos_thunderstorm
06-26-2025, 19:27
Updated information on textures. I also did commits to mapparser branch: added textures and a prototype for smoothing.