Unity and Instancing

I’m looking into how one might create instances in a Unity based network hosted game. Any advice or examples of implementing such a beast? I have been reading up on RakNet as of late but don’t see anything directly supported.

This would be instances in the MMO sense, where a portion of the world is cloned and run as it’s own separate instance from the main world. For example a group of players might enter a dungeon, and then be moved to an instance of the dungeon where only they were present. Other players that came along and entered the dungeon would be moved to their own instance of the dungeon.

Assuming you wanted to run all of the instances on the same server instance, my best guess at a solution would be to have some logic on the server that organises a group of players, plus one of each of the NPCs found in the instance (assuming there are any) into a restricted network group where:

  • Each player only receives RPCs and state synchronisation relevant to members of that players group.

  • Any game logic such as attacks, inter-character collisions, NPC aggro and so on is restricted to interactions between members of the same group.

This would mean that the server may have to handle several groups of players and a equal number of copies of each NPC, so you would need to have some kind of server solution that is capable of handling that number of objects and player connections. Ultimately what would be ideal is to have some kind of clustering solution that would enable the processing for the game world and all of its instances to be spread across multiple servers. But I have no idea how you would achieve that with Unity (my knowledge of Mono is a little limited when it comes to that kind of complexity).

Some things worth checking out in the Unity documentation in order to achieve this kind of functionality are:

NetworkView.SetScope

Network.SetReceivingEnabled

Network.SetSendingEnabled

How I would do it ( and how I suspect people like Blizzard do with their MMOs ) is to have the game world on one server, and a separate dedicated server for instances, with a maximum number of instances it can handle. If it exceeds this number, a second instance server is used in addition to the first, and so on.

There would have to be a limit to the number of players that can be connected to the world server, so that you know how many instance servers you need per world server. The limit would depend on how much data the servers are required to handle.

You would need a way to maintain the player limit, so that it does not drop when a group of players enter an instance. A simple way would be to keep a log of who is online, and only set them to offline if they log off. This way, an accidental disconnect can still be recovered ( logged in to where the player was without having to wait for a queue ). Or have a max offline time ( say 15 minutes ), and log them off if they haven’t reconnected by then.

But I’ve never ever done anything I just listed so I really don’t know how plausible it is.

Ok well I’m going to be using a server called SmartFoxServer (www.smartfoxserver.com) as the authorative server for my MMO; what this allows you to do is to have seperate rooms (which will in the main game world be each major section of the game). It also can allow users to make their own room; so what you could do is for each instanced group, add them all into the same room on smartfoxserver and then limit the updates for the instance to only receive updates from users of that room/ instance.

So what you could do is have the authorative server spawn mobs/ only send information regarding users in the same group/ room; while using the same instance on the unity game server.

(I must say at this point I am very new to this and am only just starting to learn about MMO development so what I’m saying may be utter crap, or have major security flauws which I can not yet realise).

I’d say there’s two important issues to be handled with instances:

a) handling server-transfers (world-server to instance-server and back)

b) handling multiple groups of players in the same “location” without interfering with each other (people playing in different groups in the “same” instance on the same server)

Obviously, how these things are implemented largely depends on what you’re using as server infrastructure. SmartFoxServer would be one option definitely worth looking into. Personally, I like the actual game-server to be a Unity server. Since Unity doesn’t support simultanuous connections to multiple servers, a) is a little bit tricky.

I guess one of the main points in having instances is load-balancing, so in my opinion, it only makes sense when you have the ability to switch servers when switching instances. That’s why a) is important to look at.

The approach I would use with Unity would be handling the event that players “enter the instance”. The group would get a token, and it would be determined which server the group will “land on”. Before leaving the “world server”, each participant of the group would get the information which instance server to connect to. Then, the connection to the world server would be closed, and a connection to the particular instance server opened. This will result in “zoning”, i.e. there will be a little delay between the “world” and the “instance”. However, that’s something people are used to from WoW, so I guess that’s nothing to worry about.

I haven’t done this, but it would probably work. Obviously, you need something “behind the servers” that the game and instance servers can use to communicate. There’s a couple of options for that, but I guess the simplest one would be the backend-database that’s used for persistence anyways. Another option would be socket connections between the servers.

Anyways, for b) I can actually offer “first-hand experience” because that’s something I’m doing in Traces of Illumination. There, when multiple game groups play in the same level, it’s pretty much exactly the same as if multiple groups would play in the same instanced “dungeon” (one of the reasons I implemented it that way was to have a simple test-case for future projects which will be more MMO-like :wink: ).

So, what I do is assure that no collisions are detected between players or objects of players of different game groups, and that network messages are sent out to the players that are interested. Since Unity 2.1, one would do that with NetworkView.SetScope and Network.SetSendingEnabled, as Nekharoth pointed out. I think Network.SetReceivingEnabled is not so useful for this scenario (I’ve tried that, and if you search the forums for SetReceivingEnabled you’ll probably find out what was the problem with that approach :wink: ).

As I’ve implemented this before 2.1, and haven’t had the time to convert to the new features, I’m using my own approach (sending directly to the players, which I keep in lists), but that’s probably a little worse when it comes to performance.

For the collision partitioning, you can use Physics.IgnoreCollision - however, I also have added checks in the actual collision event handlers because in my tests, it sometimes happened that even though IgnoreCollisions was used for the objects, some collisions still “came through”.

Finally, you need to instance all NPCs and game objects specific to one group. In Traces of Illumination, the power-ups exist only one time, and each game group “knows” which power-ups have already been collected by players of that game group. I guess there’s a couple of options how to approach this - in my case, anything that doesn’t move around exists only one time, and everything that can move exists for each group.

All in all, I think instances should be quite doable with Unity, but do not understand the complexity involved - as with everything that has to do with MMO. For instance, think about how you will test this - you either need a lot of people willing to play this during development, or you will need to create bots who simulate players. Even if you have thought about the design a lot, and tried a very careful implementation, multiplayer (especially “massively multiplayer”) has a tendency to have lots of bugs you’ll only find through testing; but at the same time, testing multiplayer (especially “massively”) is a huge challenge on its own (especially during development, where the bugs are cheapest to fix).

Personally, the only limitation I see with Unity on this is not being able to connect to multiple servers (haha, and the old “when will we get headless servers?”). I’m hoping that I’ll find a way to tweak Raknet in a way that I have some sort of “proxy-layer” to fix the issue with multiple servers, but that’s a future project and I have no idea, yet, if it’s even realistic :wink:

I’ve noticed that 2.1 no longer puts a camera in for you if you don’t, so that’s kind of a step closer…you still have a window, but no rendering overhead.