[Non-Authoritative][C#] coding practices

Hoi,

I’m currently playing around with some non-authoritative networking, looked at some examples, tutorials and wrote some “working” code of my own. But what I’ve experienced so far is that most scripts end up in a cluster fuck of “isServer / isClient segments”. I tried to separate client and server scripts, but since both “views” must have all RPC methods … its no improvement.

So I’m wondering if anyone has some brilliant/simple solutions that don’t require to write redundant code, or cluster fuck everything with server/client statements.

Here’s an example:

	private void FixedUpdate()
	{
		moveInput.x = Input.GetAxis("gamepad_leftX");
		moveInput.z = Input.GetAxis("gamepad_leftY");
		
		if (Network.isServer)
		{
			SendMessage("Move", moveInput, SendMessageOptions.RequireReceiver);
		}
		else
		{
			networkView.RPC("Move", RPCMode.Server, moveInput);
		}
	}

	private void Update()
	{
		if (Input.GetButton("gamepad_useAbility0"))
		{
			if (Network.isServer)
			{
				SendMessage("UseAbility", 0, SendMessageOptions.RequireReceiver);
			}
			else
			{
				networkView.RPC("UseAbility", RPCMode.Server, 0);
			}
		}

		if (Input.GetButton("gamepad_interact"))
		{
			if (Network.isServer)
			{
				SendMessage("Interact", SendMessageOptions.RequireReceiver);
			}
			else
			{
				networkView.RPC("Interact", RPCMode.Server);
			}
		}
	}

Not that I use the unity networking, but one easy solution is to have two classes which inherit from MonoBehaviour, which look like this:

    public abstract class SeverMonoBehaviour : MonoBehaviour {
        protected void Awake () {
            if (Network.isServer == false)
                Destroy(this);
        }
    }
    
    public abstract class ClientMonoBehaviour : MonoBehaviour {
        protected void Awake () {
            if (Network.isClient == false)
                Destroy(this);
        }
    }

and then inherit from these two, to split the client/server stuff

^that will probably clutter your project with basicly 2 seperate solutions.

You’d be better off making a class that inherits Monobehaviour, and use that as your base inheritance class. This is advisable anyway, so you can easily add functionality to all your components. Then, you can add a RPC method, which will do the same internally as you do now.

public class ScripBase : MonoBehaviour {

public void RPC(string message) {
         if (Network.isServer)
            {
                SendMessage(message, SendMessageOptions.RequireReceiver);
            }
            else
            {
                networkView.RPC(message, RPCMode.Server);    //you can also do some error checking here if there is no networkView
            }
    }
}

This will result in code like this:

    private void Update()
    {
        if (Input.GetButton("gamepad_useAbility0"))
        {
            this.RPC("UseAbility");
        }
    }

apart from the much cleaner code you get in your components, it also makes it easy to switch to a 3rd party networking solution if you decide to do so later on. Just replace the function in your scriptBase and you’re done :slight_smile:

Thanks for the quick answers guys!

@wasstraat65:
Thats a nice solution, I’ll put it to use! Thanks for sharing!