scmJS docs

ISOM

The isometric record, which an editor's isometric brush paints with: the lattice of terrain diamonds from which it works out the cliffs and edges between terrain types. Only editors read it. Without it the map plays the same, but an editor cannot paint it isometrically until the record is rebuilt, which the Repair plugin can do from the tiles.

How StarEdit's brush uses this record was worked out by reverse-engineering StarEdit for Chkdraft. What follows describes the record in those terms, and each claim about real files was checked against Blizzard's own maps.

Name ISOM (49 53 4F 4D)
Size (width ÷ 2 + 1) × (height + 1) × 8 bytes.
Read by Editors only. The game skips it.
Required No.
More than one copy Every copy is written over the start of the same fixed-size space, in file order, so a later copy replaces only as many bytes as it carries.
In scmJS Read, and written again when you change what it holds.

Each rect:

Offset Type Holds
0 u16 The word on the rect's left side
2 u16 Its top side
4 u16 Its right side
6 u16 Its bottom side

Diamonds and rects#

The isometric brush does not paint tiles. It paints diamonds, 128 pixels wide and 64 tall: four tiles across and two down. Their centres sit on a lattice of points 64 pixels apart across and 32 apart down, at every other point of it, the ones whose coordinates add up to an even number. Diamond (x, y) is centred on pixel (64 × x, 32 × y), so the diamonds along the top and left edges of the map are half off it.

The section does not store diamonds one by one. It stores rects: 64 by 32 pixels, two tiles side by side, with rect (x, y) having its top-left corner on lattice point (x, y). Two corners of every rect are diamond centres, and the line between its other two corners cuts the rect into two triangles, each one quarter of one of those diamonds:

Diamonds over the corner of a map, and one rect split between two of them

The rects are stored row by row from the top left, width ÷ 2 + 1 of them across and height + 1 down. That is one column and one row more than the map covers, so that the diamonds centred on the right and bottom edges have all four quarters stored. Rect (x, y) starts at byte (y × (width ÷ 2 + 1) + x) × 8.

The four words of a rect#

A rect is four 16-bit words, one for each of its sides, in the order left, top, right, bottom. Each word belongs to the quarter of a diamond that lies along that side, and holds the diamond's value and which quarter it is:

word = value × 16 + flags        value = word >> 4        flags = word & 0xF

So every diamond's value is stored eight times, twice in each of the four rects it covers. On every Blizzard map checked, all eight copies agree. The flag bits give the quarter (bits 2 and 3) and which of its two sides of the rect the word is on (bit 1):

Low four bits Quarter of its diamond The diamond's centre is the rect's Side of the rect
0x0 top-left bottom-right corner right
0x2 top-left bottom-right corner bottom
0x4 top-right bottom-left corner left
0x6 top-right bottom-left corner bottom
0x8 bottom-right top-left corner left
0xA bottom-right top-left corner top
0xC bottom-left top-right corner top
0xE bottom-left top-right corner right

Bits 0 and 15 are scratch space for StarEdit's brush while it paints. They are 0 in a saved file.

StarEdit writes the flag bits when its brush sets a diamond. The ground a map was started with, where nobody has painted since, can hold the right value with the flag bits left at 0. On the eight Blizzard maps checked, every word with wrong flags is of this kind: all of them hold one flat terrain per map, the one the map was started with. So a program reading the lattice should work out which diamond a word belongs to from where the word is in its rect, and treat the flags as a check at most.

The words in the extra column and row that belong to diamonds past the edge of the lattice still hold values on Blizzard's maps. Nothing on the map depends on them.

What a value means#

A value is one of two things:

Of the two terrains a set joins, one is laid as a patch on the other: high dirt on dirt, dirt on water, jungle on dirt. Here the terrain underneath is called the outside terrain and the patch the inside one, since the border runs around the inside. North is up the map.

Shape The diamond is
+0 Edge; the outside terrain to the north-west
+1 Edge; the outside terrain to the north-east
+2 Edge; the outside terrain to the south-east
+3 Edge; the outside terrain to the south-west
+4 Corner of the inside terrain, pointing north
+5 Corner of the inside terrain, pointing east
+6 Corner of the inside terrain, pointing south
+7 Corner of the inside terrain, pointing west
+8 Corner of the outside terrain, pointing east
+9 Corner of the outside terrain, pointing west
+10 Corner of the outside terrain, pointing south
+11 Corner of the outside terrain, pointing north
+12 Crossing: the inside terrain at the north and south corners, the outside at the east and west
+13 Crossing: the outside terrain at the north and south corners, the inside at the east and west

The fourteen shapes, each diamond split into its quarters

Each quarter of a diamond is the outside terrain, the inside terrain, or crossed by the border. The border runs through the centre of the diamond and meets the middle of a side, where the diamond beside it carries it on, so a run of edge diamonds draws one unbroken line. The values are not in any game file: StarEdit has them built in, for each tileset. Values by tileset lists them all.

A worked example#

A Jungle World map covered in Dirt, value 1, with one diamond of High Dirt painted on it with StarEdit's smallest brush:

One diamond of High Dirt on Dirt, with the value of every diamond around it

The painted diamond takes High Dirt's value, 2. The brush then joins it to the Dirt around it with the cliff between the two, values 17 to 30. The four diamonds that share a side with the centre become the four straight edges, 17 to 20, and the four beyond them, which only touch it at a point, become the corners where the high ground ends, 21 to 24. On the map this is a small raised plateau with a cliff all the way round, and no flat High Dirt tile at all: the centre diamond's four quarters all lie in rects that also hold part of the cliff.

Here are two rects from the middle, as the section holds them. The map is 16 tiles wide, so a row holds 9 rects and rect (x, y) starts at byte (9 × y + x) × 8:

 240  18 01  rect (3,3) left   0x0118: diamond (3,3), value 17, bits 0x8
 242  1A 01  rect (3,3) top    0x011A: diamond (3,3), value 17, bits 0xA
 244  20 00  rect (3,3) right  0x0020: diamond (4,4), value 2, bits 0x0
 246  22 00  rect (3,3) bottom 0x0022: diamond (4,4), value 2, bits 0x2
 248  24 00  rect (4,3) left   0x0024: diamond (4,4), value 2, bits 0x4
 250  2C 01  rect (4,3) top    0x012C: diamond (5,3), value 18, bits 0xC
 252  2E 01  rect (4,3) right  0x012E: diamond (5,3), value 18, bits 0xE
 254  26 00  rect (4,3) bottom 0x0026: diamond (4,4), value 2, bits 0x6

Rect (3,3) is even, so its left and top words belong to diamond (3,3), the north-west edge, and its right and bottom words to diamond (4,4), the flat High Dirt in the centre. Rect (4,3) is odd: its left and bottom words belong to the centre and its top and right words to diamond (5,3), the north-east edge.

From diamonds to tiles#

The lattice holds no tiles. After each stroke the brush works out new tiles for every rect it changed, and writes them to MTXM and TILE:

  1. Each of the rect's four words names a quarter of a diamond. From the diamond's value and the quarter, the brush gets a link number for that side of the rect.
  2. It looks for the tile group in the tileset whose own four links match. Every group of the tileset's CV5 file carries a link for each side (see what a tile number points at). The rect's left tile comes from that group, which is always an even number, and its right tile from the next one.
  3. It picks one of the group's variations at random, the same one for both tiles.
  4. A cliff face is taller than one rect, so the rows below the top of a cliff are chosen to continue it, by the groups' stack links.

Link numbers up to 48 are shared by any two pieces that can meet; higher ones only join pieces of the same edge set. A flat terrain carries the same link on all four sides. The table of links for each value is not stored anywhere either: an editor builds it from the tileset's CV5 and the values above.

Since the game draws MTXM and never reads this section, the two can disagree without anyone noticing in a game. Tiles placed one by one, blends and doodads are all tiles no lattice produces. The next isometric stroke over them replaces them with what the lattice says.

Values by tileset#

The value of each flat terrain, and the first value of each edge set with its outside and inside terrains. Numbers between these (Badlands 10 to 12, for example) are not used.

Badlands:

Value Terrain, or outside / inside
1 Dirt
2 High Dirt
3 Water
4 Grass
5 Asphalt
6 Rocky Ground
7 High Grass
8 Structure
9 Mud
13–26 Dirt / High Dirt
27–40 Water / Dirt
41–54 Dirt / Grass
55–68 Dirt / Rocky Ground
69–82 High Dirt / High Grass
83–96 Dirt / Asphalt
97–110 Asphalt / Structure
111–124 Dirt / Mud

Space Platform:

Value Terrain, or outside / inside
1 Space
2 Platform
4 High Platform
8 Solar Array
9 Low Platform
10 Rusty Pit
11 Plating
12 High Plating
13 Elevated Catwalk
14 Dark Platform
24–37 Space / Platform
38–51 Platform / High Platform
52–65 Platform / Solar Array
66–79 Low Platform / Platform
80–93 Rusty Pit / Platform
94–107 Platform / Plating
108–121 High Platform / High Plating
122–135 Platform / Elevated Catwalk
136–149 Platform / Dark Platform

Installation:

Value Terrain, or outside / inside
1 Substructure
2 Floor
3 Roof
4 Substructure Plating
5 Plating
6 Substructure Panels
7 Bottomless Pit
22–35 Substructure / Floor
36–49 Floor / Roof
50–63 Substructure / Substructure Plating
64–77 Floor / Plating
78–91 Substructure / Substructure Panels
92–105 Bottomless Pit / Substructure

Ashworld:

Value Terrain, or outside / inside
1 Magma
2 Dirt
3 Lava
4 Shale
5 High Dirt
6 High Lava
7 High Shale
8 Broken Rock
27–40 Magma / Dirt
41–54 Dirt / High Dirt
55–68 Dirt / Lava
69–82 High Dirt / High Lava
83–96 Dirt / Shale
97–110 High Dirt / High Shale
111–124 Dirt / Broken Rock

Jungle World, Desert, Ice and Twilight, which share one numbering:

Value Jungle World Desert Ice Twilight
1 Dirt Dirt Snow Dirt
2 High Dirt High Dirt High Snow High Dirt
3 Water Tar Ice Water
4 Jungle Sand Dunes Dirt Crushed Rock
5 Raised Jungle Sandy Sunken Pit Water Sunken Ground
6 Rocky Ground Rocky Ground Rocky Snow Crevices
7 Ruins Crags Grass Flagstones
8 Temple Compound Outpost Basilica
9 High Jungle High Sand Dunes High Dirt High Crushed Rock
10 High Ruins High Crags High Grass High Flagstones
11 High Raised Jungle High Sandy Sunken Pit High Water High Sunken Ground
12 High Temple High Compound High Outpost High Basilica
13 Mud Dried Mud Moguls Mud
17–30 Dirt / High Dirt Dirt / High Dirt Snow / High Snow Dirt / High Dirt
31–44 Water / Dirt Tar / Dirt Ice / Snow Water / Dirt
45–58 Dirt / Jungle Dirt / Sand Dunes Snow / Dirt Dirt / Crushed Rock
59–72 Dirt / Rocky Ground Dirt / Rocky Ground Snow / Rocky Snow Dirt / Crevices
73–86 Jungle / Raised Jungle Sand Dunes / Sandy Sunken Pit Dirt / Water Crushed Rock / Sunken Ground
87–100 Jungle / Ruins Sand Dunes / Crags Dirt / Grass Crushed Rock / Flagstones
101–114 Jungle / Temple Sand Dunes / Compound Dirt / Outpost Crushed Rock / Basilica
115–128 High Dirt / High Jungle High Dirt / High Sand Dunes High Snow / High Dirt High Dirt / High Crushed Rock
129–142 High Jungle / High Ruins High Sand Dunes / High Crags High Dirt / High Grass High Crushed Rock / High Flagstones
143–156 High Jungle / High Raised Jungle High Sand Dunes / High Sandy Sunken Pit High Dirt / High Water High Crushed Rock / High Sunken Ground
157–170 High Jungle / High Temple High Sand Dunes / High Compound High Dirt / High Outpost High Crushed Rock / High Basilica
171–184 Dirt / Mud Dirt / Dried Mud Snow / Moguls Dirt / Mud

scmJS 0.6.2 + main@dd79a77 · Generated from the repository. The source is under the MIT license, which does not cover what ATTRIBUTION.md lists. StarCraft and Brood War are trademarks of Blizzard Entertainment; this project ships none of their data.