Optimizing a World / Level Select with Tilemaps?

I am thinking of making a new “world map” for my game. Previously the levels were chosen from a level select menu. I am thinking through optimization challenges.

Previously, each level had a “level preview”, which looked nice, but ended up with well over 70 screenshots in the game, and I think this was a key cause of the menu loading slow and the game booting slower than desired on some older platforms like Xbox One. Screenshot below of the current menu.

So, with the world map, I want to avoid the same problem. The new format I am thinking of is (quick reference images below):

Mode select screen, ie, pick a cluster of worlds that are different game types (classic, beginner, ice sliding, etc)

World select - once you’ve clicked a “mode”, camera zooms in on those worlds, still on the same scene. Then you can pick a world.

Level select - once you’ve clicked a world, camera zooms in on that world. Each level is basically an island in an underground cavern. Select your level. Still have a level preview, but instead of a screenshot, it’s a mini tilemap where abstract tiles, ie, white tile means empty, red means obstacle, and that represents the level layout. And I have a different mini tilemap stored for each level.

So, in short, all of the worlds and their level select screen would be on one big tilemap. And I could zoom in and out at will. Would that be fairly optimized, since it’s all sharing 1 tilemap? Compared to having a menu that has to load 70+ screenshots for level previews?

I guess I could also make each “world” a separate tilemap to flick on and off as well if that would be better.

I’m not sure if there are good and bad ways to handle the different tilemaps for the previews, considering I will have over 70 of them, or if they’re so small (just re-using 5 or 6 tiles) that it’s not an issue? Would having all the different tilemaps as children be fine, and flick them on and off?

Did you profile this, rather than just “think”? :wink:

This isn’t something that should cause delayed loading/booting time if implemented well. You wouldn’t want all these images to be directly assigned to the level preview right in the scene. Instead, each level has a reference to that image and when that level is selected, the preview image gets loaded asynchronously.

As an additional optimization step particularly for consoles, since you can only navigate levels in two directions (here: up/down) the code would not just async load the image for the current level but also the next and previous one (or more). That way most of the time the preview images would be instantly visible when browsing through the level menu.

Perhaps you should consider making those optimizations instead of throwing a working system out of the window on a hunch. :wink:

Hard to say. But I can tell you that the more you zoom out on a tilemap the slower it will render and perform. And particularly large tilemaps are neckbreaking to edit - they still perform well in the game since the visible portion is perhaps 50x35 tiles but if the entire map is 1000x500 tiles, any mass operation in the editor is super slow. That’s because each tile is represented by a GameObject and in this case, that’s half a million of them!

Assuming the tilemap preview is just 50x35 tiles then the entire map would theoretically fit into a tilemap with about 125,000 tiles - although you may need more for visual spacing etc.

So no, my hunch is that the tilemap preview idea is flawed. I’d rather recommend optimizing your current solution, or if you do want that worldmap avoid zooming out as much. I wouldn’t make the “game mode” view a tilemap as well, a menu selection of sorts would work just as well. Having a visual representation for world and level selection should suffice.

The tilemap preview you suggest with the red/white dots seems far too technical and visually uninspiring, I don’t think it’s a good fit. Again, I would just use the existing preview images and async load them as needed.

Thanks for responding. As far as profiling is concerned, I’ve tried multiple times, but I find it hard understanding what I’m doing. However, I’m not making a world map to fix an optimization issue - I’m making a world map because it will be better for the game, regardless. More immersive and will solve some flow issues that will arise from new levels being added, not to mention there are currently too many sub menus. But, I was hoping this new approach might also be more optimized, or at least try and avoid a similar issue.

One of the issues is, my PC is ridiculously fast, and I have not figured out how to debug on the Xbox yet, so that makes it harder.

What I can say is, turning music to addressables gave a big boost (even though the files were only 5-8mb each. And turning the screenshots into atlases and reducing compression did give a noticeable boost, but not enough, so I know it is at least part of the problem. Especially because loading the menu causes a noticeable hitch. Just loading way too many images. And the game has slowed down as the menu got bigger, so I know it’s an issue. You are right, some sort of “addressables” to load the images would have sped things up, it’s also a headache to manage - unless you mean some sort of other async loading I’m not aware of.

Regardless, I want to be careful not to cause similar issues with the new world map. I assume using tilemaps wisely is more optimized than over 70 screenshots.

You said a super big tilemap is slow to edit. Would it be less slow if you used multiple smaller tilemaps?ie, if each “world” (blob on that image) is a single tilemap? And the black is just empty space?

Hm perhaps if I want to do a world map, I may have to come up with a different solution than just zooming in. My have to have separate scenes or something. I appreciate the technical thoughts.

Sure that makes sense. It would add overhead managing 70-ish tilemaps of course but you’re free to leave empty space between them, and move and edit them individually is likely a smoother workflow in the long term, and provides more flexibility.

Thanks I might look into this. For another type of optimization question that’s related, to help me get my head around how boot time works…

If my project had 1000 large images, but none of them were referenced in the first scene, how does that affect boot time? Would it slow down boot time still, or not?

All of my menus currently have prefabs stored in the “resources” folder as per someone elses advice, but ever since then the game has booted slower. I know this can increase boot times, but what I’m not sure is, if I delete the resources folder, and thereby all of the prefabs with public variables referencing those screenshots, whether that’s an accurate quick test to know if it affects boot time? Or, if those screenshots still exist in the project, without a public reference from a script, whether they can still slow boot time? Just trying to get my head around how Unity works in this regards.

My understanding is, if you load a scene, any public variables that reference things like Game Objects or sprites will all be loaded when that scene is loaded, even if you have no instances in the actual scene, just in case you decide to instantiate them.

But, what I don’t know is, how any of that affects boot time if your first scene does not have public references to those assets.

If you had two scenes, one empty and the other one with 1000 images but that’s the second one in the build list, then that Unity build should launch just as fast as without those 1000 images.

Though this may be a little more involved, the build may have some sort of “asset directory” whose initialization time may scale with the number of assets. Though I wouldn’t expect such a thing to be noticeable, just measurable in “split-seconds”.

Nevertheless, asset dependencies aren’t always obvious. If you had those 1000 images referenced in an SO that’s assigned to a script in both scenes, this could trigger loading those images.

The advice some people are giving … :roll_eyes:

Resources are loaded on-demand only. While this gives you full control of when they get loaded, it does require you to write code both for loading them, but also to unload them at appropriate times. Effectively this forces you to deal with asset memory management yourself.

Also, any files in Resources and StreamingAssets are always included in builds, whether they are being used or not.

The last thing I would put under Resources would be prefabs. Images, audio, text files sure, but not prefabs or scenes or ScriptableObject assets. Those are the kind of assets I want to have Unity take full control over their lifecycle, particularly because they are referencing other assets too. Whereas image, audio or text files (et al) are atomic units which do not include or require other dependencies.

That is also my understanding. Which may be wrong, as is known to happen occasionally. :laughing:

Try it out. Just create a new, empty scene and put it to build index 0 so it gets loaded first. This guarantees a zero-dependencies scene gets loaded first. If that affects your launch time significantly you may have some currently unknown/unseen dependencies in your previous first scene. Or there may be other factors like said (presumable) asset directory. And of course any script with a InitializeOnLoad(Method) could also theoretically trigger a code path that ultimately causes assets to get loaded before or during the first scene load.

Also, be sure to test with a release build. If you use IL2CPP set it to “Master” build even because that’s what you’ll publish. Debug builds are slower all around, sometimes unnoticably, sometimes significantly.

I’m not sure how far profiling is possible when it comes to launching a build, but you could make a devug build that connects with the profiler (see Build window settings) and give it a spin.

Some very helpful information here, thank you. Unfortunately, I tried deleting the “resources” folder which had all of the prefabs, and didn’t see a noticeable boot time improvement on Xbox. So I may well have to try and figure out how to profile on the console… But, it also occurs to me, I made sure the game doesn’t go past the loading splash until after certain xbox specific start up processes are done (like loading save file), so that could be making boot feel slower than it technically is, and maybe I should start the dev logos and title screen while this is happening… Should make it at least feel faster.

The only impact Resources has on boot is the time taken to build the look up table for its respective asset bundle (which is all it is, a special asset bundle). It doesn’t have a major impact on boot time.