The Common group is always activated, and contains events that apply to both the host and peers. This is another sensible way to organise events without having to duplicate identical events between the Peer and Host groups.
When someone else joins the chat room, On peer connected triggers. In this event the Multiplayer.PeerAlias expression is set to the alias of the joining peer. In this case we log that they joined and add them to the peer list. Note that On peer connected also triggers once per peer just after joining the room for everyone else who is already present. In other words, if there are 5 people already in the chat room when you join, On peer connected will trigger 5 times upon joining for each of the peers already there. While people already in the room are not technically joining at that time, it allows us to treat both pre-existing peers and newly joining peers the same way.
When someone leaves the chat room, On peer disconnected triggers. Similarly to connecting peers, Multiplayer.PeerAlias has the name of the leaving peer. The only small complication here is we need to remove their name from the peer list. To make sure their name is removed we compare each item in the list; if the item text matches the alias of the peer who left, it's removed.
Finally we handle the case where we are "kicked" from the room. This means we were forcibly removed from the room without requesting it. Usually this happens for one of two reasons. Firstly since the host is acting as the server for the game, if they quit then the game ends and everyone else is kicked. Alternatively after joining the room, if we cannot connect to the host within a certain time period then the signalling server kicks us out again. Some types of NAT make it impossible for a peer to connect to a host, and will simply sit there trying to connect unsuccessfully forever. The signalling server timeout (defaulting to 20 seconds) means you at least get the opportunity to join a different game, or retry.
The Peer group is only activated when we are in the room as a peer (so we are not the host). Note in this case we are only connected to the host - there are no connections directly between peers. The host acts as the server so if two peers want to communicate it must be sent via the host first, who then relays it on. This relay is dealt with in the Host group; for now all we need to worry about is sending and receiving messages!
First of all if we click Send or press Return with a non-empty message, we add our own chat message to the log immediately, and send a message with the tag "chat" in reliable ordered mode (using the Send message action). We wouldn't want to use unreliable mode (your chat message might never arrive!) and we wouldn't want to use reliable unordered mode either, since the network could change the order messages arrive in, and then chat messages could appear in the wrong order and possibly alter the meaning of the conversation! The message tag is also a simple way to identify different types of message. For example messages with the tag "chat" in this case are for public chat messages, but a different tag "private-message" could be used to message an individual only. Also note that as a peer, we leave the recipient (Peer ID) parameter empty to send to the host, since that is the only connection we have anyway.
Receiving messages is straightforward. When a message with the tag "chat" arrives, On peer message "chat" triggers. In this event we simply add to the chat log the name of the sender (with the Multiplayer.FromAlias expression) and the message they sent (Multiplayer.Message). Remember we don't receive messages we send ourselves, so this never triggers for our own chat messages - that's why we separately add our own chat messages to the log when sending them.
The Host group is similar to the Peer group, but instead we communicate with all peers. When the peer sends a message, they send it only to the host. However as host, when we send a message we must broadcast it to all peers so everybody receives it. This is done with the separate Broadcast message action which can only be used by the host. Also instead of specifying a recipient, we specify who the message is from, which is useful for relaying messages. In this case we leave the From ID parameter empty to indicate it is from the host.
Finally we reach the key part of the chat room: the host's relay. When the host receives a "chat" message, we add it to the chat log just like the peers do. However if we left it at that, we'd have a strange chat room: peers would only receive messages sent from the host, whereas the host could see everyone's messages. In order for peers to see other peer's messages, the host must relay them on to everyone else. So when the host receives a chat message, it also broadcasts it so all the other peers will receive it too.
Each peer has a unique Peer ID assigned by the signalling server, and can be used to refer to an individual peer permanently regardless of if their alias changes. As with the FromAlias expression, in the On peer message trigger the Multiplayer.FromID expression is set to the ID of the peer the message came from. So when the host broadcasts the message, it indicates it is really from that peer, not the host. This means when the other peers receive the message and trigger On peer message, the message shows up as being from the original sending peer instead of from the host. In other words the broadcast message is coming from the host, but we can say it is being sent on behalf of another peer. Also note that when we broadcast a message, it is not sent to the peer who we say it is from - that would pointlessly send their own chat message straight back to them. So the message is only broadcast to everyone apart from the original sender.
That concludes our chat room in 26 events! Hopefully now you have a good understanding of signalling, handling peers joining and leaving, messaging, and how to set up separate events for the host and peer.
If you feel like a challenge, try coming up with a way to private message individual peers in the chat room. In IRC this is done with a special chat message command starting with a slash, such as: /pm SomeUser hello!
In this case the host would need to relay the private message as well, but by Send message instead of Broadcast message so it is only received by the intended recipient. You wouldn't want to broadcast private messages to everyone!
The third tutorial will introduce syncing objects in real-time. If you're ready, head on to Multiplayer tutorial 3: pong!