I’m noticing that if I leave my game running for a long time it’ll start behaving oddly. I’m thinking Unity bugs are to blame but I’d like some feedback.
function deployTeleBeacon(){
audio.PlayOneShot(sound.concussionBlade_deploy);
var newViewID = Network.AllocateViewID();
networkView.RPC("spawnTeleBeacon", RPCMode.All, newViewID);
}
Here’s a snippet showing how I spawn a network object manually. It works fine until eventually something here goes wrong. I can always hear the sound play, but the object isn’t instantiated (which happens in the first line of the spawnTeleBeacon function). I’m assuming the line where that client allocates a new viewID is where we get an error. I have to restart the server to fix it. I’ve noticed some other behavior, but this one seems like the most consistent example.
So what’s happening? Am I using up some limited pool of allocated viewIDs or what? Any way I can fix it? My current plan is to try and get the server to restart itself regularly and send out RPCs telling the connected clients to wait a bit and then reconnect – but this isn’t exactly an elegant solution.
edit: Might have found at least part of my problem thanks to leepo on IRC. In some cases, I wasn’t using Network.Destroy when destroying some objects that had their own viewID, so I guess that viewID was never reused.
so Network.Destroy will cause viewid numbers to be available again for reallocation? because I’ve been wondering if that’s the case or not, and couldn’t seem to find anything.
I you are allocating a lot of IDs and the server runs for a long time you could be running out of network view IDs, we do not recycle them. I can look into support for recycling the IDs or maybe just adding the option of using a bigger variable (would add 4 bytes to every single message). It would be good if you filed a bug report (and emailed me the case number), if you have some logging info from when this starts failing I could have a look at that to verify this is the cause.
I’m surprised to hear that. So basically, servers have a limited lifespan and inevitably need to be restarted? Is there a smooth way to do this (smoother than the method I mention in the OP)?
Unity - Scripting API: Network.minimumAllocatableViewIDs reading this, I assumed viewIDs were recycled and that increasing minimumAllocatableViewIDs increases the number of active viewIDs you can have at any given time. Now I’m confused about what minimumAllocatableViewIDs actually does. Is there any reading material that would help clear this up for me?
Yes, they have limited lifespan but you should have a pretty huge pool. As in 500 million view IDs, but that should very likely be sufficient for weeks of uptime even with heavy use. If you think you are far away from that then probably something is going on and the pool isn’t as huge as it is supposed to be or something else is wrong.
As a limited stopgap you might try recycling the view IDs per client. Just by pusing destroyed/unused view IDs into a queue and pop from that before allocating a new one. Network.minimumAllocatableViewIDs sets the minimum amount of view IDs each client maintains, lowering that might also lengthen the lifetime of the server.
I can confirm now that there is a bug when reading view IDs larger than 16384. When you’ve allocated IDs which fill up the that size it automatically increases the size, the pool goes from ca. ~16000 to ~500 million when that happens. It all happens automatically and works fine when allocating and writing to the stream but it parsed incorrectly on the other side. You can detect when you are about to hit this by checking how large your view ID is or, on the receiving end, check if the view ID you just received is equal to NetworkViewID.unassigned
This is fixed in trunk now and will be in a later Unity release.