rltiles Guide

What is rltiles?

rltiles is a utility program that takes a large set of individual images for items and monsters, potentially modifies those images, and then groups them together into a tile sheet. Individual images are both easier to edit and are more source control friendly and so they are the preferred method of storing raw images. Tile sheets are more efficient to use at run-time, which is why they are packed. Tiles that are used together are put in the same tile sheet.

rltiles can be found in the crawl-ref/source/rltiles subdirectory. The crawl-ref/source/rltiles/tool directory contains all of the rltiles source code.

As well as generating a tile sheet, rltiles also generates C++ code for Crawl to access the tiles. This lets Crawl identify tiles by a numerical index, determine how many variations a given tile has, and look up tiles by name in Lua. The C++ code is generated with the tile sheet and gets compiled into Crawl. This is why Crawl needs to be recompiled when adding new tiles. FIXME :)

Crawl currently has five tile sheets:

  • GUI - actions (spells, skills, commands)
  • DNGN - features (walls, floors, altars, traps)
  • PLAYER - actors (player races, monsters, doll items)
  • ICONS - overlays and icons (also health bars, exclusions)
  • MAIN - everything else (mostly items and clouds)

rltiles (surprisingly) stands for roguelike tiles. The version Crawl is using originated from the public domain version found here: http://rltiles.sourceforge.net/. It's been entirely rewritten at this point, although it's likely backwards compatible.

Basic overview

Along with images, rltiles takes a text file as input, usually in the form dc-something.txt. The five top-level text files are named after their tile sheets: dc-gui.txt, dc-dngn.txt, dc-player.txt, dc-icons.txt, and dc-main.txt. Each input file contains a series of commands that instructs rltiles about which images to load, how tiles should be named, and other information about them.

This section details all the different commands that rltiles knows about.


Lines beginning with a hash mark (#) are comments. There are no multi-line comments, so preface each line with a #. The following snippet contains four lines of comments from dc-corpse.txt.

# All corpses get a background blood stain, either red or green.
# - red, if the monster might leave red spatters elsewhere
#   (meaning it has blood a vampire can drink, even if poisonous)
# - green, otherwise.


Lines beginning with a percent sign (%) are commands. These will be explained in more detail below.


Any other lines load an image file from disk and creates a tile in the tile sheet. The following code from dc-item.txt loads club.png and assigns it the enum WPN_CLUB.


Actually, that's not entirely true. The final enum includes both the prefix (which defaults to TILE_) and the category (which defaults to nothing). So, this club image is really referred to by TILE_WPN_CLUB from C++. You can see this in the generated tiledef-main.h file. See the %sdir command for information about where these images are loaded from. See the %prefix and %parts_ctg commands for more information about enum names.

Images can also be specified with multiple enumerations, in case you want to map a single image in the tile sheet to multiple names. This code adds a single tile (from a subdirectory) and gives it three different enum names.


Finally, images can also be specified without an enum name. Any image without an enum is implicitly considered to be a variation of the last image specified with an enum. This example from dc-dngn.txt specifies a lava tile with four variations.

floor/lava0 DNGN_LAVA

In both C++ and Lua, the full set of four images is referred to by TILE_DNGN_LAVA, rather than all of the images being referred to individually. Most often, variations are used interchangeably with each other. For example, when drawing lava, Crawl will randomly choose one of the four lava tiles. Variations are also used for things like butterfly colours, hydra heads, and enchanted items. These are all commented in the individual rltiles input files.

Reusing image enums

If you've already created a tile with a complex set of comands, and you find yourself wanting to make a variation on it, don't copy-paste! You can specify an already-built tile anywhere you can specify a filename:

# compose a set of images into a complex tile: here, a sprite on the species selection screen
%compose base/troll_f
%compose body/animal_skin
%compose hair/troll
%compose gloves/claws

# reuse the composed tile, and just add a mask
%texture disabled-fg

If a filename starts with enum:, the remaining text is used as the enum name.

This ensures that if the composition of the first tile changes, the second tile will change as well.

Tile sheet commands


Each tile sheet needs a name to differentiate itself from other tile sheets. The dc-gui.txt input file specifies the name of its tile sheet like this:

%name gui

The name specifies the final image name (gui.png), the C++ files (tiledef-gui.h, tiledef-gui.cc), the html sheet (tile-gui.html), and the C++ identifiers (e.g. tile_gui_type, tile_gui_count).


To keep rltiles input files more manageable, the include command will include another rltiles input file from the same directory. First the commands in that file will be executed and then the rest of the current file will be executed. For example:

%include dc-item.txt


This command specifies an alternate search directory for images. If the image is not found in the current search directory, it will also be looked for in the current directory. Subsequent uses of %sdir will replace the search directory. This is an example from dc-dngn.txt:

%sdir dc-dngn
wall/brick_brown0 WALL_NORMAL

rltiles will first try to load the file dc-dngn/wall/brick_brown0.png. If that is not found, then it will try to load wall/brick_brown0.png. If that fails, then it will throw an error.


The prefix command changes the prefix prepended to all tile enumerations. The default prefix is TILE. The following is an example from dc-icons.txt:

%prefix TILEI
dc-misc/cursor CURSOR

The cursor tile in the above code will get a C++ enumeration of TILEI_CURSOR.


By default, enumerations for tiles start at the value 0. In some cases, it can be useful to start them at a different value.

# Start the first enumeration with a value of 3.
%startvalue 3
# Start the first enumeration with a value of TILE_MAIN_MAX.
# That enumeration can be found in the file "tiledef-main.h".
%startvalue TILE_MAIN_MAX tiledef-main.h

Note: In trunk, the syntax for this changed to accomodate Webtiles. The above example would now be:

%startvalue TILE_MAIN_MAX main


It can sometimes be useful to specify groups of tiles as categories. Its main use is to differentiate categories of doll items (bodies, pants, hats, weapons, beards). This is a code snippet from dc-player.txt:

%prefix TILEP

%parts_ctg BEARD
short_black SHORT_BLACK
short_red SHORT_RED
short_yellow SHORT_YELLOW

The category name gets baked into the enumeration name. The code above creates three images: TILEP_BEARD_SHORT_BLACK, TILEP_BEARD_SHORT_RED, and TILEP_BEARD_SHORT_YELLOW. Additionally, the C++ functions tile_player_part_start and tile_player_part_count allow Crawl to query the starting tile index and the total number of tiles in any given category.


The %variation command says that the next tile to be specified is a coloured variation of some previously-declared enumeration. Here's an example from dc-dngn.txt:


%variation DNGN_STONE_WALL brown
wall/stone2_brown0 DNGN_STONE_WALL_BROWN

This code first creates DNGN_STONE_WALL with four (non-coloured) variations. Then, the %variation command specifies that DNGN_STONE_WALL_BROWN is a brown-coloured variation for DNGN_STONE_WALL. (There is no need to have an identical number of images for a single tile enumeration.)

All colour variations don't need to be specified. If a colour is not specified, then the original image (in this case DNGN_STONE_WALL) will be used. Therefore, the default image should be specified first.

rltiles creates a C++ function for each tile sheet that allows one to find coloured variations from a given tile index. For the DNGN tile sheet, the function is called tile_dngn_coloured.

In C++, tile_dngn_coloured(TILE_DNGN_STONE_WALL, BROWN) will return TILE_DNGN_STONE_WALL_BROWN. tile_dngn_coloured(TILE_DNGN_STONE_WALL, BLUE) will return TILE_DNGN_STONE_WALL, as there is no blue variation in the above example.


For variation tiles out of a set of tiles, such as several rock wall variants etc., the game will pick one of them randomly when first initializing the level. The same applies to tiles shifting randomly from turn to turn, such as water or lava. The %weight command allows to set probabilities for the tiles of a set of being picked randomly. By default, all tiles of a set get equal probabilities.

In the following example, the rocky sand tiles are made less common than the plain sand ones:

%weight 5
floor/floor_sand_stone0 FLOOR_SAND_STONE
%weight 2
%weight 1

If the %repeat command (see below) is used for a set of tiles, the weight settings are also repeated.

As a rule of thumb, the more outstanding and eye-catching a tile variant happens to be, the less common it should be.

Basic image manipulation


When the rim setting is turned on, a one-pixel black outline is added to the image before being packed into the tile sheet. This black outline is drawn adjacent to any non-transparent non-black pixel (but not diagonal). By default, the rim settings is off.

Most tiles in Crawl have a black rim around them, so in general a rim should be added in the tile itself or through this %rim command. It can often be more convenient when editing a tile to have the rim added automatically.

# turn rim on
%rim 1

# Rim setting applies to all images until it is turned off.
# Both of these tiles will have a rim added to it.
demon_whip WPN_DEMON_WHIP
giant_club WPN_GIANT_CLUB

# turn rim off
%rim 0


The corpse setting can be used to turn a monster tile into its equivalent corpse. It's often used with the %back command to add a blood splatter underneath it. When the corpse setting is turned on, then the image will appear to have been split in two. By default, this setting is off. The following is an example from dc-corpse.txt:

# Turn on corpsification.
%corpse 1
# Add a green blood splatter.
%back dc-misc/blood_green
# Giant cockroach corpse

In the above example, giant_cockroach.png is the original cockroach image. The corpse setting takes that image and turns it into a corpse. The resulting images aren't as good as doing it by hand, but it's fairly reasonable.


By default, tiles are packed tightly into the tile sheet. If a 32×32 tile image only has an 8×8 square of non-transparent pixels, then only those 8×8 pixels need to be written into the tile sheet. If you look at the PNG files in dat/tiles, you can see the results of this packing.

%shrink 0

# This tile is a 32x32 pixel PNG, but the non-transparent pixels
# in it only take up 16x16 pixels.  By turning shrink off, it will
# be written as a full 32x32 pixel tile to the tile sheet.

# Reset the shrink setting back to default for other tiles.
%shrink 1

Image composition

It's often convenient to combine two raw image files into a single tile in a tile sheet. This allows a tile author to not have to repeat parts of an image from one tile to another and only to draw the parts that change.


The %back command is a convenient way to add a single tile as the background for a large number of tiles. This is used for corpses, potion labels, and identified scrolls.

# Turn all monster images into corpses.
%corpse 1

# Use the blood_green image as the background.
%back dc-misc/blood_green

# Change the background to a set of red blood images.
# Each time a background is needed, one will be randomly picked from the set.
%back dc-misc/blood_puddle_red dc-misc/blood_puddle_red1 dc-misc/blood_puddle_red2 dc-misc/blood_puddle_red3 dc-misc/blood_puddle_red4

# Clear the background image.
%back none

In the above code, the giant centipede corpse will have a green blood splatter and the rat, quokka, and grey rat corpses will randomly pick one of five blood puddles.

%start, %compose, %finish

If a single background image is not sufficient, there are extended composing commands that allow for the composition of unlimited numbers of tiles. Here's an example from dc-corpse.txt:

# Begin composing.  This takes no arguments.
# Each compose command takes a single image.
%compose drcwing/drcwing_black
%compose base/draconian_black_m
%compose drchead/drchead_black
# Finish composing.  This also specifies the enum for the composed image.

The above code draws the head on top of the base on top of the wings. Any rim is applied after the composition is finished.

Image recolouring

It can often be convenient to modify a tile's colours before putting it into a tile sheet. In combination with coloured variations, it allows a single piece of tile art to generate multiple coloured variations without having to create new images for each of the variations. On top of that, if the original art is modified, the coloured variations will automatically be changed as well.

Other than %pal, most recolouring commands specify a hue, which is an integer from 0-360. A tool like GIMP or Photoshop can be used to look at a pixel and determine its hue. In the GIMP in particular, you can use the color picker tool to inspect the RGB (red, green, blue) or the HSL (hue, saturation, luminance) values for any given pixel. See http://en.wikipedia.org/wiki/HSL_and_HSV for more information about hue, saturation, and luminance.

All of the recolouring commands that specify a hue apply to the original hue of the image, not the modified colour from previous recolouring commands.

If you are creating coloured variations of a tile, it is easiest to start with a coloured image and desaturate than to start with a greyscale image. This is because the hue of an unsaturated colour (black, grey, white) is 0. Unfortunately, red also has a hue of 0, so it is impossible to tell them apart by hue alone.


Palette changes are the most basic (and cumbersome) form of recolouring a tile. All the pixels of a given RGB (or RGBA) value are replaced by some other colour. R, G, B, and A values are all specified in the 0-255 range.

See http://en.wikipedia.org/wiki/Rgb#Numeric_representations for more information about RGB values.

# Replace red with green.
# Red is RGB(255, 0, 0).
# Green is RGB (0, 255, 0).
%pal 255 0 0 0 255 0

# Make blue transparent.
# Solid blue is RGBA(0, 0, 255, 255).
# Half-transparent blue is RGBA(0, 0, 255, 127)
%pal 0 0 255 255 0 0 255 127


The hue command takes all the pixels of a given hue and changes them to a different hue. Hues are specified as an integer from 0-360.

# Change all brown pixels to red ones.
# Brown pixels have a hue of 30.
# Red pixels have a hue of 0.
%hue 30 0


The desaturate command takes all the pixels of a given hue and desaturates them. Desaturating turns a pixel into a greyscale version of itself.

# Take all the magenta pixels (hue == 300) and turn them greyscale.
%desat 300


The lum command adjusts the brightness of pixels of a certain hue.

# Make yellow pixels (hue == 60) 10% brighter.
%lum 60 10

# Make cyan pixels (hue == 180) 20% darker.
%lum 180 -20

The first number in the lum command is the hue to modify. The second number is an absolute change in percentage. If the luminance of a yellow pixel is 80%, then the above commands will make the luminance of that yellow pixel 90%. Adjusting luminance too high or low will cause the tile to appear washed out.


This command clears all recolour settings so that future tiles are not recoloured at all.


The %repeat command will repeat all of the images for a given tile enumeration. In addition, it uses the final images, after any recolouring, corpsifying, or adding a rim.

# Define a normal brick wall with 8 variations.

# Define a coloured variation of the above brick wall.
%variation WALL_BRICK blue

# Recolour brown pixels to be blue.
%hue 30 240
# Recolour red pixels to be blue.
%hue 0 240

# Repeat all 8 images that make up WALL_BRICK above.
# Call this tile WALL_BRICK_BLUE.

# Clear all the recolouring options.

The %repeat command above is just shorthand for the following code:

wall/brick_brown0 WALL_BRICK_BLUE
Logged in as: Anonymous (VIEWER)
dcss/help/rltiles.txt · Last modified: 2019-10-14 18:59 by aidanholm
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki