Skip to content

Build & run

This page assumes Raylib is already installed on your system. Otherwise, compilation will fail at link time.

Compiling

The GUI is built with GNU Make from the gui/ directory:

cd gui
make

The output is the build/zappy_gui binary (gui/Makefile:12). The Makefile exposes the usual targets:

Target Effect
make (all) Builds build/zappy_gui
make clean Removes object files (build/obj)
make fclean clean + removes the binary
make re fclean then all

The compiler is g++ with -Wall -Wextra -std=c++17 (gui/Makefile:1), with the header directories src/core, src/network, src/renderer, src/world, src/player (gui/Makefile:4). Nine translation units are compiled (gui/Makefile:15); gui/raylib/Window.cpp is deliberately excluded (dead code).

Root wrapper

The repository's root Makefile builds the three components (gui, ai, server) and generates a small ./zappy_gui script at the root (Makefile:11):

make            # at the root: builds everything
./zappy_gui -h 127.0.0.1 -p 4242

This wrapper simply does cd gui/build/ then exec ./zappy_gui "$@" (Makefile:13). It exists so the binary finds its assets — see Asset resolution below.

Running

./build/zappy_gui -h <host> -p <port>

Command-line options

Argument parsing happens in gui/src/core/main.cpp:22:

Option Meaning Details
-h <host> Server address Required: if empty, usage + exit
-p <port> Server port Default 4242; must be > 0

Although -p has a default value (4242, gui/src/core/main.cpp:20), -h does not: launching without -h prints Usage: <argv0> -p port -h machine and exits with failure (gui/src/core/main.cpp:46). Both options are therefore effectively required in practice. An unknown argument, or a non-numeric port (Invalid port value), also causes a failure exit (gui/src/core/main.cpp:34).

# Typical example: local server on the default port
./build/zappy_gui -h 127.0.0.1 -p 4242

The GRAPHIC handshake

As soon as the connection is established, the GUI announces itself as a graphical client by sending GRAPHIC\n (gui/src/core/main.cpp:55):

NetworkClient net;
if (!net.connect(host, port))
    return EXIT_FAILURE;
net.send("GRAPHIC\n");

In response, the server pours out the world state (map size, tiles, teams, players, eggs…) that the MessageParser decodes. The full exchange is documented in GUI ↔ Server protocol.

Deliberate detail: the socket is opened BEFORE InitWindow

The order of operations in main is not incidental (gui/src/core/main.cpp:52):

NetworkClient net;
net.connect(host, port);   // (1) socket opened
net.send("GRAPHIC\n");     // (2) handshake
// ...
InitWindow(WINDOW_W, WINDOW_H, WINDOW_T);  // (3) window + textures
renderer.loadAssets("assets");             // (4) ~1000+ PNG files

The connection is made before InitWindow and asset loading on purpose. loadAssets opens and reads over a thousand textures, consuming many file descriptors. By connecting the socket first, we guarantee it gets a stable descriptor, with no risk of colliding with an internal Raylib fopen happening late in an already crowded descriptor table.

Asset resolution

The binary locates its assets/ folder flexibly, via resolveAssetsBase (gui/src/renderer/Renderer3D.cpp:25). It probes for a witness file (/animation/walk/1.png) at several levels:

static const char* kProbe = "/animation/walk/1.png";
if (FileExists((assetsDir + kProbe).c_str()))      return assetsDir;        // ./assets
if (FileExists(("../" + assetsDir + kProbe)...))   return "../" + assetsDir; // ../assets
if (FileExists(("../../" + assetsDir + kProbe)...))return "../../" + ...;    // ../../assets

That is why the GUI is typically run from gui/build/: the assets are then at ../assets. This is exactly what the root wrapper does (cd gui/build/ then exec), and the reason that cd exists.

# "Manual" launch equivalent to the wrapper
cd gui/build
./zappy_gui -h 127.0.0.1 -p 4242   # finds ../assets

If the sprites do not appear

A GUI launched from a directory where none of the three path variants point to the assets falls back to the raw assetsDir, and the animations do not load. Run it from gui/build/ (or via ./zappy_gui at the root).

Next step

Once connected and showing the map, on to rendering: see Graphics rendering for the main loop, the camera and the controls.