TileSetSource in Godot – Complete Guide

Tilesets are the cornerstone of many 2D games, acting like the building blocks from which game levels and environments are constructed. Understanding how to effectively manage and implement these tilesets can significantly impact a developer’s workflow and the game’s performance. Godot 4 introduces the new TileSetSource class to simplify this aspect of game creation. In this series of tutorials, we’ll learn what TileSetSource is, how to use it, and why mastering it can greatly enhance the way you design your game’s levels. Whether you’re completely new to game development or have experience under your belt, this series is tailored to facilitate all learners in grasping the concepts of handling tilesets in the versatile Godot 4 engine.

What is TileSetSource?

The TileSetSource class in Godot 4 is a type of resource that organizes the tiles used in a tileset. It comes under the Resource inheritance hierarchy, which means it benefits from Godot’s efficiency in managing reusable assets. Tiles are the small images used repeatedly to create larger game environments like floors, walls, and backgrounds. TileSetSource acts as a container that holds these tiles, managing them through a system of coordinates and alternative IDs.

What is it for?

TileSetSource serves several purposes in Godot 4. It’s primarily used to categorize and access individual tiles or groups of tiles within a tileset. With the methods provided by TileSetSource, you can iterate over tiles, query information about them, and handle multiple variations or “alternatives” to a given tile. This can be incredibly useful when creating more dynamic and visually diverse game worlds.

Why Should I Learn it?

Understanding how to use TileSetSource is central to working with 2D tile-based game worlds in Godot 4. It allows for a more organized way to work with the plethora of tile variations that modern games require. By mastering TileSetSource, you’ll be able to streamline the game development process, reduce errors, and create more complex and engaging levels. Equipping yourself with this knowledge can expand your Godot skill set, open up new opportunities for creativity, and improve the overall quality of your game projects.

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Creating TileSetSource Resources

Before diving into advanced features, we’ll start by creating a basic TileSetSource resource in Godot 4. This resource will be the foundation from where we populate our tileset with individual tiles.

var my_tileset_source = TileSetSource.new()

We can also save this resource to a file for later use, which is helpful in managing assets in larger projects.

var my_tileset_source = TileSetSource.new()
ResourceSaver.save("res://my_tileset_source.tres", my_tileset_source)

Adding Tiles to TileSetSource

Once we have our TileSetSource resource, the next step is to add tiles to it. Tiles are usually represented by a region of a texture. Godot’s Rect2 structure suits this purpose by defining a position and size for our tile within the texture.

First, let’s assume we have an image named “tileset.png” loaded into our project.

var tile_texture = preload("res://tileset.png")
var tile_region = Rect2(0, 0, 64, 64)  # x, y, width, height
my_tileset_source.create_tile(tile_texture, tile_region, 0)  # 0 is the tile ID

Each tile is identified by an ID which should be unique. Here is how to add multiple tiles with their respective IDs:

my_tileset_source.create_tile(tile_texture, Rect2(0, 0, 64, 64), 0)
my_tileset_source.create_tile(tile_texture, Rect2(64, 0, 64, 64), 1)
my_tileset_source.create_tile(tile_texture, Rect2(128, 0, 64, 64), 2)

Working with Tile Alternatives

TileSetSource in Godot 4 allows defining alternative tiles. This feature is particularly useful for adding variety to your game levels without creating extra tiles from scratch. Let’s define some alternatives for our first tile:

my_tileset_source.create_alternative_tile(0, tile_texture, Rect2(0, 64, 64, 64), 1)
my_tileset_source.create_alternative_tile(0, tile_texture, Rect2(0, 128, 64, 64), 2)

In the above code ‘0’ refers to the original tile ID, and ‘1’ and ‘2’ are the IDs of the alternative tiles.

Creating Collision Shapes for Tiles

A crucial feature of TileSetSource is its ability to define collision shapes for tiles. These are essential for gameplay mechanics such as preventing players from walking through walls or interacting with the environment.

Let’s define a simple square collision shape for our first tile.

var collision_shape = RectangleShape2D.new()
collision_shape.extents = Vector2(32, 32)
my_tileset_source.tile_set_shapes(0, [collision_shape], [Transform2D(0, Vector2(32, 32))], 0)

The `tile_set_shapes` method applies collision shape data to a given tile. The last ‘0’ is the shape’s ID, allowing multiple collision shapes for one tile.

To give another example, this is how you can add a collision shape to one of the tile alternatives:

my_tileset_source.tile_set_shapes(0, [collision_shape], [Transform2D(0, Vector2(32, 32))], 1, 1)

Here, ‘1’ after the Transform2D specifies the alternative tile ID, and the subsequent ‘1’ at the end is the shape’s ID.

These are the basic operations to set up a TileSetSource with tiles, alternatives, and collision shapes, which form the foundational mechanics of your game world. In the next part of this tutorial, we will delve further into retrieving tile information and using TileSetSource with a TileMap for level building in Godot 4.

Retrieving Tile Data

Once tiles are added to the TileSetSource, it is often necessary to retrieve information about them for various purposes, such as editing or gameplay mechanics. Godot 4 enables this through a series of functions provided by the TileSetSource class.

To get a list of all tiles IDs:

var tile_ids = my_tileset_source.get_tiles_ids()

This will return an array containing all the unique tile IDs that we have specified when adding the tiles.

To obtain data about a specific tile, like its texture or region, you can use:

var tile_texture = my_tileset_source.tile_get_texture(0)
var tile_region = my_tileset_source.tile_get_region(0)

Where ‘0’ is the ID of the tile we want to retrieve the information for.

For detailed data, especially when dealing with tile alternatives, you can utilize:

var alternative_texture = my_tileset_source.tile_get_texture(0, 1)
var alternative_region = my_tileset_source.tile_get_region(0, 1)

The second parameter, in this case ‘1’, specifies the alternative tile ID.

Using TileSetSource with TileMap

The true power of TileSetSource is revealed when used in conjunction with a TileMap. You can create visually rich and interactive game worlds by placing tiles onto a grid-based map.

Assuming we have a TileMap node set up in our scene, we need to attach our TileSetSource to it. This can be done using the TileSet class, which holds one or more TileSetSources.

First, create a TileSet:

var tileset = TileSet.new()
tileset.add_source(my_tileset_source)

Now, let’s assign the tileset to the TileMap:

var tile_map = TileMap.new()
tile_map.tile_set = tileset
add_child(tile_map)

With the TileSet now assigned to the TileMap, you can begin placing tiles. To place a tile using code, define its cell location and the tile ID:

tile_map.set_cell(0, 0, 0)  # x, y, tile ID
tile_map.set_cell(1, 0, 1)  # Place different tiles by changing the tile ID

If you wish to use an alternative tile, you’ll need to set the alternative tile ID:

tile_map.set_cell(2, 0, 0, false, false, false, Vector2.ZERO, 1)  # Last '1' is the alternative tile ID

Editing Tile Data at Runtime

Godot 4 not only allows creating and managing TileSetSource resources, but also modifying them on the fly. This can create dynamic environments where tiles change properties during gameplay.

For instance, to change the texture of an existing tile, use:

var new_texture = preload("res://new_tile_texture.png")
my_tileset_source.tile_set_texture(0, new_texture)

If you need to define a new region for an existing tile, possibly to update its visual appearance:

my_tileset_source.tile_set_region(0, Rect2(64, 64, 64, 64))

Remember to refresh the TileMap to reflect changes made to the TileSetSource:

tile_map.update_dirty_quadrants()

This method ensures that the rendered tiles on the TileMap display the latest data.

The ability to edit tile data dynamically paves the way for real-time game mechanics, such as interactive environments or tile-based puzzles.

In conclusion, Godot 4’s TileSetSource offers a powerful, efficient way to handle one of the most fundamental elements in 2D game design: the tileset. By leveraging the features covered in this tutorial, you can create, manage, and interact with tiles in ways that are both programmatically robust and creatively flexible. Whether designing intricate puzzles or extensive worlds, these techniques can significantly boost productivity and bring your game concepts to life. Stay tuned as we continue to explore deeper aspects of Godot 4’s TileSetSource and how it can revolutionize your game development process.Enhancing the TileMap with Autotile Functionality in Godot 4 becomes a critical feature when dealing with larger game worlds. Autotiles automatically adjust their visuals based on their neighbours which is great for creating complex maps efficiently.

Let’s define an Autotile within our TileSetSource:

var autotile_coords = PoolVector2Array([Vector2(0, 0), Vector2(1, 0), Vector2(2, 0)])
my_tileset_source.autotile_set_subtile_coords(0, autotile_coords)

In this example, we define three subtile coordinates that our autotile will use, depending on the surrounding tiles. Each Vector2 value represents the position of a subtile within the tilesheet image, based on tile sizes (0, 0 being the first tile).

Now, to enable the Autotile feature on the TileMap, specify the cell as an autotile:

// The `set_cell` method signatures vary slightly for autotiles 
tile_map.set_cell_autotile(0, 0, 0, true)

By passing `true` to `set_cell_autotile`, you are telling the TileMap that this tile should use autotiling logic to determine its appearance.

Animating Tiles for Lively Maps is also possible with TileSetSource. Animation involves a sequence of tiles to create the illusion of motion.

Defining an animated tile is simple:

var animation_frames = [0, 1, 2]  // IDs of the tiles used for animation frames
var animation_speed = 5  // Speed of the animation in fps
my_tileset_source.tile_set_animation(0, animation_frames, animation_speed)

An animated tile can be placed just like any other tile:

tile_map.set_cell(0, 1, 0)  // Place the animated tile at coordinates (0, 1)

When the game runs, this tile will animate, cycling through the tile IDs provided at the speed set.

Determining Tile Neighbours is an important part of creating advanced game mechanics. Godot’s TileSetSource provides methods to retrieve information about tiles adjacent to a specific tile in the TileMap.

Here’s an example of how to find neighbours of a tile at coordinates (x, y):

var neighbours = []
for xi in -1..1:
    for yi in -1..1:
        if xi == 0 and yi == 0:
            continue
        neighbours.append(tile_map.get_cell(x + xi, y + yi))

This will give you an array of the tile IDs surrounding your tile, which you can use to define interaction logic based on adjacent tiles.

Modifying TileMap Appearance with Bitmasking in Godot 4 is used for complex Autotile behavior.

First, define the bitmask for the autotile:

// Assuming 3x3 minimal bitmask mode
var bitmask = [
    false, true, false,
    true, true, true,   // The central `true` represents the tile itself
    false, true, false
]
my_tileset_source.autotile_set_bitmask(0, bitmask)

With bitmasking, we can manage which tile variation to show based on the pattern of surrounding tiles. The bitmask definition above allows for connectivity on four sides of the tile.

And finally, to use the TileSetSource with scenes other than the one it was created in, preload the resource:

var loaded_tileset_source = preload("res://my_tileset_source.tres")

You can then use the `loaded_tileset_source` the same way you use local TileSetSource instances.

These examples show further capabilities of TileSetSource which you can use to refine the visual and interactive aspects of your TileMap. Whether you’re creating landscapes that adapt to their surroundings or designing levels with colorful, animated features, Godot 4 provides developers with the power to do it effectively. Understanding and utilizing these techniques is key to producing professional-quality games that stand out visually and engage players with their environment.

Furthering Your Game Development Journey

As we wrap up this tutorial on using TileSetSource in Godot 4, remember that this is just the beginning of your game development journey. To keep growing your skills and expanding your knowledge, we at Zenva encourage you to delve deeper into the world of game creation.

Check out our Godot Game Development Mini-Degree, a course collection designed to take you from the fundamental principles to more complex game development concepts using Godot 4. With a multitude of topics covered, from 2D and 3D game mechanics to UI systems and beyond, you will build a robust portfolio of projects to showcase your burgeoning development prowess. The courses, created by experienced game developers, are accessible anytime, anywhere, and are tailored to fit both your learning pace and your schedule.

And if you’re looking to broaden your horizons even further, be sure to explore our wider range of Godot courses at Zenva Academy. With over 250 supported courses, including content for intermediate and advanced learners, we support your growth from beginner to professional. Step by step, you can learn coding, create intricate games, and earn certificates to pave a successful career path in game development. Your journey is just starting, and the path forward is rich with possibility — let Zenva guide you every step of the way.

Conclusion

Mastering the intricacies of Godot 4’s TileSetSource is akin to acquiring a superpower in the realm of game development – empowering you to weave intricate levels with elegance and efficiency. As we’ve seen throughout this tutorial, it’s a crucial skill that elevates your game design, allowing you to create with more depth and dynamism. The path of a game developer is one of constant learning and creation, and by harnessing the full potential of tools like TileSetSource, you’re well-equipped to craft experiences that captivate and inspire.

Your adventure doesn’t have to end here. With the Godot Game Development Mini-Degree by your side, the journey continues towards greater mastery and more complex creations. At Zenva, we’re here to support your growth as a game developer with courses that ensure your skills remain on the cutting edge. We’re thrilled to be a part of your educational quest and can’t wait to see the amazing games you’ll bring to life. Level up with us, and take your game development dreams from concept to reality.

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.