Managing linked areas in a multiplayer environment - Level Streaming needed?

In my current setup, players can either be on the “surface” or “underground”. These areas do not need to be physically connected - the transition between the two areas does not need to be seamless (although I suppose it would be cool if it was).

Imagine a single level with both of these areas existing.


The player is on the surface. The camera is an overhead “top-down” camera, pointing toward the ground and following the player. While on the surface, the player cannot see anything in the “underground” area and they will not be able to unless they transition there. But let’s say this underground area was flooded with actors… tons of actors with tons of materials and components. Does the game “know” the player can’t see this? Would the player lag? I believe they would. (Note: this relates to another topic I posted that remained un-answered, so I was never able to get more information about how this works).

To help with this, I wanted to implement a system where the Underground area would not be rendered by players on the Surface and vice versa. My first thought was that everything underground would be flagged as “Hidden in game” for players on the surface. Then, when they transition to the underground, remove this flag and apply the flag to the surface actors instead. This seems pretty messy as I now need to find a way to effectively flag every object as either underground or surface and loop through all of them when the player transitions. It may be that this is needed but I wanted to explore other options.

I recently discovered Level Streaming. I don’t fully understand it yet but I was able to implement a basic test to see it in action. It did bring up some concerns though since when one player transitioned to the underground, the surface unloaded for all players. Also, I noticed that changes made to actors on the surface were not retained when the surface was re-loaded. This tells me that unloading a level does more than just “hide” it from view, it actually removes the actors involved.. I need the server to never truly “unload” either level. The server needs to keep track of both the surface and underground at all times. The system I am trying to implement is simply a clientside measure to improve performance. I suppose I could run a “is locally controlled” check to only execute the unload/load on the client performing the transition… but then what about the listen server? The listen server needs to keep track of both areas, so are they just screwed in terms of performance?

So for my questions:

  1. Is this even necessary? Is there a better way to tell UE4 not to render things that are out of the player’s camera?
  2. Does a loop to flag actors for rendering sound like a typical and viable option?
  3. Can level streaming be implemented effectively here?

Are you using a listen or a dedicated server?

There is a problem with using level streaming and listen server: every “unloaded” assets on the Server (IE every assets in unloaded levels) are not being calculated by the Server. It thinks of them as being unloaded and therefore is not updating anything in them. Once the Server loads the level, everything works fine for the clients who are inside that level.

To be clear: let’s say you have a floor in your Level_2. The Server’s player is in Level_1 (therefore, Level_2 is not loaded on Server). If a Client’s player travels to Level_2 alone, without the Server’s player, he will just pass through the floor, because his movement is replicated and the server tells him there is no floor.

I don’t have the answer to your questions but I know Level Streaming needs a lot of work to function properly in Multiplayer and I have yet to discover everything I need to do to make it work.

I am using a listen at the moment but I have no issues changing it over to a dedicated server. I will give this some testing to see how it works. Thanks

@Chumble @Yun-Kun

Is this what you are looking for:

**So first of all: **

UE4 does not support more than ONE level being loaded at a time. Or to be more specific, more than one World.

What does that mean?

That means, that if you want to have TWO areas in the world, they both need to be in the same UMAP or at least
use the same persistent level.

In other words, you can’t let a client travel to another level/world. They must be on the same level/world as the Server.

Furthermore, this means that you need to put upperground and underground into the same level, but you need to make sure,
that upperground Player don’t get the underground stuff replicated and other way round.

How could you do this?

First thing you could use is the NetCullDistance. In other words, the distance in which the Actor is relevant for other Actors.

If your two layers are far away from each other, they won’t be replicated to each other. You can adjust he number for this
in the Replication settings of each Actor.

If you are good in C++, you could also override the function called “IsNetRelevantFor”. This mainly decides if the
Actor should be replicated or not. So you would make sure that your Actors have this overridden and then use,
for example, the Actor Tags to mark players as “Upperground” and “Underground”. If these do not match, you
don’t replicate. Of course this is not as easy as it sounds, since things like “PlayerState” or “GameState” should still replicated.

The link that Dartanlla send is actually only a solution if you are willing to replace UE4s current Server System with a custom one.
And while that looks easy in the thread, it needs coding if you want to expand it.