Multiple simultaneous levels

Hypothetical setup: I have an authoritative server and two connected clients (one for Player 1 and one for Player 2). When players reach a doorway at the end of each level they are taken to the next level, but they do so on an individual basis. For example, Player 1 can enter Level 2 while Player 2 is still finishing Level 1.

The Problem: The authoritative server must host all levels at the same time. What is a good way to manage these levels on the server? Specifically, I don’t want players on different levels to receive each other’s RPCs and state sync updates. I also don’t want the server to have to run levels when no players are in them.

As suggested elsewhere on the forms, I’ll use LoadLevelAdditive on the server. I’ll probably offset each level in 3D space to keep them separate. This is a good start, but I’m still looking for more.

My Questions:

  1. What’s the best way to make sure players only receive network updates for other players in the same level?
  2. How do I “unload” a level from the server when no players are in it?

Thanks in advance!

there is no such situation as you describe.
the server can be in a single scene at a time, it can’t open more than one.

so if you have a world with multiple scenes available at a time, you need multiple player instances running, each on its own scene and find a way to transfer players between the servers.

Really? Why can’t the server load multiple levels with LoadLevelAdditive? I thought that was the point of the LoadLevelAdditive function, but I perhaps I was mistaken. Can you please clarify?

Thanks!

Using loadleveladditive won’t put the server in more than one scene.

You just expanded that scene by content from another scene.

But its still a single scene you are in and all players in it are within the same single scene.
You would need to use setscope to restrict the updating etc.

Also keep in mind that just adding more and more scenes like that won’t get you too far as the memory requirements and the cpu requirements for the simulation will raise correspondingly too.

And naturally your scenes must be layout to be loaded into a single superscene.

Okay, I see what you’re saying now. If I have Level 1 and Level 2 and load them additively on the server, I’ll still have only one scene, even though it will contain content from both levels. That makes sense.

That said, what about the clients? On the client side, what if I only load one level locally (e.g. Player 1 loads Level 2 and Player 2 loads Level 2)? Each player only sees one level, but the server sees both players and both levels running in one big combined scene.

Do I have that right? And if so, is this implementation problematic. You’ve already mentioned the concern about high memory/processing loads on the server. Are there other major reasons why I should avoid this approach?

Finally, given these concerns, what other ways might I go about structuring a game so the players can (or at least appear to) enter different levels at different times?

Thanks a bunch. Your feedback has been very helpful so far!

You would have to test.
We never loaded additional scenes additively.

But with just a scene and the network instanciate etc if you load a new level on the server, all clients will do soo too.

In Traces of Illumination, I do have multiple levels simultanuously on the server and it works quite nicely. Basically, the server simply loads all those scenes on startup and the geometry is layed out so that there are no overlaps (in the original scenes). Obviously, this won’t work for all types of games but in my case it does work quite well.

You can then use SetScope and SetSendingEnabled(*, false) to make sure the players only get the relevant information. I don’t use the built-in network synchronization and instead do everything myself via RPCs (I prefer control over convenience … up to a certain level :wink: ). I also don’t use Network.Instantiate as that will create objects for all players which is something you obviously don’t want in that setup.

In my case, I’m loading all scenes on the server during startup and keep them in memory (it’s simplified versions of the scene - I don’t need any fancy stuff on the server, just the main geometry for collision detection; the simplification happens during load-time, in other words I destroy everything I don’t need on the server and also disable a lot of stuff). You could probably also put scenes in and out on demand - but that will likely give you trouble because Unity still will hiccup when loading a scene (which is something you obviously want to avoid in a multiplayer environment).

If you want something a bit more interesting you can even do “instanced levels”. For that, Physics.IgnoreCollision is your friend. So, groups of players can be inside a level the same time other groups of players are - without the different groups interacting (but “physically” being in the same locations). That’s only possible with limited amounts of objects, though, because you have to call Physics.IgnoreCollision for every possible combination … so having bullets of a machine gun will probably break that approach (any scenario where a lot of objects are created and destroyed makes this heavily expensive) :wink:

In those cases, however, you might still be fine by doing what I use as “fallback” (I sometimes had the case that IgnoreCollision didn’t have the intended effect and collisions “got through”): Do a relevancy check in the collision handler. But if you have lots of objects you might still have a performance problem in that scenario because the engine still has to check everything (I hope that IgnoreCollision does optimize for such cases :wink: ).

Sunny regards,
Jashan

Hi Jashan,

Thanks so much for the feedback! That’s exactly what I was looking for, and your specific implementation in Traces of Illumination sounds like it will work perfectly with the game I’m trying to make too.

I’m sure I’ll have questions as I try to implement it, so I hope you don’t mind if I reach out to your expertise in the future.

Thanks!

Btw, how many players do you expect? In my tests, with a “somewhat decent” (meaning: not high-end, and not even Mac) server, I pretty much hit the limit around 80 players. That’s for a heavily action based game, though, so your mileage may vary.

80 players seems like well more than I expect at a time. Under a heavy load I was only counting on about 50 players, with the average load being closer to 20 or so. If your setup can handle up to 80 that should be more than enough for my initial purposes.

Cool … 20 players average and 80 max should be really easy. In my case, I was a bit disappointed because I was targetting 200 to 300 per server … but oh well, we live and learn :wink:

Jashan, hi!

I think your implementation is great and very efficient. I just wanted to ask how you handled synchronization of transforms. My object here is changing position and rotation a lot of time. So I don’t think it will be good to use RPCs. But I need to send transform information only to the opponent.

Another thing, how did you instantiate your objects selectively? If I instantiate my object on client A and in client B (the opponent) without using Network.Instantiate, how do I set the networkView owner.

Thanks, Jashan. :slight_smile: