Syncing a random number?

Hello!

So, in my game you have two sides. One side only has one player (Hide and seek type thing).

I’m trying to make a system where the server generates a random number between 0 and the amount of players that there are. Unfortunately I can’t get the result to synchronize. Here is my code…

	public void StartServer()
	{
		
		// Generates random number by taking the amount of players currently connected...
		
		ServerPN = Random.Range(0, m_numberofplayers);
		
		// Calls the map change (Start of the round)	
		networkView.RPC("ChangeMap",RPCMode.Others, m_selectedMapName);	
		ChangeMap(m_selectedMapName);
	
		
	}
		
	
	[RPC]
	void ChangeMap(string mapName)
	{
		Network.isMessageQueueRunning = false;		//Turn on all rpcs until loaded the map
		Application.LoadLevel(mapName);
		
		// Sets the clientside value (Used in the GUI debug) to the random number...
		
		ClientPN = ServerPN;
	}

Unfortunately I’ve gone about loads of crazy solutions to the point where I’m butchering my netcode out of desperation. If somebody could help me I would be eternally grateful, if I have made a stupid mistake please point me in the right direction with pseudo code of some kind. Thank you everybody!

1 Like

At what point are you assigning m_selectedMapName to be equal with the random number generated? When do you send the random number to the clients?

The m_mapselectedMapName has nothing really to do with the random number. I’m just nestling the ‘ClientPN = ServerPN’ inside the changemap value. How would I go about sending the random number to the client? Making an RPC and passing it as a parameter?

EDIT:

		public void StartServer()
	{
		
		// Generates random number by taking the amount of players currently connected...
		
		ServerPN = Random.Range(0, 10);
		
		networkView.RPC("ChangeMap",RPCMode.Others, m_selectedMapName);	
		networkView.RPC("SetPN", RPCMode.AllBuffered, ServerPN);
		
		// Calls the map change (Start of the round)
		
		ChangeMap(m_selectedMapName);
	
		
	}
		
	
	[RPC]
	void ChangeMap(string mapName)
	{
		Network.isMessageQueueRunning = false;		//Turn on all rpcs until loaded the map
		Application.LoadLevel(mapName);
		
		// Sets the clientside value (Used in the GUI debug) to the random number...
	}
	
	[RPC]
	void SetPN(int ServerPN)
	{
		
	
	ClientPN = ServerPN;
		
		
		
	}

Still gives nothing. I’m probably making a really stupid mistake, network code isn’t my strong suit. I also get this error now:

RPC call failed because the function ‘SetPN’ does not exist in any script attached to GameSetup

You can combine it with the Change Map function instead of adding another RPC.

I tried that originally but had no luck so I moved it to a seperate RPC.

You don’t need luck.

If you want to use a separate RPC then that’s fine too but you probably want to send the PN RPC before the ChangeMap RPC, as it looks like your ChangeMap RPC requires ServerPN to be correctly set already.

The error you received implies that you don’t have the right components attached on one end of the connection. To send an RPC, both ends of the connection need to have a component attached with the right RPC method defined. It doesn’t have to be exactly the same method (e.g. you might have a separate component on the server) but the signatures need to match.

I think my problem is just getting the ServerPN to send to clients. At the moment I have the following…

public void OnConnected()
	{
		Network.isMessageQueueRunning = true;
	 	networkView.RPC("AddPlayer", RPCMode.AllBuffered);
		
		
		if(Network.isServer)
		{
                        ServerPN = Random.Range(0, 10);	
			networkView.RPC("TellInfo", RPCMode.AllBuffered, m_multiplayerScript.m_playerName, Network.player);
			
		}
		else
		{
			networkView.RPC("TellName", RPCMode.Server, m_multiplayerScript.m_playerName, Network.player);
			
			
		}
	}

I then have the following script called MYID.cs which holds information sent by the server…

public int MyID;
	public int numberofplayers;
	public int publicPN;

	
	public string IDString;
	private Lobby lobby;
	
	
	// Use this for initialization
	void Awake()
	{
	
	}
	
	void Start () 
	{
	
		
			lobby = GameObject.Find("Lobby").GetComponent<Lobby>();
		
	}
	
	// Update is called once per frame
	void Update () {
		
		numberofplayers = lobby.m_numberofplayers;
		publicPN = lobby.ServerPN;
	}
	
	
	void OnConnectedToServer(){
		
		
		IDString = Network.player.ToString();
		MyID = int.Parse(IDString);	
		
	}
	
	void OnGUI(){
		
	
		GUI.Label(new Rect(10,10,200,50),"MYID " + MyID);
		GUI.Label(new Rect(10,30,200,50),"NOP " + numberofplayers);
		
		
	}
}

So now the brunt of the issue seems to be, how can I pass the variable from the server to the client?

Sorry for all of these dumb questions, network code isn’t easy.

Assuming your TellInfo RPC is getting properly received somewhere, just add it as an extra argument. So I guess somewhere you have:

[RPC]
void TellInfo(string playerName, Player player)

Change it to this:

[RPC]
void TellInfo(string playerName, Player player, int serverPN)

Then change the RPC call to this:

networkView.RPC("TellInfo", RPCMode.AllBuffered, m_multiplayerScript.m_playerName, Network.player, ServerPN);

Then whatever receives this RPC will receive the ServerPN value along with the other data, and you can do what you like with it.

If you have any doubt over whether this RPC is getting received then put some Debug.Log calls in, and enable network debugging too which will print a lot of diagnostic information which can help track down why an RPC is not being received.

Networking is hard to get right, and Unity’s API doesn’t help much. The best thing you can do is try to keep the stuff you’re networking as simple as you can.

I shall try this when I get home. If I’m generating the random number using if (Network.isServer) then it should still pass through fine shouldn’t it?

EDIT: Applied a solution that gave me both the same random number on both machines. Could have been chance so went to test it to find that I had overloaded the masterserver. I shall report back later :wink: