Multiplayer & Networking in Games

kids playing multiplayer games, concept art
Game Development 101: (incomplete)
a. Basics of Game Development
b. Designing your Video Game
c. Math in Video Games
d. AI Decision-making & Pathfinding
e. Asset Creation & Game Art
f. Physics & Collision Detection
g. Shaders & VFX in Games
h. Multiplayer & Networking in Games

Basic Networking Overview

In multiplayer game, if we are sending data to another player, sending data to other player’s machine is not enough; we need to find which program/process must receive the data (out of many network-based programs running on destination machine). To achieve this, we have transport layer; which keeps track of destination process, we make use of port number since each port number can make every program/process uniquely identifiable.

But how to actually transmit the data between machines? (forget about the program/process within it). For this we have network layer that keeps track of devices using IP-addresses. This layer is used to determine which device should the data go. It does the actual routing & forwarding of data packets.

Now forget about routing between millions of devices, how exactly does the data transfer between two directly connected devices occur? For this we have link layer which handles data transfer between two directly connected devices. It is a single edge between two nodes.

But, how does the data is actually transferred between two devices connected by 1 edge? We have raw bits/signals going in the wire or the wireless channel. This layer is called physical layer as the data is ‘actually’ transferred here.

Why link layer?

There could be different physical mediums such as wired, wireless and their types. We have to manage the transfer between two incompatible mediums such as from wire to wireless and so on. That’s why we have link layer (to manage transfer between 2 devices, no matter which medium they are in!).

Why network layer?

Link layer has resolved the issue of incompatibility, but it does not work if we have a device connected indirectly via tens of routers in between. We have to find the shortest path between many possible paths between two distant devices. That’s why we have network layer.

Why transport layer?

Network layer has resolved the issue of finding the correct device in network of millions of devices. Now it is upto the next layer of software, the transport layer to deliver the data packet to correct process (or socket).

Finally, the Application Layer

This is our game, which has finally received the data through transport layer socket.

Transfer Data Between Devices

We will start with basic socket programming to send data between two devices. Below is example of a server that receives client’s name & sends “Greetings, CLIENT_NAME”. And client program sends its name to the server. for a very basic multiplayer, similar connection utilizing TCP or UDP can be made & transfer of positions, orientations or input events among connected devices will synchronize the game state across devices.

Server.py:

import socket

def start_server():
    # Create a socket object
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Bind the socket to a specific address and port
    server_address = ('localhost', 5555)
    server_socket.bind(server_address)

    # Listen for incoming connections (maximum 1 connection in the queue)
    server_socket.listen(1)
    print('Server is listening for incoming connections...')

    while True:
        # Wait for a connection
        connection, client_address = server_socket.accept()
        print('Accepted connection from', client_address)

        try:
            # Receive the data from the client
            data = connection.recv(1024)
            if data:
                client_name = data.decode('utf-8')
                response = f"Greetings, {client_name}"
                connection.sendall(response.encode('utf-8'))
        finally:
            # Clean up the connection
            connection.close()

if __name__ == "__main__":
    start_server()

Client.py:

import socket

def start_client():
    # Create a socket object
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # Connect to the server's address and port
    server_address = ('localhost', 5555)
    client_socket.connect(server_address)

    # Get the client's name from the user
    client_name = input("Enter your name: ")

    try:
        # Send the client's name to the server
        client_socket.sendall(client_name.encode('utf-8'))

        # Receive the response from the server
        response = client_socket.recv(1024)
        print(response.decode('utf-8'))
    finally:
        # Clean up the connection
        client_socket.close()

if __name__ == "__main__":
    start_client()

THIS ARTICLE IS UNFINISHED

Game Development 101: (incomplete)
a. Basics of Game Development
b. Designing your Video Game
c. Math in Video Games
d. AI Decision-making & Pathfinding
e. Asset Creation & Game Art
f. Physics & Collision Detection
g. Shaders & VFX in Games
h. Multiplayer & Networking in Games