How To Use Steamworks SDK P2P System With Unity
This tutorial uses the Steamworks.Net C# wrapper, so it is highly recommended that you follow their Getting Started Section.
This tutorial also relies heavily on the Steamworks SDK itself, so following their documentation is required for this tutorial. Setting up a lobby system will not be covered in this section.
Note that an App ID is required to have your game's network traffic route properly through Steam's network. You can only obtain one after being accepted onto Steam's platform, otherwise you will be using their Spacewar dummy App ID.
To sum up our starting point, we have a fully functioning lobby system, where the host will create a lobby, and other clients will connect are able to join. These lobby members are stored with their CSteamID and ConnectionStatus to later reference.
Setting Up
The fist thing we need to set up now is a network object for our code to derive from. Every object we want to synchronize through the network will need to have the following:
An Object Identifier is needed so we know what kind of object it is.
A Local Identifier tells us whether or not we own the object
A Network ID is required for each client reference the correct object.
An ID counter tells the host the next number to assign as an Id
Serialize / Read Functions Allow us to work with the object's data we need to send
Sending Data
Now in a P2P Networking Script, we have to start packing data together for others to read and synchronize with.
To update an object, we are following a specific order to packing:
(MessageType.Update)(ObjectType)(NetworkId)(UpdateData)
Then to actually send our message using Steamworks, We Call SendP2PPacket()
And that's it, that is really all we need to handle update messages, the bulk of the data being sent across the network.
Receiving Data
To collect these messages that others have sent us, first we have to check if packets are available.
If they are, we want to continue reading packets until we have collected all of them.
Host Responsibilities
Now with all of the messages collected, the host of the game has a few responsibilities to fulfill.
Iterating through each message, they have to decide what to do with it.
If the message they are reading is an update message, the have to route it to all other clients that are connected.
If the message is a request to spawn a new object, if we accept their request, we send back an Accept Spawn message along with a Network Id that only the host can provide. This will let them know that they own the object.
Synchronizing With Host
With the host responsibilities now finished, now everyone can read through messages and synchronize the the updates.
First, if the message type we received is an accepted spawn, we get to spawn in a new object for ourselves.
Otherwise, It should be an Update Message. In this case we have to unpack all of the object updates in the message. We should be Iterating through each network object to see if it exists.
In a case where there is no such match, we have a new object that we must spawn in and add it to our list as an object we do not own.
Now all we have to do is clear the message buffer and wait for new messages to come in.
That's It!
Summary
Now we should have a network game that allows for spawning new objects and synchronization. Destroying objects is not covered, but works very similar to spawning objects. If you have any questions about Steamworks, most things can be answered in their documentation, so be sure to take a look.
I hope you take Steamworks into consideration when building your next game!