MazeWar Game Server
Multi-threaded real-time combat in C
A multi-threaded C server for real-time maze combat. One thread per TCP client, a shared maze guarded by fine-grained locks, a custom binary packet protocol, and SIGUSR1-driven asynchronous laser-hit notification. Coursework, written to be Valgrind-clean and Criterion-tested end to end.
What it is
MazeWar is a 1980s-era multiplayer game in which players navigate a
shared maze, see each other through a first-person view, and shoot
lasers. This repository is the server side: a TCP daemon that accepts
client connections, maintains the maze and player state, and pushes
incremental view, scoreboard, and chat updates back to every client.
Built for CSE 320 (Systems Fundamentals II) at Stony Brook, Apr-May
2025. Headers marked === DO NOT MODIFY THIS FILE === are the
course-provided contract; everything under src/ is the implementation.
By the numbers
| Metric | Value |
|---|---|
| C source files | 6 (~1,616 LOC under src/) |
| Header files | 6 (~861 LOC under include/) |
| Criterion test suite | 145 lines |
| Packet types | 13 (6 client-to-server, 7 server-to-client) |
| Packet header | 16 bytes fixed + optional length-prefixed payload |
| Concurrency model | 1 service thread per connected client |
| Compiler flags | -Wall -Werror, links -lpthread -lcurses |
Architecture
+------------------+
SIGHUP ------> | main thread | accept() loop on listenfd
+------------------+
|
| pthread_create per connection
v
+-------------------------------------+
| client service threads (N) |
| mzw_client_service(int *fd) |
| - proto_recv_packet |
| - dispatch: LOGIN/MOVE/TURN/FIRE/ |
| REFRESH/SEND |
| - proto_send_packet |
+-------------------------------------+
| | |
v v v
+----------------+ +--------+ +---------------+
| CLIENT_REGISTRY| | PLAYER | | MAZE |
| mutex + sem | | table | | lock per cell |
| wait_for_empty | | refcnt | | avatar coords |
+----------------+ | recmtx | +---------------+
+--------+
^
| SIGUSR1 on laser hit
|
shooter thread- Client registry (
src/client_registry.c) — registers fds, signals main when empty, issuesshutdown(2)on every fd during teardown. - Protocol (
src/protocol.c) —proto_send_packet/proto_recv_packethandle htonl/ntohl and payload framing over a TCP byte stream. - Maze (
src/maze.c) — parses the template, tracks which cell each avatar occupies, performs collision and line-of-sight queries. - Player (
src/player.c, ~600 LOC) — login/logout, scoreboard, view diffing, laser resolution, chat broadcast, recursive locking discipline. - Server loop (
src/server.c) — per-client service function driving the protocol state machine.
Key features
- POSIX threads, one per client.
main()accepts on the listening socket and hands each connection tomzw_client_service()running in a detached thread. - Thread-safe client registry.
creg_register/creg_unregistertrack live file descriptors.creg_wait_for_emptyblocks the main thread during shutdown until every service thread has exited. - Reference-counted player objects. Players can be referenced concurrently by the maze module and by other players' view updates; refcounts keep them alive until the last reference drops.
- Recursive mutexes on players. Player -> maze ->
player_update_viewup-calls requirePTHREAD_MUTEX_RECURSIVEto avoid self-deadlock. - Mutexes plus semaphores. Mutexes protect shared state; semaphores coordinate the empty-registry wait during graceful shutdown.
- Custom binary protocol. Fixed 16-byte header in network byte
order (
type, 3xint8params,uint16payload size,uint32sec /uint32nsec timestamp) followed by an optional payload. - SIGUSR1 for async laser hits. When a player is shot, the shooter's thread signals the victim's thread with SIGUSR1 to interrupt any blocking read and trigger alert delivery without polling.
- SIGHUP for graceful shutdown. The main thread closes the listening socket, shuts down every registered client fd, waits for the registry to drain, then exits.
- Valgrind-verified. No leaks, no invalid reads/writes under the standard course test battery.
Stack
| Layer | Technology |
|---|---|
| Language | C (gnu11), -Wall -Werror |
| Concurrency | POSIX threads, mutexes (incl. PTHREAD_MUTEX_RECURSIVE), counting semaphores |
| Networking | BSD sockets, TCP/IPv4 |
| Signals | SIGHUP (shutdown), SIGUSR1 (async laser notification) |
| Tooling | GNU Make, Valgrind, Criterion, ncurses (reference clients) |