I’ve made each house a level instance, and I’m working on placing the house level instances in the village.
Now that I have a few dozen houses, it’s taking a very long time to open the village level, or to enter play mode from the village level.
In particular, it takes 30+ seconds to enter play mode, which is a pretty inconvenient time lag for iteratively testing and developing levels.
Is there anything I should keep in mind when creating and placing level instances?
I’m wondering if I’m doing something wrong, or if this kind of latency is inherent in Unreal Engine once the level gets to a certain size.
I’m specifically asking about using Level Instances because it would be much faster to create a level of the same size by deconstructing it all into Level Instances.
Hey @hysecha! I’m resurrecting your thread here because our group just ran into the same issue on a project, and we were able to resolve it by making some small changes to the engine code. Changes were tested in 5.5, but should work all the same in previous versions.
The core issue is that the engine is forcing a flush of all level streaming data at a few critical points:
The first point is within GameInstance.cpp, where a flush is forced as part of UGameInstance::StartPlayInEditorGameInstance. The comment seems to imply that only levels relevant to the player will be loaded, but in every test, level instances were flushed regardless of streaming settings and player distance.
Commenting this line out prevents the flush, and results in graceful async loading every time (as long as you’re not using World Partition. We’ll get to that).
But wait, isn’t this being force-flushed for a reason? What did you just break?
So far, there have been no adverse effects from this change, apart from the fact that you’ll now see your level instances pop-in as the async loads complete (which is kinda the point).
A similar flush also occurs when loading any World Partition enabled level. In WorldPartition.cpp, you’ll find two calls to the same blocking function during the WP startup logic.
Commenting these out once again prevented the flush and does not appear to have caused any adverse effects. Everything loads asynchronously, and WP gracefully handles loading the level instances in/out based on distance as expected.
I’ll continue to report back here if we encounter any issues from these changes, or discover a less intrusive way to address the problem.
You broke nothing so long as you manually unload levels, or you do not rely on the fact that “starting again will start clean” in any way shape or form.
I’m guessing that the proper way to handle calling the flush anyway would be to move the functions where they should be - in an Async method where the processing doesn’t cause blocking of any sort.
It would work, because as you demonstrated by commenting things out, stuff works even if the function call never existed…
Idk what edjit at Epic is coding level loading stuff in a game blocking thread in the first place to the extent they even comments to the effect of having to “wait”… but then again, there is your proof - for the nth^n time - that epic doesn’t know what the f they are up to…
Just chalk it off as yet another reason anyone and everyone should just stay away from world Partition…
World composition sure has its issues, but none of them are this basically flawed…
Either way, kudos for sharing.
Even if you should go back and just use world composition instead
Another WTF moment reading this thread, seeing the changes that were needed.
There’s just so many traps to avoid falling into with the whole ‘loading’ side of UE.
Got 1000s of threads bookmarked now (WP / Level-Instances caveats / gotchas).
The async loading sounds great, but have you seen any problems with pop-ins while playing after removing the flush calls?
Also, do you think changing streaming distances or using fewer Level Instances could help if someone can’t edit the engine code?
No issues observed so far. There is pop-in that occurs, but it happens where expected.
As for streaming distance/fewer level instances, neither of these prevented the initial flush from occurring in my tests. You’re stuck dealing with it, the only variable is how long the hitch lasts. More mesh/texture data = longer hitch.
If you want to improve your editor experience, use small test levels as much as possible. If you aim to improve your shipping experience, either don’t use WP as suggested above, or throw up a static loading screen and tell em’ to strap in (this feels so bad).
Thanks for the detailed reply,
It’s good to know that streaming distance and level instances don’t impact the initial flush. I’ll experiment with smaller test levels for now.