Ry-E / Genesis

Discription? Excellent question.
0 stars 0 forks source link

Networking #6

Open bhowl opened 2 years ago

bhowl commented 2 years ago

How do we make our game multiplayer? What parts of the stack are directly involved?

WebSockets WebSockets is a lightweight messaging protocol that utilizes TCP, rather than a Javascript implementation of TCP sockets, as you've noted. However, beyond the initial handshake, there are no HTTP headers being passed to and fro beyond that point. Once the connection is established, data passes freely, with minimal overhead.

Long-polling Long-polling, in a nutshell, involves the client polling the server for new information periodically with HTTP requests. This is extremely expensive in terms of CPU and bandwidth, as you're sending a hefty new HTTP header each time. This is essentially your only option when it comes to older browsers, and libraries such as Socket.io use long-polling as a fallback in these cases.

WebRTC In addition to what has been mentioned already, WebRTC allows for communication via UDP. UDP has long been used in multiplayer games in non web-based environments because of its low overhead (relative to TCP), low latency, and non-blocking nature.

TCP "guarantees" that each packet will arrive (save for catastrophic network failure), and that they will always arrive in the order that they were sent. This is great for critical information such as registering scores, hits, chat, and so on.

UDP, on the other hand, has no such guarantees. Packets can arrive in any order, or not at all. This is actually useful when it comes to less critical data that is sent at a high frequency, and needs to arrive as quickly as possible, such as player positions or inputs. The reason being that TCP streams are blocked if a single packet gets delayed during transport, resulting in large gaps in game state updates. With UDP, you can simply ignore packets that arrive late (or not at all), and carry on with the very next one you receive, creating a smoother experience for the player.

At the time of this writing, WebSockets are probably your best bet, though WebRTC adoption is expanding quickly, and may actually be preferable by the time you're done with your game, so that's something to consider. -stackoverflow

Lastly, here is the github catalog of websocket apis for golang... but I'm kind of confused on where this needs to be impemented. Maybe a js websocket API would do or we don't need one at all because of the go fiber framework? maybe if someone could draw a picture of turtles stacked on top of one another i would understand

also some WebRTC

howl0893 commented 2 years ago

Good stuff! So our backend and frontend should communicate via WebSockets. It would be ideal to use Socket.io (which is built on top of the WebSocket protocol) to have the long-polling fallback for older browsers and automatic reconnection.

Northern guild folks appear to be working with Socket.io too:

potentially useful go libraries: go-socket.io fiber-websocket


Here is a good article explaining client-server game architecture: https://www.gabrielgambetta.com/client-server-game-architecture.html

& here is a ru·di·men·ta·ry drawing on my very ru·di·men·ta·ry understanding of how turtles may stack: client-server-architecture-networking

Ry-E commented 2 years ago

Socket.io sounds good to me! turtles are looking well balanced.

It would be interesting down the line to look into the possibility of using websockets as the foundation for security purposes but then implementing webRTC for things like movements so attacks will have more precision. Might not be necessary at all or even possible without jeopardizing security, but it strikes my curiosity.

This is a little off topic for this issue but I don't feel like it merrits another issue, I was poking around in the source code for the demo and i noticed they are using react for the general "web app", and pixijs for the actual game. I think that makes sense and should be added t the tech stack. Additionally i noticed they are using Typescript, which is essentially the standard now for scaleable javascript apps, and so i think we should implement that as well. Its not something initailly vital though and its easy enough to add types later, but something to keep in mind at least.