Broadcast a LAN Multiplayer Game
Code and workflows to send and receive broadcast packets to join multiplayer sessions
What you'll develop on this page

Our server will broadcast its IP address over LAN and clients will be able to see all LAN servers broadcasting so they can select and join.
Github branch link: https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/tree/Broadcasting-and-Joining-on-LAN
Creating UdpConnection
UdpClient
We are going to create a new class called UdpConnection which will have methods to both send and receive UDP broadcast packets. Our implementation works off of MattijsKneppers' great start in the Unity forums.
The core component of broadcasting will be UdpClient from .NET. It is important to note that this broadcasting method is not "Unity-approved"; we are using a Microsoft technology to get this done.
On the server side we will create a new UdpClient. We will create a "sendToEndpoint," which will be our broadcasting IP address and broadcasting port. We will then use UdpClient's "send" method to send data over to that endpoint.
On the client side we will also create a UdpClient. We will bind on the broadcasting port to receive the messages sent in a broadcast at that port. We will then listen for messages.
Doesn't this mean that we'll just be broadcasting to ourselves and as a result we'll just be constantly receiving the messages we just sent, because we are binding and sending on the same port?!
Great point! And that's why we will only create a UdpConnection to broadcast in MainScene (the game) when we are the server. There'll be no clients that will also be broadcasting when joining the server. We will only be "listening" for broadcasts in NavigationScene (title menu).
For testing on the same machine we will make a build, then hardwire a port change for our editor player just to check if it works.
Thread
Listening for broadcast packets is a "blocking" activity, which means that this activity blocks a thread while it awaits a message.
We do not want to block all of Unity while we listen for broadcast messages. So, we're going to create a separate thread to handle listening for messages. Enter: Microsoft's Thread class.
Although this approach is also not "sanctioned" by Unity, it has never caused an issue throughout all of our testing.
Serialized JSON
Finally, what kind of message are we sending?
We will be serializing our data as JSON objects which contain - game name - server IP address - timestamp of when message was sent (server tick)
We will be serializing and deserializing our data using JsonUtility. This approach is a common pattern shown in the Unity docs.
NETWORKING IS HARD
We have tested this broadcasting on Windows/Linux/Mac desktops and iOS devices.
The broadcasting/pick up works great in "normal" cases (super majority of cases). "Normal" cases mean when devices are using "built in" wifi or ethernet.
We have gotten mixed results with "wacky" cases. "Wacky" cases are like a desktop computer using a usb dongle for wifi, or like if you are connecting through a VM so everything is "virtualized." In these types of cases, you may experience trouble with broadcasting or picking up broadcasts when using our methods in this gitbook.
Why? Well when machines have a Network Interface Controller (NIC) and additional methods to connect to the internet, it is hard to "automatically" know which IP endpoint to bind to. (Don't worry you don't need to know this stuff, just know "wacky" situations mean it's hard to know the right answer without asking the user).
To handle these "wacky" situations we can: 1) build a UI component into the app that asks the user and potentially add confusion, 2) program a more robust sending mechanism that sends across all interfaces or, 3) choose the most likely one and hope for the best.
In this gitbook,we went with approach #3. (If it turns out that we chose the wrong option for you all, please let us know in our Discord and we will update).
Additionally, you may find (like we did) a lot of answers on Stack Overflow telling you not to do broadcasting, and instead to do multicasting! It is "way better and recommended!"
Do not listen to those charlatans! You will spend countless hours testing, and retesting, and then after days of using Wireshark, and tracing packets, and learning more than you would ever like about networking data layers and IGMP packets, and learn that it is completely unknown how many routers support this functionality and that there is no way to really configure a router to see if it can support it.
Oh us? No, no we're not bitter....
UdpConnection
Without further ado...
Create a new script in the Multiplayer Setup folder called UdpConnection
Paste this code snippet into UdpConnection.cs:

We have a class that allows either the server to send messages or a client to receive messages
We created UdpConnection
Broadcasting from the server
Now that we have UdpConnection we need to create a script to pull the broadcast IP address, port, and game name from ClientServerInfo and send a broadcast message
Navigate to MainScene, right-click on the Hierarchy, and create an empty GameObject called GameBroadcasting
With GameBroadcasting selected in Hierarchy, click "Add Component" in the Inspector and make a new script called "GameServerBroadcasting"
Move GameServerBroadcasting into the Multiplayer Setup folder

Paste the code snippet below into GameServerBroadcasting.cs:

Now select GameBroadcasting in Hierarchy, and drag the ClientServerInfo GameObject (also in Hierarchy) into the appropriate field in the GameServerBroadcasting component in Inspector

Now the server can send broadcast messages when in MainScene
We created a new GameBroadcasting GameObject in MainScene
We added GameServerBroadcasting component
Listening and joining on the client
We are going to need to listen for the broadcast messages in NavigationScene. Instead of having LocalGamesFinder search for GameObjects, we will update LocalGamesFinder to listen for broadcast messages.
We will then need to update what happens when we click on the list item, so we need to populate JoinGameScreen with the data sent in the broadcast packet.
Navigate to NavigationScene and then open LocalGamesFinder
Paste the code snippet below into LocalGamesFinder.cs:

Now that we have updated LocalGamesFinder to update the list with the latest unique broadcasts we need to update JoinGameScreen custom Visual Element (cVE) to take in the new passed-through ServerInfoObject data
Paste the code snippet below into JoinGameScreen.cs (cVE):
Now delete all the LocalGame GameObjects in the NavigationScene Hierarchy
Save the NavigationScene
Navigate to the BuildSettings folder, select the configuration file of your development platform (i.e. "macOS - Build"), then go to Inspector and hit Build and Run

Change the port in line 47 in UdpConnection to 9001
We make this change so that we don't bind on same port when testing
Hit play in the editor
Host a game in the editor and check out the build
Remember to host in the editor, not the build, when testing
The editor must send to the hardwired broadcast port

Great, we see our broadcasted game
In the editor: quit the game, and then start a new game with a new name

We can see our game name change in our build
In the build: click on the broadcasted game and join the game

Undo the port change in UdpConnection and we are set!
If you want to test again you will need to build then change like we did in this section
We are now able to join broadcasted games
We updated LocalGamesFinder
We updated JoinGameScreen cVE
We updated the port in UdpConnection for testing
We built our project and was able to broadcast and join a game
Github branch link:‌
git clone https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/
git checkout 'Broadcasting-and-Joining-on-LAN'‌
Last updated