How would I make a non-laggy Metroidvania that is not composed of rooms?

This is quite a theoretical question and is not about a specific problem in an existing project.

I would like to make a 2D Metroidvania whose world map is not composed of distinct rooms but rather a 100% seamless world where even areas don’t have clear limitations. One of the advantages of this would be allowing me to design a really nice fast-travel system that uses underwater currents to push the player towards their destination, much like on Timer Hearth in Outer Wilds. I think the easiest way to make the map would be with a Tilemap but I do not know if there is any way to make a sort of “render distance” with Tilemaps that would completely disable collisions, rendering and navigation layers of tiles that are at a certain distance from the player (very similar to the techniques Minecraft uses not to blow up your computer even though the world is HUGE).

So here I will make my question clear:

  1. If I want to make such a Metroidvania, would I be able to make this not laggy?
  2. If yes, should I use a Tilemap to make the world or another node?
  3. And lastly, how would I make anything far enough from the player be disabled so that it does not take too much computing power, including tiles from the Tilemap?

For info, I am using Godot 4. Thanks in advance to anybody that takes the time to answer my question!

1 Like

The best way to find out is to test it by quickly putting together a large level with some sprite assets, though I reckon it’s going to be difficult.

That being said, I’m currently doing a version of this with my game. Instead of the screen fade in and out during room transition in most metroidvania, I wanted multiple rooms to be once seamless huge level and it has been working so far. It’s not a whole map as seamless levels but it’s definitely bigger than most metroidvanias have without the fade in. Right now, there’s probably about 15 rooms I’ve put together in a seamless fashion this way.

What I did was to separate group elements/objects in an area/room under the same CanvasGroup so I could hide or not process it once the player is not in the room. There is also a visibility notifier node you can make use of to help with this. So far, I’ve not faced performance issues but I’m sure if I try to fit a whole map this way, there will be issues.

In summary, you need to figure out a way to load and unload chunks of the level. You can take a look at the video in my post here to get an idea of how large the level is.

It will be difficult to do, but I’m sure it’s not impossible. You just need to find what works for your game.

As a bonus thing to think about from my experience, cameras are a pain to deal with for seamless large levels. The constant need to change camers parameters on the fly is something you also have to figure out.