---
title: MazeWar Game Server
description: Multi-threaded real-time combat in C
section: craft
tags: [project, systems-programming]
genre: reference
stability: stable
lastUpdated: 2026-04-19
url: https://fardiniqbal.com/docs/craft/projects/mazewar-game-server
---


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 [#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 [#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 [#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, issues `shutdown(2)` on every fd during
  teardown.
* **Protocol** (`src/protocol.c`) — `proto_send_packet` /
  `proto_recv_packet` handle 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 [#key-features]

* **POSIX threads, one per client.** `main()` accepts on the listening
  socket and hands each connection to `mzw_client_service()` running
  in a detached thread.
* **Thread-safe client registry.** `creg_register` / `creg_unregister`
  track live file descriptors. `creg_wait_for_empty` blocks 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_view` up-calls require `PTHREAD_MUTEX_RECURSIVE` to
  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`, 3x `int8` params, `uint16` payload size, `uint32`
  sec / `uint32` nsec 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 [#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)                    |

## Links [#links]

* **Source:** [https://github.com/FardinIqbal/concurrent-network-game-server](https://github.com/FardinIqbal/concurrent-network-game-server)
