How do you setup and work with multiple levels in a single-player game?

Up until now I had only one persistent level with several sub-levels in my projects. I’d load one “main” sub-level and then stream (load/unload) other sub-levels as needed. My projects were of a small scale and it worked fine for me.

Now I am wondering how does one go about setting up level structure for a single-player game with let’s say 20 levels. I’d like to have one or two hub levels where player comes back after beating other levels (let’s say a town from which player can go into caves, catacombs, another districts, etc.)

Do I still keep it in the same format with one persistent level and bunch of streaming sub-levels ?

Do I need to make each level to be a persistent level? In this case, how do I unload level once players beats it and how do I load next persistent level ?

How do I transfer stats (opened/unlocked doors, some dead enemies, solved puzzles, etc.) from one persistent level to another ?

Thanks beforehand

Yes, each level would be completely independent, loaded using the openLevel() function, which unloads the current level and loads the one you specify. Be aware that this destroys everything, including PlayerController, gameMode, gameState, playerState, etc. To persist information between levels you use the GameInstance object, which is the same for the entire time your game is running.

The advantage of this approach is that it’s much easier to test specific levels, since you can open and play directly on them without having to go through the streaming process first. The downside is you cannot have “seamless” worlds this way, of course. Setting up custom loading screens also requires a tiny bit of C++ (or a free plugin that does that for you).