A fast-paced multiplayer arcade game built using Python's Arcade library, featuring real-time UDP network communication, physics-driven gameplay via Pymunk, and an intuitive ImGui-based interface. This project demonstrates a robust client-server architecture with several optimizations to ensure low latency and efficient data transfer. Key features include personalized game state updates, selective object transmission based on proximity, UDP networking, and the use of Protocol Buffers with zstandard compression.
demo.mp4
- Overview
- Installation & Setup
- Usage
- Project Structure
- Optimizations & Performance Enhancements
- Cool Stuff(s)
- Customization & Future Work
- License
This repository contains a networked arcade shooter that pits players against each other in a physics-driven multiplayer arena. The project is divided into two main components:
-
Client:
Built with Arcade and ImGui, the client handles user input, renders players, bullets, and the game world, and manages interactive UI elements such as the chat window, minimap, and leaderboard. -
Server:
The server processes player inputs, simulates physics (movement, collisions, bullet dynamics) using Pymunk, and broadcasts personalized game state updates via UDP. It also maintains an in-game leaderboard and chat system, ensuring that each player receives only the information relevant to their immediate surroundings.
-
Clone the Repository:
git clone https://github.com/PavelFalta/udp_multiplayer_game.git cd udp_multiplayer_game
-
Set Up a Virtual Environment 🤓:
python -m venv venv source venv/bin/activate
-
Install Dependencies:
pip install -r requirements.txt
Start the game server to handle player connections, physics simulation, and game state updates:
python server.py
Launch the client to join the multiplayer arena:
python client.py
-
classes.py
Contains core classes for game objects and UI:- Entity System:
TheEntity
class is the foundation for all game objects, extended byPlayer
andBullet
classes. These classes implement smooth interpolation through buffered positions. - GUI & Chat:
Manages the chat system (ChatWindow
), message classes (PlayerMessage
,Announcement
), and UI elements such as the minimap and customization panels using ImGui. - Terrain:
Handles the drawing of game boundaries and static obstacles. Unused as of now.
- Entity System:
-
client.py
The client entry point:- NetworkManager:
Manages UDP communication, sending player inputs to the server and receiving zstandard-compressed game state updates. - Game Loop & Rendering:
Sets up the Arcade window, camera movement, and integrates ImGui for a dynamic user interface. - Input Handling:
Captures keyboard and mouse events to update the player's state and relay input data to the server.
- NetworkManager:
server.py
Implements the game server:- Game Physics:
Uses Pymunk to simulate realistic physics, managing player movement, bullet trajectories, and collision detection. - Player Management:
Processes incoming player inputs, manages connections/disconnections, handles respawns, and applies health/damage logic. - Network Communication:
Utilizes UDP and multithreading to concurrently handle player inputs and send personalized, compressed game state updates. - Leaderboard & Chat:
Maintains a dynamic leaderboard and message buffer to broadcast game events and chat messages to players.
- Game Physics:
game_pb2.py
Auto-generated code from the Protocol Buffers definition file (.proto
). It defines message structures such as:- Messages:
PlayerInput
,Player
,Bullet
,GameState
,ServerMessage
, andLeaderboardEntry
. - Serialization:
Provides fast serialization and deserialization for real-time communication between client and server.
- Messages:
imgui.ini
Configuration file for ImGui window positions and sizes, ensuring a consistent UI layout.requirements.txt
Lists all required packages, including:arcade
,arcade-imgui
,pymunk
,imgui
,protobuf
,zstandard
, and more.
- Tailored Updates:
Each player receives a personalized game state update. In the server'sserialize_game_state
method, the current player's position is used to filter out distant objects. This ensures that only relevant objects (e.g., players, bullets) within a specific distance are included in the update, reducing unnecessary data transmission.
- Distance Threshold Filtering:
The server only sends objects that are within a defined distance (determined bySEND_DISTANCE_THRESHOLD
) of each player. This optimization significantly reduces bandwidth usage and client processing load, especially in large maps where distant objects are irrelevant to the player's immediate gameplay.
- Low-Latency Communication:
By using UDP (viasocket.SOCK_DGRAM
), the game minimizes network overhead compared to TCP. Although UDP does not guarantee delivery, the game design compensates by sending frequent state updates (at 60 FPS), ensuring that lost packets are quickly replaced by new ones. - Reduced Connection Overhead:
UDP's connectionless nature eliminates the latency introduced by TCP’s connection setup and maintenance, making it ideal for fast-paced real-time gaming.
- Compact, Schema-Based Messages:
The use of Protocol Buffers allows for fast, efficient, and structured serialization of game data. This minimizes message size and parsing time. - Zstandard Compression:
Before sending game state updates, messages are compressed with zstandard. This further reduces the data footprint on the network, ensuring rapid transmission even when game state messages are large. - Fast Deserialization:
On the client side, decompression and deserialization occur swiftly, keeping the rendering loop smooth and responsive.
- Concurrent Processing:
Both client and server employ multithreading. For example, the client’s network manager runs a dedicated thread for receiving game state updates, ensuring that network I/O does not block rendering or input handling. - Thread Safety:
Locks (e.g., in the server’s game state update and leaderboard management) ensure that shared data is safely accessed and modified across threads, maintaining data integrity without sacrificing performance. - Decoupled Game Logic:
Network communication is separated from game logic and rendering. This decoupling guarantees that high-frequency physics and rendering updates (60 FPS) are not impeded by network latency or variability.
- UDP & Compression:
The game leverages UDP for low-latency communication. Game state messages are compressed using zstandard and serialized with Protocol Buffers to maximize efficiency. - Threaded Networking:
Multithreading separates network I/O from core game logic, ensuring smooth performance even under heavy network load.
- Pymunk Integration:
The server uses Pymunk to simulate realistic physics, managing movement, damping, and collision detection for players and bullets. - Bullet Collision Detection:
Bullet collisions are detected using segment queries, ensuring that impacts are accurately registered and damage is applied in real time.
- ImGui-Based Interface:
The client employs ImGui (viaarcade-imgui
) to render interactive UI panels, including:- A Chat Window for real-time messaging.
- A Leaderboard displaying top players and scores.
- A Minimap providing a top-down view of the arena.
- A Customization Panel to adjust player name and color.
- Interactive Chat:
Double-clicking on chat messages allows players to quickly reuse text, enhancing in-game communication.
- Personalization:
Players can customize their in-game appearance by modifying their name and color through the built-in customization panel.