Search Unity

Resolved Some ServerRpc calls not working

Discussion in 'Netcode for GameObjects' started by MidniteOil, Feb 1, 2023.

  1. MidniteOil

    MidniteOil

    Joined:
    Sep 25, 2019
    Posts:
    345
    Greetings,

    Unity 2021.3.16f1
    Netcode for GameObjects 1.1.0

    I'm making really good process on a multiplayer card game but have run into a bit of a snag which seems to me to be a bug.

    I have this OnStopDragging() method that gets called when the player drops a card. I populate a DropData struct (that implements INetworkSerializable) and make a ServerRpc call:
    Code (CSharp):
    1.     void OnStopDragging(CardUI cardUI)
    2.     {
    3.         if (!_dragStack.DropTarget)
    4.         {
    5.             DropRejected();
    6.             return;
    7.         }
    8.         _dropData.PlayerId = MatchmakingService.CurrentPlayer.Id;
    9.         _dropData.SourcePileId = _cardPiles[_dragStack.SourceStack].PileId;
    10.         _dropData.CardId = _dragStack.Cards[0].Card.CardId;
    11.         _dropData.DestinationPileId = GetCardPileFromTransform(_dragStack.DropTarget.TargetPileTransform);
    12.         Debug.Log($"OnStopDragging - calling _gameManager.AttemptDropServerRPC");
    13.         _gameManager.AttemptDropServerRpc(_dropData);
    14.     }
    15.  
    On the host I determine if this is a legal drop (it might not be if another player beat this player to the spot) and either makes a DropAttemptRejectedClientRpc() call or a CardPlayedClientRpc() call if it was legal. All the clients will process the play in that case.
    Code (CSharp):
    1.     [ServerRpc(RequireOwnership = false)]
    2.     public void AttemptDropServerRpc(DropData dropData)
    3.     {
    4.         Card card = GetCardById(dropData.CardId);
    5.         CardPile destPile = GetPileById(dropData.DestinationPileId);
    6.  
    7.         Debug.Log($"Drop attempt: Card: {card} to pile {destPile}");
    8.         if (!destPile.IsLegalDrop(card))
    9.         {
    10.             DropAttemptRejectedClientRpc(dropData.PlayerId);
    11.             return;
    12.         }
    13.        
    14.         CardPlayedClientRpc(dropData);
    15.     }
    16.  
    17.  
    This works beautifully, MOST OF THE TIME. But occasionally I've gotten to a point in the game where the server never receives the AttemptDropSErverRpc call from the client.I get the log output when making the call but never get the log output for when the call is received (in the case where the host player is trying to make the drop). I have also verfied this behavior in the debugger.

    I'm not getting any errors. The server simply never receives the call.

    Is this a bug or can y'all see anything wrong with my code?

    Here's a video demonstrating the issue:


    The issue starts happening at 1:57 in the video
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,005
    If this is on the host, the call to AttemptDropServerRpc should be a local method call. Meaning it cannot get lost via transport, so I would suspect that the method isn‘t actually called on the host for some reason.

    You could add timestamps to your log to make sure sou aren‘t misreading previous logs as being related while they ,ay be seconds apart.

    In case this is a Netcode bug you could try upgrading to v1.2 or check the Netcode changelog before doing so.
     
  3. MidniteOil

    MidniteOil

    Joined:
    Sep 25, 2019
    Posts:
    345
    Thanks, I literally stepped over this call in the debugger and tried to step into it. For reasons yet unknown it simply isn't making it into that function on these rare occasions. I'm gonna wrap it in a try/catch and take your advice and look at the Netcode changelog. I didn't know an update was available. I'm still in early stages of development and under full source control so it can't hurt to try and upgrade.
     
  4. MidniteOil

    MidniteOil

    Joined:
    Sep 25, 2019
    Posts:
    345
    Okay, my initial assumption was false. The ServerRpc function is getting called. I thought it wasn't because apparently, when debugging, I don't see log messages from the server function nor do I hit breakpoints inside them (and I can't step into them). This makes debugging server issues tricky.

    By passing more detailed log messages back to the client I've determined that the server is rejecting the drop in some cases. I must have an issue in my IsLegalDrop() logic I need to fix. Time for some unit tests I think.