Quick answer: Pass tile data, not raw index. Build it with tile_set_index, tile_set_mirror, tile_set_flip, tile_set_rotate.

A procedural dungeon places mirrored tiles to reuse art. Calling tilemap_set_cell with index 5 places the tile, but setting a mirror bit doesn’t flip it. The orientation never changes.

What Went Wrong

tilemap_set_cell_xy(tilemap, cx, cy, 5 | $80000000);   // trying to set mirror manually — brittle

Raw bit manipulation works if you know the exact mask, but GameMaker provides helpers that are forwards-compatible.

The Fix

var data = tile_set_index(0, 5);
data = tile_set_mirror(data, true);
data = tile_set_flip(data, false);
data = tile_set_rotate(data, false);
tilemap_set_cell_xy(tilemap, cx, cy, data);

Build data step by step. Each helper modifies the appropriate bits. Final value sent to tilemap_set_cell.

Transform Combinations

The four orientations of a tile are encoded:

Combinations of these three produce all 8 unique orientations (including the original).

Reading Back

var data = tilemap_get_cell_xy(tilemap, cx, cy);
var idx = tile_get_index(data);
var mir = tile_get_mirror(data);   // true/false

Inspect bits independently with their getters. Useful for debug overlays of tile transforms.

Verifying

Place known transforms in a row: original, mirrored, flipped, rotated. Visually inspect each renders correctly. Read-back values match what you set.

“Use the helpers. Bit-twiddling tilemap data is fragile and version-dependent.”

For procedural worlds, randomizing mirror/flip per tile cuts visible repetition without new art. Eight orientations of one tile look like eight tiles.