NMLTutorial/32 bit sprites

From TTWiki

As of OpenTTD 1.2.0, 32 bit graphics are to be provided via NewGRF. NML has the ability to add 32 bit sprites to your NewGRF, as well as different sprites for different zoom levels in both 8 bit and 32 bit colour depth. Here we'll focus on the most common: adding 32 bit sprites for normal, 2x zoom in and 4x zoom in.

Important: it is mandatory to provide 8 bit sprites for the normal zoom level. You cannot make NewGRFs without the 'classic' sprites. If you only have/want 32 bit sprites, this means that you have to do one of the following:

  • Also draw classic 8 bit sprites for your project;
  • Do a simple batch conversion from 32 bit to 8 bit in your graphics editor;
  • Provide transparent 1x1 px sprites for 8 bit normal zoom.

Of course the first option is preferred, as there are always players who want to stick to 8 bit. The last option will break your NewGRF outside of 32 bit blitters, so if you don't care about 8 bit sprites you still may want to go for the second option.

32 bit sprites in NML are added via alternative_sprites blocks. These blocks are similar to spriteset blocks and generally appear right after them.

Alternative sprites

Like the spriteset, the alternative_sprites block defines where sprites can be found in a graphics file, how big these sprites are and what their offsets should be with respect to the ingame bounding box. In addition to the spriteset, alternative_sprites also specifies the colour depth and zoom level for this block. So if you want to provide 32 bit sprites for multiple zoom levels, you're going to need an alternative_sprites block for each of the zoom levels.

The general syntax is as follows:

alternative_sprites(<identifier>, <zoom_level>, <type> [, <filename> [, <mask_filename>] ] ) {
  • The <identifier> is the same as the identifier for the spriteset this block provides alternative sprites for. This way you connect the additional sprites to the classic 8 bit sprites.
  • The <zoom_level> entry sets for what zoom level these sprites are intended. Most used will be ZOOM_LEVEL_NORMAL, ZOOM_LEVEL_IN_2X and ZOOM_LEVEL_IN_4X. See the NML documentation for other options.
  • The <type> indicates if 8 bit or 32 bit sprites are provided. Use either BIT_DEPTH_8BPP or BIT_DEPTH_32BPP.
  • The <filename> and <mask_filename> are optional. You either provide them here and don't specify file names for the individual realsprites in this block, or you don't provide them here and instead provide the filenames for each individual realsprite.
    • The <filename> is mandatory either here or with the realsprites. Like with a spriteset, it points to the png file with the sprites.
    • The <mask_filename> is optional either here or with the realsprites. It only applies to 32 bit sprites and points to an 8 bit png file containing the mask for recolouring purposes. You can leave it out if you don't want recolouring or action colours in your sprites.


The <list_of_realsprites> defines the details of each actual sprite. The format is the same as for spritesets:

[left_x, upper_y, width, height, offset_x, offset_y]
[left_x, upper_y, width, height, offset_x, offset_y, filename]
[offset_x, offset_y]
[offset_x, offset_y, filename]

In addition to that, the following options are available in case you want to provide a mask file with the individual 32 bit sprites:

[left_x, upper_y, width, height, offset_x, offset_y, filename, mask_filename]
[offset_x, offset_y, filename, mask_filename]

Consult the tutorial page on spriteset for more details on the individual bits and pieces, in case you've forgotten.

On the next page we're going to apply this new knowledge to the example road vehicle from the beginning of this tutorial.

NML Tutorial: 32 bit sprites