How can I effectively change the texture?

Godot Version

4.2.2

Question

I have a large map (4800x3600) which has a season change feature.

However, I have noticed that when the seasons change, for example from fall to winter, the game lags for a short time (A few tenths of a second).
Is there any way to smoothly change textures (sprites/tile maps, etc.) across the map?

How are you changing for the seasons now? Without knowing I would guess modulate instead of texture change would be the fastest. If you are changing individual tiles you could batch them into smaller chunks such as a LFSR used in OpenTTD.

The key to performance in this case would be to avoid working with individual tiles. Few ideas:

  • As @gertkeno said, modulating the entire tilemap is absolutely the fastest way, because it avoids working with individual tiles. But also doesn’t give you much control over what tiles to modulate.
  • Modulate individual tile layers. This requires you to place for example grass or nature tiles into specific tilemap layers. You can find the modulate property on each layer in the TileMap node!

Now – with the performant solutions out of the way, you have to modify the individual tiles (which I think is what you are doing now). You can do so in multiple ways, but I would say alternative tiles are your best bet. For example the default tile is always spring, first alternative always summer and so on. Lots of work as far as tile creation goes…

How to go about changing the actual tiles? I have a few ideas here too:

  • Try calling your season change method with call_deferred. If your map is small enough to be swapped in a single frame, this is the easiest way.
  • If your tilemap is too big to update entirely in a single frame, then you have to split the work somehow. For example swap only the tiles that are on the screen.
    • Or swap the tiles row by row over several frames and call it a feature :smiley: You could make a nice animation out of it (winter spreading around the player…). Or hide the transition with a cutscene or bunch of particles or something.
    • I personally would go for something like this.
  • You could also duplicate the tilemap node, deactivate it, swap the tiles in a background thread and once that is finished, delete the old tilemap and activate the new one in its place.

Hope some of this helps.

1 Like

Currently, I’m dealing with “season transitions” in a very crude way:

I have a main event loop that emits a “transition signal” when it notices that time is transitioning from fall to winter, and all nodes subscribe to this signal. So when they receive this signal, they change their texture to the current season’s texture. Modulation is not an option for me, because different sprites produce different effects depending on the season (snow/falling leaves/etc).

I’ve never thought of alternative tiles before because I split the different seasons into different sprites. It might be a good option if I combine all the sprites into one, I’ll try that later.

Duplicating the nodes and changing the visibility might also be a solution, although it would take up more memory, but considering my game is a pixel game, I don’t think that should be a problem. I also think making a scene to “hide” the process is also an option. In fact, forcing the player to fall asleep at midnight is common in farm games.

Winter spreads around the player… It’s an excellent idea, I’ve seen some effects of this solution and I think it’s great, but I don’t know how it’s implemented. I don’t think changing the texture of the tiles around the player in a for loop would work, I’d also need to split the action into several frames, but I don’t know how to do that right now. (Sorry I’m a beginner and this is my first game.)

Your reply has inspired me a lot, thanks!

1 Like