BAR Extractor improvements

Texture support was (possibly) fixed for BTX (and DDT support added) to the BAR extractor. Just drag a BAR file into the page and it’ll load up thumbnails for all images within. I’m using it to look through the Age of Mythology files; I dont have Age of Empires 3 installed, but it should work with that too.


Visit here to use the tool.


Improved UI, set input types, Worley Noise

The UI is now much cleaner and easier to understand. The types of some parameters can be changed (for example making the frequency 2D for PerlinNoise, or changing blend to work with grayscale values). Worley Noise (aka cellular noise) has been added, which is useful for cutting out wedges from objects (like stone). Nodes that can be transformed can now wrap in Presentation space (ie. they still produce a tiling texture) or not at all. Tiles has some more properties, and offset was changed to be relative to the count (like in Substance).

Procedural Texture Generator – Shadows

Added a shadows node, made the Shape node more generic (all falloff functions work with all shapes), and optimised things a bunch. Also added FileSaver so large files export correctly.

Heres a perlin terrain:


Use this version here, it will automatically load the test surface now (just hit New to clear it).


Procedural Texture Generator

More work on the procedural texture generator, this time I added functionality for nodes to act as “passthrough” nodes, where instead of rendering to a texture, they pass their code onto the next node, so that a whole branch can be generated at once. While this can help with rendering times, a far bigger advantage is that nodes (like the Tiles node) can provide their own seed for the input branch. Passthrough nodes are denoted by a blue border, or can be forced on by selecting them and checking the “Passthrough” checkbox in their preview.

Loading/saving to external files is there now too, ‘blend’ outputs a (broken) mask as ‘output 2’, and various nodes have added parameters.


In this render, all the stones are unique. Disable passthrough on the PerlinNoise nodes to see without. The comparison below shows the difference.

Try out this release by visiting and load in the above surface from

Procedural Node Texture Generator

I was very impressed with the Substance Designer workflow, so decided to build my own node-based texture editor. After a month, here is the result.

It is only tested with Chrome, use it by visiting

Future goals are to better tag data types so they are converted correctly (ie. height-map implicitly converted to normal-map) and allow different types of data to be passed between nodes (points and meshes). And obviously add and fix nodes.

Mod HQ – .BAR, .DDT and .XMB

I’ve made a lot of progress today, adding support for streaming content from .BAR archive files, reading .DDT texture files (except for the DXT sub-formats), and building an XDocument from .XMB files. The project was updated so that it can be pointed at the Age Of Mythology game folder, and it will extract all the data it needs; no need to use BAR explorer or AOMEd to get the data in a more usable format.

In case anyone else wants to know how the formats work, here is a breakdown:


BAR files are a collection of other files. They start with a short header, then a huge binary blob of all the data from all files within it, finally there is a “directory” containing the filenames and offset/length of the binary data above that belongs to the file. (1)
– [8 bytes] The “id”, seem to always be 0’s
– [4 bytes] Skip
– [4 bytes] Item count integer
– [4 bytes] Directory size integer
– [4 bytes] Directory offset integer
– […] binary data blob
==Jump to directory offset==
[For each file (0 .. item count)]
  – [4 bytes] File offset
  – [4 bytes] File size
  – [4 bytes] File size repeated (maybe packed size?)
  – [8 bytes] Skip
  – [null terminated string] File name
==Jump to File offset==
  – [File size bytes] The file contents


DDT files are a container for image data of a number of formats (uncompressed, Palette, Grayscale, DXT formats). It starts off with a short header, then optionally some palette data, and finally the image data.
– [4 bytes] File magic code “RTS3”
– [4 bytes] Texture usage, ignored but has significance in AOE3 (2)
– [4 bytes] Alpha bit-depth; 0: no alpha, 1: binary alpha, 4: 4-bit alpha, 8: 8-bit alpha
– [4 bytes] Texture format; 1: Uncompressed, 3: Palette, 4&5&6: DXT formats, 7: Grayscale (2)(3)
– [4 bytes] Mip levels
– [4 bytes] Texture width
– [4 bytes] Texture height
[If Format == Palette]
  – [4 bytes] Number of colours in palette
  – [4 bytes] Skip
  – [4 bytes] 16-bit palette offset (565)
  – [4 bytes] 15-bit palette offset (?)
  – [4 bytes] 15b-bit palette offset (1555)
  – [4 bytes] 12-bit palette offset (4444)
[For each image mip level]
  – [4 bytes] Image data offset
  – [4 bytes] Image data size
[If Format == Palette]
==Jump to appropriate palette offset (16-bit if 0-bit alpha, 15b-bit if 1-bit alpha, 12-bit if 4-bit alpha)==
  – [Number of colours * 2 bytes] The palette data as 16-bit packed integers (RGB565, ARGB1555, ARGB4444)
  ==Jump to each image offset==
  – [Image-length bytes] The image data


XMB files are compressed binary XML files, though in the AOM alpha, there were uncompressed versions. They start with a magic code of l33t for compressed and both compressed (after being decompressed) and uncompressed begin with X1. Compressed files are compressed using zlib deflate. The files then contain a list of element names and parameter names, then a tree of elements with ids mapping into these arrays. (3)
– [2 bytes] “X1”
– [4 bytes] Length of document
– [2 bytes] “XR”
– [4 bytes] Version Major
– [4 bytes] Version Minor
– [4 bytes] Number of element names
[For each element name]
  – [4 bytes] Length of string
  – [Length bytes] String data
  – [4 bytes] Number of parameter names
[For each parameter name]
  – [4 bytes] Length of string
  – [Length bytes] String data
[Begin read-element sub-routine]
  – [6 bytes] Skip
  – [4 bytes] Length of content
  – [Length bytes] Content data
  – [4 bytes] Index into element names
  – [If Version > 4.7]
    – [4 bytes] Source document line number
  – [4 bytes] Number of parameters
  [For each parameter]
    – [4 bytes] Index into parameter names
    – [4 bytes] Length of content
    – [4 bytes] Content data
    – [4 bytes] Number of child elements
  [For each child element]
    – […] Repeat read-element
[End read-element sub-routine]

The interface was also tweaked a little, adding images for units, a filter to show only units or buildings, and some more tabs for when more functionality is added.

(3) AOMEd source code (cont+alt+shift+triple-click the window to get source)

Download, click Data source, and point it to your Age of Mythology directory.

Note to self: WPF ListBox bug appears when the parent Grid has multiple rows AND columns.