From GRFSpecs
Jump to navigationJump to search
Block Syntax

A spritegroup combines several spritesets into a single unit. It is supported only for vehicles and stations.


A typical spritegroup looks like:

spritegroup spritegroup_name {
	loading: (spriteset_name | [spriteset_name1, spriteset_name2, ...])
	loaded: (spriteset_name | [spriteset_name1, spriteset_name2, ...])

Vehicles take two different series of spritesets; loading is used when the vehicle is loading within the station, loaded is used when the vehicle is travelling. Each of those can be a single spriteset, or a (bracketed) array of spritesets. Both loading and loaded are required and should provide at least one spriteset each. If a spritegroup would contain only one spriteset, it's better to omit the spritegroup and directly use the spriteset instead. Spritegroups are used to show different graphics depending on how much the vehicle is loaded, with increasing load from left to right. Furthermore, you can easily provide special graphics for when loading in the station (for example: wagon with doors open).


A typical spritegroup looks like:

spritegroup spritegroup_name {
	little: (spriteset_name | [spriteset_name1, spriteset_name2, ...])
	lots: (spriteset_name | [spriteset_name1, spriteset_name2, ...])

Stations pick a spriteset depending on the amount of waiting cargo and the property cargo_threshold.

  • 0 ≤ amount ≤ cargo_threshold: use spriteset from little list.
  • cargo_threshold ≤ amount < 4096: use spriteset from lots list.
  • 4096 ≤ amount: use last spriteset from lots list.

Within the ranges for little and lots the listed spritesets are distributed equally-spaced.

You must define at least one spriteset for lots; little may be left empty, and will fall back to using the first lots spriteset.

The amount of waiting cargo is computed depending on:

  • If the station uses cargo-specific graphics (using a cargo-identifier in the graphics section), then the amount of this cargo type is used.
  • If no cargo of any of the cargo-specific graphics is waiting, then the default callback is used, and the amount will be the sum of all waiting cargo.
  • By default the total amount of cargo is attributed to every tile. If STAT_FLAG_DISTRIBUTED_CARGO is set in property general_flags, then the cargo amount is split equally between all station tiles.


Below a simple example for defining a train engine with a livery override. The passenger wagon shows different sprites whether it is travelling empty or is filled with people.

 // Define the sprites for the engine
 template tmpl_train_length78(x, y) {
 	[x,     y,  8,22,   -3,-10]
 	[x+ 16, y, 21,15,  -14, -7]
 	[x+ 48, y, 31,12,  -16, -8]
 	[x+ 96, y, 21,16,   -6, -7]
 	[x+118, y,  8,24,   -3,-10]
 	[x+144, y, 21,16,  -15, -6]
 	[x+196, y, 32,12,  -16, -8]
 	[x+224, y, 21,15,   -6, -7]
 spriteset(turbotrain_engine_set, "src/gfx/turbotrain.png") {
 	tmpl_train_length78(142, 118)
 // Define the sprites for the passenger wagon when used with this engine
 // Loading sprites with open doors
 spriteset(turbotrain_passenger_loading_set, "src/gfx/turbotrain.png") {
 	tmpl_train_length78(142, 139)
 // Passenger wagon is empty. No people shown
 spriteset(turbotrain_passenger_traveling_empty_set, "src/gfx/turbotrain.png") {
 	tmpl_train_length78(142, 159)
 // Passenger wagon is full. Show people through the window
 spriteset(turbotrain_passenger_traveling_full_set, "src/gfx/turbotrain.png") {
 // has slightly different dimensions, don't use template
 	[142,159,  8,21,   -3,-10]
 	[158,159, 20,15,  -13, -7]
 	[190,159, 28,10,  -12, -6]
 	[238,159, 20,16,   -6, -7]
 	[270,159,  8,21,   -3,-10]
 	[286,159, 20,15,  -15, -6]
 	[318,159, 28,10,  -16, -6]
 	[366,159, 20,16,   -6, -7]
 // Engine has no sprite group, because it always looks the same the spriteset is used directly.
 // Associate graphics with the wagon for the different loading stages
 spritegroup turbotrain_passenger_group {
 	loading: turbotrain_passenger_loading_set;
 	loaded: [turbotrain_passenger_traveling_empty_set, turbotrain_passenger_traveling_full_set];
 // Define new graphics for the turbotrain (it has vehicleID 20):
 item(FEAT_TRAINS, turbotrain, 20) {
 	property {
 		sprite_id:                    SPRITE_ID_NEW_TRAIN;    // We have our own sprites
 		misc_flags:                   bitmask(TRAIN_FLAG_MU); // We use special sprites for passenger and mail wagons
 	graphics {                           // graphics for engine
 		turbotrain_engine_set; // note that no spritegroup is used here, it is not needed
 	livery_override(passenger_wagon) {   // graphics for alternative look of passenger wagon when used with this engine