Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Chat Example

Brent Farris edited this page Aug 17, 2020 · 10 revisions
Directory Previous Next
Directory Examples Spawning Example

Running the sample

Forge Alloy Chat Example - How to run it

Chat is about as basic as we can get for an example of networking as the only thing to worry about is sending a string across the network and when it arrives we display it in some way to the player. To start we need to tell the game that we wish to open the chat example when we host/connect.

  1. Open the MultiplayerMenu scene
  2. Click on ForgeMain in the hierarchy
  3. In the inspector, change "Scene To Load" to be Chat

This scene (Chat) can be located in the Assets/Examples/Chat/Scenes folder.

We'll start by testing out the chat sample and then we'll check out the code. To do this, we first need to make sure that Unity is setup to build the project correctly.

  1. Open Unity's build settings
  2. Ensure that the first scene to build is set to MultiplayerMenu
  3. Ensure that the Chat scene is in the build list as well
  4. Make sure that "Run In Background" is set in the player settings
  5. Make the application run in windowed mode (800 x 600 is good enough)

Now that you have the project all setup, you can make a build of the game. Once the build has been made, run 2 instances of the build. One will act as the server, the other will act as the client. Click the Host button on one instance, and click Connect on the other.

At this point you should see the same white box with a text input box at the bottom that says "Send". Type a message into the message box on one of the instances and click the send button. The other instance should instantly see the message (with a name next to the message). If you do the same in the other instance you will have the same result in the previous instance. Great! Now we see the messages being sent across the network, it is time to check out the code and see what all has been made in order for this example to work.

The Message

We'll start by looking at the ChatMessage.cs file within the Assets/Examples/Chat/src/Messages folder. If you have not read about Network Messages then you should read that first. In this class there are 2 fields Name and Text. The Name is used to tell the recipient what sending player's name is, the Text is the actual message that was typed in by the player. As far as network messages go, this is one of the simplest and the reason why we chose for the Chat example to be the first example we show. This is the only message that is used by this example. Next we'll take a look at the interpreter for this message

public string Name { get; set; }
public string Text { get; set; }

The interpreter

Now we'll take a look at the ChatInterpreter.cs file within the Assets/Examples/Chat/src/Messages/Interpreters folder. If you have not read about Network Message Interpreters then you should read that first. The first thing to notice about this interpreter is that it is processed on both the client and the server. You can tell this because the ValidOnClient and ValidOnServer booleans are set to true. This will ensure that both the client and server are able to process the ChatMessage when it comes in on the network.

public bool ValidOnClient => true;
public bool ValidOnServer => true;

The following code is just used to print the message to the screen. It is not necessarily related to forge so we won't spend too much time going over this here.

var m = (ChatMessage)message;
var cl = GameObject.FindObjectOfType<ChatListener>();
cl.PrintMessage(m.Name, m.Text);

Something you may notice in the interpreter is that we are going to need to check to see if the code that is currently being executed is being done as the server in order to know to send the messages to all other connected clients. If your interpreter is locked to be client only or server only (through the above booleans) then this check would not be necessary.

private bool IsServer(INetworkMediator netMediator)
{
	return netMediator.SocketFacade is ISocketServerFacade;
}

The last bit of code is for the server to go through all of the connected players and send a copy of the message that it received from the player to all other connected players. You will notice that it checks itr.Current.EndPoint != sender which makes sure that the server doesn't send the message back to the player who sent it (they printed their message locally already as you will see soon). If it isn't the sending player then the server will do netMediator.SendReliableMessage(message, itr.Current.EndPoint); to send the message reliably to the client. Feel free to wrap something like this into a helper function if you wish, I may add one into the lib at a later time.

private void SendMessageToOtherClients(INetworkMediator netMediator, EndPoint sender, IMessage message)
{
	var itr = netMediator.PlayerRepository.GetEnumerator();
	while (itr.MoveNext())
	{
		if (itr.Current != null && itr.Current.EndPoint != sender)
			netMediator.SendReliableMessage(message, itr.Current.EndPoint);
	}
}

How the message is sent

To find where the message is being sent, open the SendButton.cs file located in the Assets/Examples/Chat/src folder. If not evident by the name of the script, this script is on the Send button located in the Chat scene. When the button is clicked it executes the Send function in this class which in turn calls SendNetworkMessage. Here you see that a message is pulled from the message pool. Please be sure to read about Message Pools if you have not already. After being pulled, the message fields are being assigned to the name and message being sent, then are sent using the SendMessageAsServer or SendMessageAsClient function.

private void SendNetworkMessage(string txt)
{
	var m = _chatMessagePool.Get();
	m.Name = _myName;
	m.Text = txt;
	if (_isServer)
		SendMessageAsServer(m);
	else
		SendMessageAsClient(m);
}

In the SendMessageAsServer function, you will see that the message is sent to all clients by not providing a specific client in the _engine.NetworkMediator.SendReliableMessage function. As for the client, it will send it's message to the server by providing the specific endpoint _engine.NetworkMediator.SendReliableMessage(m, _mySocket.EndPoint);. Note that clients can not send messages directly to each other, they must go through the server

Conclusion

This is all the critical code that is needed for the chat program to work across the network. Feel free to take a look at the Chat scene and the other non-network related code to understand how the UI is setup and all of that to get a full feel for the program.


Directory Previous Next
Directory Examples Spawning Example

Home

Getting Started
Network Contract Wizard (NCW)
Network Object
Remote Procedure Calls (RPCs)
Unity Integration
Basic Network Samples
Scene Navigation
NetWorker
Master Server
Web Server
Netcoding Design Patterns
Troubleshooting
Miscellaneous
Forge Networking Alloy
Steamworks
Clone this wiki locally