Hi,
I am trying to implement a feature as follows. We have a BigWorld map with World Partitions enabled. The player starts connected to a dedicated server. The mission requires the player to be phased into a local standalone game, of the same map starting with the same location, to do some fighting stuff. After the fight the player will be phased back to the DS, right where the fight ends. So the feature involves the player world traveled from the DS to local first then back to DS, all happened with in the same level map. Most of the world’s enviromental states should remain unchanged during the travel. But due to the way how engine works we still need to reload the map to cleanup things from the old world and reinitialize the game logic. The reloading process takes 4 seconds or maybe longer, which is totally not acceptable in my cases.
After digging into the LoadMap process, I found that before destroying the old world all partitions will be forced streaming out. After the new world being created, it will flush its streaming state and stream these partitions back. It takes a significant amount of time. Is there anything I can do to improve this? like:
1. Try to reuse the streaming state between the two levels, so that no levels will be streamed in/out during the map reloading process?
2. Even if the partitions must be streamed out, could we keep the levels loaded in memory (there is a TrimMemory during LoadMap and when I tried to disable it I found the cleanup of other unwanted entities (like actors from the old world) depends on the trim) thus we do not need to reload it back from the disk when the new world initialize its streaming state?
Thx
Hello,
After discussing this with a colleague familiar with the networking side of things, it seems that reloading is unavoidable. When connecting to the server, the client has to unload their level and then load the server’s level, regardless of whether they are the same. Unfortunately, I haven’t really explored what you’re trying to do to be able to advise on whether modifying some engine code might be feasible, and you’ll most likely need to investigate and experiment.
Here are some other cases that seem like they might give you more insight around this:
- [Content removed]
- [Content removed]
- [Content removed]
Thanks,
Ryan
As a supplement, the loading we **may** have wanted to avoid can be found in the following trace. I think both of them happened during UWorld::FlushLevelStreaming.
[Image Removed]I’ve also tried root refering LevelStreaming’s Level, World, Persistent Level, etc. None of them worked for me. Any ideas?
Thx
Currently, there is not really any control over the granularity of what is reloaded when going through LoadMap. Regarding your question about PIE, the sublevels are temporarily generated at runtime. This doesn’t apply to packaged builds, which will have the sublevels generated during cook time.
It’s unclear from the capture, but I wonder if the first flush is to finish any loading that was happening for the “old world” while the second one is for the “new world”? With the second one showing that it’s called from UWorld::FlushLevelStreaming, I don’t think the first is as well, since I would also expect it to show up in the capture. You may want to temporarily enable additional channels or use `stat named events` just to be able to gather more details in the capture.
I’ve also tried root refering LevelStreaming’s Level, World, Persistent Level, etc. None of them worked for me. Any ideas?
Could you expand on what you tried and what happened?
-Ryan
Sorry for the mislead. We have modified the Standalone world creation procedure a little bit that the WorldBeginPlay has been delayed by several frames to wait for further instructions from the Global Game Server. So there are two AsyncLoading in the trace, with the first one being AsyncLoading the level itself (or any other resources required to load the Persistent map itself), the second one being the World Partiton init force loading during the WorldBeginPlay period.
[Image Removed]
We have also found that the loading of levels/streaming levels are very different from the other resources. If I stream in two sublevels of the same map, there will be two individual packages and level instances created. So simply keep the loaded levels from the old world does not avoid a reloading from the new one. This explains, as the content you have pointed out in my previous questions, root refering Level/World/PersistentLevel does not help reduce async loading time, the levels will be reloaded anyway.
I’ve tried another solution and made some progress. Before the old world being destroyed I remove every single actor from the old world’s streaming levels, keep it root referred and release them when the new world is fully loaded. This seem helped preserving some of the resources at least, as you can see from the following traces (compared to the one I provided above, without root refering the actors). Still I think the levels themselves are reloaded after all.
[Image Removed]
It would be very great if you could help us with the last mile. Thx.
At this point, I’m not sure I can offer much help here as I haven’t had a chance to explore this myself.
-Ryan
Actually in a previous on-site support we have discussed this issue. It has been revealed that Unreal had been working on a seamless cross-DS travel mechanism to support a bigger seamless server world consist of multiple Dedicated servers of the same map, with each one them hosting an individual subregion. Theoretically seamless travel between Dedicated servers of the same map, without reloading the map on Client is possible.
What we have wanted is travelling from DS to standalone, and then backwards. This is hard and a map reload is inevitable due to the fundimental differences between a client world and a standalone one. We need to create a GameMode for the standalone world, recreate and reinitialize almost every actors and WorldSubsystems for the world for their logic (or even if the subsystem should be created or not) may vary in two net modes. So we totally understand we need to go through the LoadMap process. We have also figured out how to retain the player pawn and camera state from the old world and transport them to the new one.
But since the level map and streaming source location is the same, we were wondering if it is possible to protect the consistent resources from GC, so we do not need to reload them again afterwards? As a trial, I plan to make an reference UObject, make it refer all the loaded streaming levels and add it to the root, then unref the levels and delete the object after the new world has flushed its streaming state. I do not know if it would work, or is there any more efficient or maybe more formal way to do this?
Thx
Also in Editor I found the aformentioned way does not work. Is it because the World Partition streaming levels are acutally generated memory-only temporary assets (As the figure below shows)? Would it work in a packaged client?
[Image Removed]