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.
Hello, @GameDevKirk !
It took me a while to test your solution.
My project is on version 5.4 and the source code you provided is different from version 5.5, so I needed to migrate my project to version 5.5 first.
And this is my first time to modify the engine source code to build a custom engine, so it took more time.
After applying the source changes you pointed out, the speed of getting into play mode is very fast, thank you so much!
But I think I still have some work to do. Entering play mode is faster, but the loading speed of newly loaded actors due to movement of the streaming source (character) is still too slow. Some partitions take more than 10 seconds to load and the character is already walking on air. I’ll have to look further into what is causing the excessive loading slowness. Your work has helped me a lot, thank you!
Oh, that’s because of a cheat I created to move the character around quickly.
When enabled, the character can move through the air very quickly. He’s actually flying, but my character’s animation is walking, so… I think I may have confused you.
It’s a very fast movement speed, but it’s still a speed that player can see during play. It’s similar to the speed of the fastest mounts in my game.
You may need to reduce speeds to the lowest avaliable system you want to support Loading Speed wise.
Hoever; 10 seconds is probably unacceptable. Id say more than 1/2 a second is likely not acceptable…
The old system manages loading a streamed level with billions of foliage in like .25s on an older CPU.
Some of it you need to fine tune (because cpu limits), but some of it is probably unacceptable in the current state…