Skip to main content

Overview

Wizard Duel uses ENet, a reliable UDP networking library, for multiplayer functionality. The implementation supports peer-to-peer connections with one player acting as host (server) and another as client.

Network architecture

Connection model

Host (Server):
  • Listens on port 7777
  • Accepts one client connection
  • Sends/receives position updates
Client:
  • Connects to server IP (default: 127.0.0.1)
  • Sends local position to server
  • Receives opponent position from server

Global network state

The game uses separate host/peer pointers for client and server roles, allowing either player to act as host.

ENet initialization

ENet must be initialized before any network operations:
The atexit call ensures proper cleanup when the program terminates.

Setting up a host (server)

The SetupHost() function creates a server that listens for connections:

Parameters explained

The game is designed for 1v1 battles, so only one client connection is allowed.
Provides two communication channels for separating different types of game data (though currently only one is used).
No bandwidth limiting is applied, allowing maximum throughput for local network play.

Setting up a client

The SetupClient() function connects to an existing host:
Clients pass NULL as the address to enet_host_create, meaning they don’t bind to a specific port.

Position packet structure

Player positions are synchronized using a simple struct:
This minimal packet structure keeps network traffic low, sending only 8 bytes per position update.

Event handling

The game processes network events using enet_host_service:

Connection events (HOST state)

Connection events (JOIN state)

The timeout parameter in enet_host_service is set to 0, making it non-blocking. This allows the game to continue rendering while checking for network events.

Position synchronization

In the MULTIPLAYER state, the game continuously syncs positions:

Receiving position updates

Sending position updates

Position updates are sent only when the player moves:
Using ENET_PACKET_FLAG_RELIABLE ensures position updates arrive in order and are resent if lost, preventing desync issues.

Packet creation and sending

Creating packets

Sending packets

From client to server:
From server to client:
The channel parameter (0) specifies which of the 2 available channels to use.

Latency monitoring

The game displays real-time ping information:
ENet automatically tracks round-trip time (RTT) for each peer connection.

Network cleanup

Proper cleanup is essential to free network resources:
This releases all associated connections and memory before the program terminates.

Event types

ENet provides several event types (though only these are currently used):
Fired when a connection is established. Used to transition from HOST/JOIN states to MULTIPLAYER state.
Fired when a packet is received. Contains packet data that must be manually destroyed after processing.
Would be fired when a peer disconnects. Currently not handled, which could lead to undefined behavior if a player disconnects mid-game.

Limitations and future improvements

No spell synchronization: Currently only position data is synced. Spells are not transmitted over the network, meaning players can’t damage each other in multiplayer. No disconnect handling: The game doesn’t handle ENET_EVENT_TYPE_DISCONNECT events. No health/mana sync: Health and mana values are not synchronized between players. No lobby system: Players must manually coordinate who hosts and who joins. Local network only: Default configuration uses 127.0.0.1 (localhost).
To play over LAN, change SERVER_IP to the host’s local IP address (e.g., “192.168.1.100”).