Unallocating view ids

Options
Hi everyone,

I have run into a problem with my view id allocation in PUN.
Each player in my game has the ability to throw stones. Once thrown, these stones need to be observed by every client, hence they all have their own photon view. The problem with that is, that after a little while players run out of view ids to instantiate new stones. I found another thread that recommended using a single photon view to synchronize a player's bullets in a fps, but I would rather have them manage themselves until destruction.

Upon further inspection of the PhotonNetwork class I discovered the method "UnAllocateViewID" and tried using it right after my call to PhotonNetwork.Destroy to release the stones view id after it was destroyed. This should fix my problem because the player will never be able to exceed the MAX_VIEW_ID limit at any given point in time. But that did not work as I expected. Most view ids were never unallocated and those that were, were never reallocated.

Is there a way to release unused view ids and reuse them for other photon views?

Cheers,
KB

Comments

  • Tobias
    Options
    If you use PhotonNetwork.Instantiate and .Destroy, you should not run out of IDs. Destroy will free them.
    Exception: you have more items live than MAX_VIEW_IDS. In that case, you are very likely to run into connection issues as well, as each will send updates. Also: If someone new joins a game late with MAX_VIEW_IDS items, the client is likely to be overwhelmed by instantiate requests.
  • When and how are IDs freed by PhotonNetwork.Destroy? I am only using PN.Instantiate and PN.Destroy and I am sure I do not have more items than MAX_VIEW_IDS. I increased the limit to 2000 for testing purposes and the problem still occurs, but the player did not have 2000 items (with a photon view) under his control in the scene, neither did the scene itself have that many live items.

    The latter problem should not occur to me as player's cannot join rooms midgame.

    Could there be anything else causing this?
  • Tobias
    Options
    Destroy will allow re-using the viewID immediately locally. At least in theory.
    How many items do you have?
    Can you post the console output you get? If something in PUN goes wrong, it should have some output and I know more about it then.
  • Each player can have a maximum of 45 items, theoretically. In reality, some of the items will be destroyed after mere seconds so it is quite impossible to actually reach that number of items.

    The first occurrence of the problem generated this output:
    output_log wrote:
    Exception: AllocateViewID() failed. User 1 is out of subIds, as all viewIDs are used.
    at PhotonNetwork.AllocateViewID (Int32 ownerId) [0x00000] in <filename unknown>:0

    at PhotonNetwork.Instantiate (System.String prefabName, Vector3 position, Quaternion rotation, Int32 group, System.Object[] data) [0x00000] in <filename unknown>:0

    at PhotonNetwork.Instantiate (System.String prefabName, Vector3 position, Quaternion rotation, Int32 group) [0x00000] in <filename unknown>:0

    at CGladiator.AddTag (Int32 _TagID, .CGladiator _Originator) [0x00000] in <filename unknown>:0

    at CGladiator.RegisterHit (Single _HealthDelta, Int32 _TagID, .CGladiator _Originator) [0x00000] in <filename unknown>:0

    at CGladiator.RegisterHit (Single _HealthDelta, Int32 _TagID, Int32 _OriginatorID) [0x00000] in <filename unknown>:0

    at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&)

    at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0

    at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0

    at NetworkingPeer.ExecuteRPC (ExitGames.Client.Photon.Hashtable rpcData, .PhotonPlayer sender) [0x00000] in <filename unknown>:0

    at NetworkingPeer.OnEvent (ExitGames.Client.Photon.EventData photonEvent) [0x00000] in <filename unknown>:0

    at ExitGames.Client.Photon.PeerBase.DeserializeMessageAndCallback (System.Byte[] inBuff) [0x00000] in <filename unknown>:0

    at ExitGames.Client.Photon.EnetPeer.DispatchIncomingCommands () [0x00000] in <filename unknown>:0

    at ExitGames.Client.Photon.PhotonPeer.DispatchIncomingCommands () [0x00000] in <filename unknown>:0

    at PhotonHandler.Update () [0x00000] in <filename unknown>:0

    (Filename: Line: -1)

    In this situation, a player was hit by a stone. The hit was registered on every client (CGladiator.RegisterHit) which resulted in the addition of a new tag to the hit player (CGladiator.AddTag). This method instantiates a new item with a photon view, at least it tried to before failing because it could not allocate a a new view id.

    EDIT:
    I just reduced MAX_VIEW_IDS to 100 to see how fast the problem would occur and everything seemed fine. The player only uses two ids persistently and releases the others properly. I don't know how he could run out of ids.
  • Tobias
    Options
    Please keep us posted if this issue "stays" resolved.
    It should work with 1000 (the default) as well.
  • tethysinteractive
    edited May 2016
    Options
    NM, Found the UnAllocate() command just trying to work it into our workflow now.
  • maxmax
    maxmax
    edited December 2020
    Options
    Tobias wrote: »
    Destroy will allow re-using the viewID immediately locally. At least in theory.
    How many items do you have?
    Can you post the console output you get? If something in PUN goes wrong, it should have some output and I know more about it then.

    wow this is so old topic and so important question - surpisingly this mechnism is not working! im creating with photon.instantiate and destroying with photon destroy and viewid for new gameobjects keep creating from latest viewid and more so my whole 1000 range is filled up in just like couple of minutes and no workaround no fix is possible except making a custom serialization with mask bitwise collector unique id gameobject separator on top of the existing pool and network event patterns. fantastic absurd been thinking all the time using photon that this possibility is excluded 100% PUN 2.25 Photon lib 4.1.4.7 with unity 2020.1.2f1

    well ive tested again it does seems that it doesnt unallocate but it is view id for all new prefabs is being used with higher view id BUT since it goes up to x999 allocator uses freed one from bottom of the freed array so there is no bug in this version of photon at least for my knowledge
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited December 2020
    Options
    Hi @maxmax,

    Thank you for choosing Photon!

    I just did a quick test.

    ViewIDs are reserved / locked once 'claimed' / allocated.
    ViewIDs are recycled and reusable once free / unallocated: meaning after network destruction of the corresponding networked GameObject/PhotonView.

    But the error "Exception: AllocateViewID() failed. The room (user x) is out of viewIDs. It seems all available are in use." is probably due to something else:

    The room and each actor can have up to PhotonNetwork.MAX_VIEW_IDS - 1 of PhotonViews.

    For the default case of `MAX_VIEW_IDS` equal to 1000:

    - ViewIDs multiple of `MAX_VIEW_IDS` are not used: 0, 1000, 2000, etc. until 2,147,483,000.
    - Default ViewID 0 is special and reserved, it means that a viewID is not allocated yet.
    - Scene objects have viewIDs between 1 and 999.
    - Actor number 1's objects have viewIDs between 1001 and 1999.
    - Actor number x's objects have viewIDs between `x * MAX_VIEW_IDS + 1` and `(x + 1) * MAX_VIEW_IDS - 1`.
    - Actor number 2,147,483's objects have viewIDs between 2,147,483,001 and 2,147,483,647. Only 647 possible values since we hit the `int.MaxValue` limit.