A template for making real time online games with a server-client structure, web browsers as clients and a pion backend as a server.
The biggest challenge with making real time online browser games (AKA .io games) is that there is no way to send an arbitray UDP packet to a browser client. WebRTC solves this problem by allowing you to make a secure connection between browser clients and a pion client and then send packets acting exactly like UDP between them. Unordered, unreliable SCTP packets will behave exactly like vanilla UDP, but with encryption. In this example, we will be using an unreliable, ordered SCTP packets. We will include the ordered tag in the datachannel because any packets received older than the last packet received will be dropped, allowing every client the ability to assume every message received is the most recent update from the server.
For player controls we send what the client does to the server reliably (SCTP acting like TCP), so every player action can be taken into account by the server without any dropped messages.
This code is structured with main.go being the web server/ webrtc client and index.html in the public folder being the web client.
You will need to add your public IP or domain name of the location you're hosting the web server (main.go) at to the New Websocket
line in index.html, link. You'll also need to add the IP of your server in main.go here. e.g settingEngine.SetNAT1To1IPs([]string{"172.16.0.0"}, webrtc.ICECandidateTypeHost)
. (But leaving the IP line in main.go as is will default to using your link-local address.)
Next you can add any game code you'd like to index.html, or a seperate .js file.
Send no-retransmit, but ordered, game state updates across the network to browser clients using the dataChannel.SendText
or dataChannel.Send
methods in main.go.
To receive client actions I chose to create another datachannel with ordered messages and retransmits enabled to be able to receive reliable messages from clients. (No one wants to have to guess if pressing right on their controller will actually make their character move :P)
Also I added an example of how to do entity interpolation client side in public/interpolationExample. This example just takes each update from the server, saves a copy of the previous update, and divides how much the players have moved by a specified number (interpolationFrames
in index.html). Then the quotient is used to move the player square only that much each render, for the specified amount of frames, interpolationFrames
, creating smoother movement to the actual update positions.
- You need to first install golang
- Next make sure you have at least golang 1.15 by running
go version
- Then git clone, or download this repository and place it inside your GOPATH
(You can find your GOPATH by executing
go env
) - Next enter:
set GO111MODULE=on
for windowsexport GO111MODULW=on
for linux or mac
- Finally navigate inside the downloaded repository and run
go build
which will produce the binary server file for you to run!
Thank you to:
- Pion For the wonderful WebRTC library in Go!
- Gorilla/Websocket For the wonderful websockets library in Go!