Help with Sync a Deck of Cards

Good day. I am trying to sync a deck of cards over the network. The deck is made up of 52 playing cards on which i have photonViews on the card object and also on the Deck object.

I want to use the master client to Instantiate the deck, intialize it, shuffle it and kick the top card of the deck then send this shuffled deck to each client accross the network. I am able to instantiate it on each client but each one has it shuffled differently so when The kick is done each click has a different kick card.

I am using RaiseEvent to spawn the deck and an RPC to try to Sync it.

SpawnDeck Method

public void SpawnDeck()
{
gameDeck = Instantiate(deckPrefab, Vector3.zero, Quaternion.identity);
gameDeck.transform.SetParent(gameDeckUI.transform, false);
gameDeck.GetComponent().InitializeDeck();
gameDeck.GetComponent().Shuffle();
gameDeck.name = "Deck";
Deck deckScript = gameDeck.GetComponent();
GameObject deckGO = GameObject.Find("Deck");

UpdateDeckUI(deckScript, deckGO);

PhotonView photonView = gameDeck.GetComponent();

if (PhotonNetwork.AllocateViewID(photonView))
{
object[] data = new object[]
{
gameDeck.transform.position, gameDeck.transform.rotation, photonView.ViewID
};

RaiseEventOptions raiseEventOptions = new RaiseEventOptions()
{
Receivers = ReceiverGroup.All,
CachingOption = EventCaching.AddToRoomCache
};

SendOptions sendOptions = new SendOptions
{
Reliability = true
};

PhotonNetwork.RaiseEvent(CustomManualInstantiateEventCode, data, raiseEventOptions, sendOptions);
}
else
{
print("Failed to allocate a ViewID");
Destroy(gameDeck);
}
}


OnEvent CallBack

public void OnEvent(EventData photonEvent)
{
if(photonEvent.Code == CustomManualInstantiateEventCode)
{
object[] data = (object[])photonEvent.CustomData;

GameObject GD = (GameObject)Instantiate(deckPrefab, (Vector3)data[0], (Quaternion)data[1]);
PhotonView photonView = GD.GetComponent();

photonView.ViewID = (int)data[2];

}
}

My StartMethod

private void Start()
{
PV = GetComponent();
Photon.Realtime.Player[] players = PhotonNetwork.PlayerList;
if(players != null && players.Length == 2)
{
if (players[0].IsLocal)
{
LocalPlayerName.text = players[0].NickName;
RemotePlayerName.text = players[1].NickName;
}
else
{
LocalPlayerName.text = players[1].NickName;
RemotePlayerName.text = players[0].NickName;
}
}

SpawnDeck();

PV.RPC("RPC_Kick", RpcTarget.All);

}


My RPC_Kick Method

[PunRPC]
private void RPC_Kick()
{

kickCard = gameDeck.GetComponent().Kick();
kickCard.transform.SetParent(kickCardsGO.transform, false);
kickCard.transform.position = new Vector3(-5.7f, -1.6f, 0);
kickCard.GetComponent().ToggleFace(true);

}


Can someone help me with syncing the deck across the network?

Comments

  • Hi @Punisher,

    is it necessary that each client knows the shuffled deck? You can also use the MasterClient to deal cards to the other players. In this case only the MasterClient has to know the shuffled deck. Dealing cards to other players can be for example done by using the RaiseEvent function. This would also have the benefit, that the deck doesn't run out of synchronization because only the MasterClient manages it.

    If you still want to have the deck synchronized on all clients, you should think about giving the cards unique identifier, for example unique IDs from 0 to 51 or similar. You can "shuffle" these numbers locally on the MasterClient and add them to an array. These array can be sent to other clients by using the RaiseEvent function.

    One other thing: right now each client calls the above shown Start function and furthermore each client calls the SpawnDeck function as far as I can see. This results in each client allocating a ViewId for the PhotonView component and raising an event. It is enough if only the MasterClient does that.
  • Ok thanks for the help. I will try what you have suggested. The master client will instantiate the deck and shuffle deal and kick. Each client will have to see the same kick card in order to know what suit is trump. How do I achive this?
  • Also I would like a visual representation of the deck on each client
  • Ok thanks for the help. I will try what you have suggested. The master client will instantiate the deck and shuffle deal and kick. Each client will have to see the same kick card in order to know what suit is trump. How do I achive this?


    If you have the deck synchronized on all clients, the MasterClient can simply raise an event that tells each client, to show the top card of the deck.

    If you don't have the deck synchronized, the MasterClient can raise an event nevertheless, but this time he includes the type of the card in this event. When thinking about this scenario (without synchronizing the entire deck), I'm thinking about a deck of blank cards. The shuffled deck is only logically stored as a list for example. Now the MasterClient raises an event to turn over the top card of the deck. He checks his logical representation of the deck and adds the type of the top card to the raised event. Whenever a client receives this event, he can replace the blank card on top of the deck with the card's information he has received. Then he can turn over the card.
  • I have a card script which and a card game object. The deck game object has a List cards that is the deck. The deck also has methods to intialialize, Shuffle and Draw A card from the deck. So my deck of cards is really a list of card GameObjects