TileMapLayers within ParalaxBackground affect performance badly

Godot Version

4.3

Question

Hi, everyone!

I make an endless runner game in a countryside setting. So, the background is presented by several tilemap layers: grass, trees, houses and so on. As I need it to repeat infinitely, I’ve placed it into a ParalaxLayer and mirrored the Layer at 10 * viewport width (12800 px). No camera node, background just moves from right to left within the viewport (the subviewport to be precise).

Unfortunately, on the half of the running cycle the game starts lagging with freezes and kind of jittering. But when the background reaches a new cycle, the lags disappear.

I’ve made some research. At first, I disabled Vsync. It made the game even more laggy but let me saw that FPS drop from 700 to 70 as the character (so the background) runs forward and reset to 700 when the new cycle begins. Then I tried to isolate the problem deleting all obstacles and background tilemap layers except the one. The absolute values became higher, but the drop persisted, now it was like from 4000 to 400. Only when I got rid of the last tilemap layer in favor of a Sprite2d, the problem disappeared and FPS became stable.

So, it makes me think that lots of tiles within a long paralax background somehow create a huge load on the engine. Now I’m thinking about merging some tilemap layers together or even some sort of baking (make the whole background as several big sprites). But it will be quite demanding and inconvenient in terms of further development, so I’ve decided to ask you for help. Did anyone faced similar problem? Maybe I’m missing something and there is a simple solution?

Thanks in advance!

P.S. I also tried to make chunks of tilemap layers and terminate them as they go out of screen, to free memory, but in that case they won’t appear in the next cycle.

Is the tilemap static, or do you change it as it cycles?

It is static. It just repeats making sort of illusion that the character runs in circles.

Ok. I was asking because I’ve found set_cell() can be quite expensive.

Does the problem happen every cycle, or is it just the first cycle? Do you have any shaders on any of those layers?

Every cycle.

No shaders. Though I have some animated tiles and animated sprites as background children.

It looks like that, pixel game 1280x720, in subviewport 640x360. Should not be demanding in theory.

I’ve got a six layer tilemap that’s 32768x32768 in my game, I’m not seeing any lag scrolling it around arbitrarily, and I’ve got it wrapping.

Maybe it’s the parallax layer?

2 Likes

Ooops, I think you’ve opened my eyes. I have more than 20 of tilemap layers, because I was not aware about how demanding they are while I was drawing the map :sweat_smile:

The FPS drop might be unavoidable as paralax moves, but at least I can try to raise it absolute value by minimizing the number of layers, so the lags will disappear…

For those who come after.

Number of tile map layers itself doesn’t really affect the performance, but the rendering of tile sprites do. And I assume that paralax makes it worse somehow. I’ve found that when I make some heavy layers invisible, it makes a huge FPS boost.

So, I’ve come to an idea (not original, tbh) to split the map to chunks and make them visible only when they are about to appear on screen, and invisible again as they disappear from the viewport. It provides 350-400 FPS in my case, almost independent from paralax layer position.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.