-
-
Notifications
You must be signed in to change notification settings - Fork 492
Tileset
SuperTux tilemaps are composed from tiles, little 32x32 pixel wide images. These tiles are defined
in an S-Expression based file, located under data/images/tiles.strf
.
These tilesets are included into the level by a tiles
and tilegroup
entry.
A general tile
contains an ID number, an images path and an attribute to determine its use
(e.g. a tile being solid, a slope, slippery etc).
A tilegroup
describes the collection of several tiles usually sorted by themes. For example,
all snow-themed tiles are sorted into a snow
tilegroup while all forest-themed tiles are sorted
into a forest
tilegroup.
An example of a simple solid tile looks like this:
(tiles
(width 1)
(height 1)
(ids 1)
(attributes 1)
(images "tiles/[tilegroup]/[tile].png")
)
The attribute
defines the tile's properties. In this example we set it to 1 which makes this
tile solid so Tux can stand on it.
More on tile attributes can be read here.
For an animated tile you can define its animation speed with an FPS
value:
(tiles
(width 1)
(height 1)
(ids 2)
(fps 12)
(attributes 512)
(images "tiles/[tilegroup]/[animatedtile]-0.png"
"tiles/[tilegroup]/[animatedtile]-1.png"
"tiles/[tilegroup]/[animatedtile]-2.png"
"tiles/[tilegroup]/[animatedtile]-3.png")
)
It is also possible to extract parts of bigger images to create tiles:
(tiles
(width 3)
(height 2)
(ids
3 4 5 6
7 8 0 0)
(attributes
0 0 0 0
1 1 0 0)
(images "tiles/[tilegroup]/[multipletiles].png")
)
For a tile which looks different in the editor, you can set the images separately:
(tiles
(width 1)
(height 1)
(ids 9)
(attributes 3)
(images "tiles/[tilegroup]/[tile].png")
(editor-images "tiles/[tilegroup]/[tile]-editor.png")
)
If you want the tile to be invisible in-game, remove the (images)
section.
In the following example, a basic set of tiles will be extracted from the image tileset_example.png
.
The left tiles are solid ground with the rest of the tiles becoming various types of slopes.
To ignore a portion of an image (e.g. empty spaces), an ID of 0 is always being used in the appropriate places.
To define a tile as a slope, its attribute
must be set to either 16 or 17. You will also have to set an appropriate data
value to define the correct slope-type.
More on tile datas can be read here.
(tiles
(width 11)
(height 4)
(ids
10 11 12 19 20 21 22 27 28 31 35
13 14 15 23 24 25 26 29 30 32 36
16 17 18 0 0 0 0 0 0 33 37
0 0 0 0 0 0 0 0 0 34 38)
(attributes
1 1 1 17 17 17 17 17 17 17 17
1 1 1 17 17 17 17 17 17 17 17
1 1 1 0 0 0 0 0 0 17 17
0 0 0 0 0 0 0 0 0 17 17)
(datas
0 0 0 18 34 32 16 2 0 66 48
0 0 0 33 17 19 35 1 3 50 64
0 0 0 0 0 0 0 0 0 49 67
0 0 0 0 0 0 0 0 0 65 51)
(images "tiles/[tilegroup]/tileset_example.png")
)
A tile can have one or more of the following attributes:
Attribute | Value | Description | Data section |
---|---|---|---|
solid |
0x0001 / 1 |
Tile collision that is solid / walkable | |
unisolid |
0x0002 / 2 |
Modifies the tile collision to be only detected from one side. | Unisolid side. 0 = up / 1 = down / 2 = left / 3 = right. |
slope |
0x0010 / 16 |
Modifies the tile collision to be a slope | Type of slope. See below for possible values. |
ice |
0x0100 / 256 |
Modifies the tile collision to make it slippery. | |
water |
0x0200 / 512 |
Tile collision that is liquid / swimmable. | |
harmful |
0x0400 / 1024 |
Tile collision that hurts the player when touched. | |
glowing |
0x0800 / 2048 |
Makes the tile emit a softly pulsating light. The light becomes red if the tile is harmful. | |
walljump |
0x1000 / 4096 |
Tile collision that allows the player to walljump while inside it. |
A tile can have multiple attributes on it by adding the values together. Some attributes may not work alone in a tile (i.e: unisolid, slope and ice), as they modify the tile collision instead of creating a collision. That being known, it is important to combine different tile attributes in order of making the tile behave as you want it to.
Attribute combination examples:
Combination | Value | Added Values | Description | Data section |
---|---|---|---|---|
unisolid tile |
0x0003 / 3 |
0x0001 + 0x0002 / 1 + 2 |
The tile is solid, but only from one side. | Unisolid side. 0 = up / 1 = down / 2 = left / 3 = right. |
solid slope |
0x0011 / 17 |
0x0001 + 0x0010 / 1 + 16 |
The tile is a walkable slope, solid from all sides. | Type of slope. See below for possible values. |
unisolid slope |
0x0013 / 19 |
0x0001 + 0x0002 + 0x0010 / 1 + 2 + 16 |
The tile is a walkable slope, only solid from one side. | Type of slope. See below for possible values. |
ice tile |
0x0101 / 257 |
0x0001 + 0x0100 / 1 + 256 |
The tile is fully solid and slippery. | |
unisolid ice tile |
0x0103 / 259 |
0x0001 + 0x0002 + 0x0100 / 1 + 2 + 256 |
The tile is solid from one side and slippery. | Unisolid side. 0 = up / 1 = down / 2 = left / 3 = right. |
ice slope |
0x0111 / 273 |
0x0001 + 0x0010 + 0x0100 / 1 + 16 + 256 |
The tile is a fully solid, slippery slope. | Type of slope. See below for possible values. |
unisolid ice slope |
0x0113 / 275 |
0x0001 + 0x0002 + 0x0010 + 0x0100 / 1 + 2 + 16 + 256 |
The tile is a slippery slope, solid only from one side. | Type of slope. See below for possible values. |
water slope |
0x0210 / 528 |
0x0010 + 0x0200 / 16 + 512 |
The tile is swimmable but only at the area of a slope. | Type of slope. See below for possible values. |
harmful unisolid |
0x0402 / 1026 |
0x0002 + 0x0400 / 2 + 1024 |
The tile hurts the player, but only if touched from a certain side. | Unisolid side. 0 = up / 1 = down / 2 = left / 3 = right. |
harmful slope |
0x0410 / 1040 |
0x0400 + 0x0010 / 16 + 1024 |
The tile hurts the player, but only at the area of a slope. | Type of slope. See below for possible values. |
harmful water |
0x0600 / 1536 |
0x0400 + 0x0800 / 512 + 1024 |
The tile is swimmable and hurts the player. | |
light block |
0x0801 / 2049 |
0x0001 + 0x0800 / 1 + 2048 |
The tile is solid and emits light. | |
fire |
0x0C00 / 3072 |
0x0400 + 0x0800 / 1024 + 2048 |
The tile hurts the player and emits a red light. | |
lava |
0x0E00 / 3584 |
0x0200 + 0x0400 + 0x0800 / 512 + 1024 + 2048 |
The tile is swimmable, hurts the player and emits a red light. |
You can try as many different combinations as you want, the ones above are only examples of what you can do.
Some attributes that were used to make a tile have a special behavior don't seem to be working on current builds of the game, as they were replaced by the possibility of creating object tiles. See here the guide for adding objects as tiles.
Attribute | Value | Description |
---|---|---|
brick |
0x0004 / 4 |
The tile would act as a brick that could be destroyed by hitting it in different ways. |
goal |
0x0008 / 8 |
The tile would finish the level when touched, with data 0 triggering end sequence and data 1 finishing instantly. |
fullbox |
0x0020 / 32 |
The tile would act as Bonus Block, with datas 1 to 5 defining its content. |
coin |
0x0040 / 64 |
The tile would act as a coin. |
??? |
0x0080 / 128 |
This attribute doesn't seem to do anything at all. |
Each tile definition can have a datas
section. This section is used when the yes/no-information
usually stored in the attributes
definition isn't appropriate for the type of information.
Currently, this section is only used to store slope angles and unisolid sides.
Each type of information stored in the data section needs to reserve a range of values for itself.
The slope information, for example, uses the values zero through 67 (64+3), so the mask is at least
0x007f
. To allow for future extension, the mask 0x00ff
has been reserved.
Name | Mask | Meaning |
---|---|---|
Slope information |
0x00ff (actually: 0x0073 ) |
Valid only when the tile has a collision attribute set. See slope types below. |
Unisolid side | 0x0003 |
Valid only when the tile has a collision attribute set. 0 = up / 1 = down / 2 = left / 3 = right. |
The deformation means the following:
Name | Value | Meaning |
---|---|---|
Deform1 | 16 | Only the lower half of the tile is used. |
Deform2 | 32 | Only the upper half of the tile is used. |
Deform3 | 48 | Only the left half of the tile is used. |
Deform4 | 64 | Only the right half of the tile is used. |
The important part is that the deformation determines which part of the tile is used and
not the actual form of the tile. For example, the 0+48
tile is a (steep, south-west)
triangle, while 2+48
is a (steep, south-east) trapezoid.
You want to contribute new tiles to the main game or just add custom tilesets for your own levels? This next portion will show how to do so.
You can simply add new tiles with the help of a text editor of your choice. You can now either add
new tiles to the main file tiles.strf
or create your own should you only seek to use custom tiles.
In that case create a new file and end it with .strf
!
At first glance a tileset file can look quite intimidating. But worry not. In its core it is not that bad. The following steps will show you how everything works in a more controlled environment. The SuperTux tileset file is quite big, which makes it look more complicated than it is.
To prepare your new file it is important to set it up the right way, so the game can read it properly
(This step can be skipped if you want to add your tiles to tiles.strf
).
Before you begin adding your tile entries, your file should look like this:
(supertux-tiles
)
Next, you can start adding your tiles one by one. In this example we are adding one tile entry for some solid tiles and another one for some slopes.
Which tiles you include in one entry is fully up to you. Technically, you could also combine both tile entries into one big tile entry. But for simplicity and better readability it is advised to make separations!
(supertux-tiles
(tiles
(width 3)
(height 3)
(ids
1 2 3
4 5 6
7 8 9)
(attributes
1 1 1
1 1 1
1 1 1)
(images "tiles/[tilegroup]/[tiles1].png")
)
(tiles
(width 4)
(height 6)
(ids
10 11 12 13
14 15 16 17
18 19 22 23
20 21 24 25
0 0 26 27
0 0 28 29)
(attributes
17 17 17 17
17 17 17 17
17 17 17 17
17 17 17 17
0 0 17 17
0 0 17 17)
(datas
18 34 32 16
33 17 19 35
2 0 66 48
1 3 50 64
0 0 49 67
0 0 65 51)
(images "tiles/[tilegroup]/[tiles2].png")
)
)
To create a tilegroup which lists all of your new tiles, you must add an tilegroup
entry. Try categorizing
your tiles by themes (e.g. Snow, Forest, etc.) so you don't have to search for all your tiles in one single
tilegroup.
(supertux-tiles
(tilegroup
(name (_ "My Tilegroup"))
(tiles
1 2 3 0
4 5 6 0
7 8 9 0
10 11 12 13
14 15 16 17
18 19 22 23
20 21 24 25
0 0 26 27
0 0 28 29)
)
(tiles
(width 3)
(height 3)
(ids
1 2 3
4 5 6
7 8 9)
(attributes
1 1 1
1 1 1
1 1 1)
(images "tiles/[tilegroup]/[tiles1].png")
)
(tiles
(width 4)
(height 6)
(ids
10 11 12 13
14 15 16 17
18 19 22 23
20 21 24 25
0 0 26 27
0 0 28 29)
(attributes
17 17 17 17
17 17 17 17
17 17 17 17
17 17 17 17
0 0 17 17
0 0 17 17)
(datas
18 34 32 16
33 17 19 35
2 0 66 48
1 3 50 64
0 0 49 67
0 0 65 51)
(images "tiles/[tilegroup]/[tiles2].png")
)
)
Some tiles are special, as they turn into objects (i.e: Bonus Blocks, Coins and Bricks) when the level is loaded.
Special tiles can only be defined one by one, that meaning, you can't turn a larger image into multiple tiles.
Turning a tile into an object is done by adding an object-name
and an object-data
within the tile
.
The general structure for adding a special tile in your tileset is the following:
(tile
(id [your tile ID])
(images
"objects/[object]/[object].png"
)
(object-name "[object class name]")
(object-data "
([propriety1] 50)
([propriety2] \"[string]\")
")
)
Be aware that any quotation mark in object-data
must be escaped by adding a backslash (\
) before it, as it's a quotation mark inside other quotation marks.
If you find it difficult to write the object proprieties you want to add as a tile, you can place the object in your level, open the level in a text editor and copy the properties present for the object. For example, if you add a Mr.Snowball to a level and customize it, in the level file you'll find:
(snowball
(z-pos 50)
(direction "left")
(x 288)
(y 128)
)
From this information, you may extract what you want to turn into a tile. You must ignore the x
and y
position properties as they will be defined, depending on where the tile is.
Let's turn that Mr. Snowball into a tile, then:
(tile
(id 52)
(images
"creatures/snowball/snowball-0.png"
)
(object-name "snowball")
(object-data "
(z-pos 50)
(direction \"left\")
")
)
For another example, here is a rock added as a tile:
(tile
(id 53)
(object-name "rock")
(images
"objects/rock/rock.png"
)
)
Now, a non-portable trampoline as a tile:
(tile
(id 54)
(images
"objects/trampoline/trampoline2-0.png"
)
(object-name "trampoline")
(object-data "
(type \"stationary\")
(z-pos 50)
")
)
Now let's be creative, let's say you want to add a bonus block that is orange and has 2 Mr.Iceblocks inside it:
(tile
(id 55)
(images
"objects/bonus_block/orange-0.png"
)
(object-name "bonusblock")
(object-data "
(type \"orange\")
(z-pos 51)
(custom-contents
(mriceblock
(z-pos 50)
)
)
(count 2)
(contents \"custom\")
")
)
Again, if you feel confused with what information you must type in the object name and data sections, you can copy them from an object that's already placed in your level file!
When a tile becomes outdated due to it being replaced by a different tile / object / decal, or when it is no longer necessary for level design, it is usually made deprecated for the sake of compatibility with older levels which include it. Deprecated tiles can still be loaded by the level and will work as they used to, but they cannot be added to tilegroups, nor can they be copied when editing the level.
If you need to deprecate a tile, it is recommended to move the images of this tile into a subfolder called deprecated
. It is also recommended to remove every deprecated tile from the tilegroups you made with them before.
Then, you'll add a (deprecated #t)
value to your tile structure to indicate that this tile or tileset is not supposed to be used anymore, and change the path of the images into its new file destination.
(tiles
(width 3)
(height 2)
(ids
3 4 5 6
7 8 0 0)
(attributes
0 0 0 0
1 1 0 0)
(deprecated #t)
(images "tiles/[tilegroup]/deprecated/[multipletiles].png")
)
Be aware that deprecated tiles still need their own IDs to exist. If a tile is deprecated, it doesn't mean its ID can be overwritten by other tiles, but as they are not supposed to be used, it is highly recommended to replace or erase these tiles from your levels to avoid a loss of compatibility in future builds of the game that may or may not overwrite these IDs.
And that is all! Go open / create a new level in the Level Editor, select your tileset file in the Level Properties and see if your tiles and / or tilegroups appear in the tiles menu.
WARNING: Unfortunately the tilemanage application is broken at the moment and does not work correctly! You'll destroy several tile attributes like slopes and some of the tiles created from multiple images, when opening and saving a tileset with the editor!
We provide an easy to use editor to make this task easier (especially extracting regions of bigger images).
You can find it in the tools/tilemanager
directory. It's a mono/gtk\#
app so you have
to have these 2 things installed and should invoke make in that directory then. It'll create
tilemanager.exe
which you can then start with mono like this:
mono tilemanager.exe
NOTE: You should be careful when choosing tile ids to not overwrite existing tiles. You should also keep in mind that existing levels will break if you change tile numbers later (the levels just save a big a list of numbers that reference the tile file).
Note that some tiles aren't actually used in-game. Right after the level is loaded, various tiles in the solid tilemaps are replaced with objects. These include all with the coin, fullbox, brick, or goal attributes, and tile id 112 (invisible block). But the game doesn't end there. It also adds light sources to torches and lava, which are then hidden unless the level uses a lightmap.
Home
Guidelines
Game Mechanics
Tools
Engine
- Cameras in other games
- Collision
- Configuration File
- Console
- Cutscenes
- Game_Engine
- Lighting
- Map_transformer
- Portables
- SceneGraph
- Scripting
Specifications
Milestones
- Milestone 1 Analysis
- Milestone 2 Design Document
- Milestone 2 Design Document Old
- Milestone 3 Design Document
Building (mostly outdated)
- INSTALL.md
- Building
- Building on macOS
- Building SuperTux
- Building on Windows
- Building with MXE (cross-compile)
Meetings