Known limitations¶
About this page
This page documents the actual state of the code as it exists today:
functions left as stubs, mismatches between the code and the historical
documentation, and potential bugs found while reviewing the repository. The
goal is an honest, precise reference — not a blame list. Each item is framed
as a current state, a known limitation or future work, with the
file:line when known and the practical impact.
The code is functional for the nominal use case; the items below concern un-wired branches, representation inconsistencies, or features that are announced but not realized end-to-end.
IA (Python)¶
The AI (ai/) is largely implemented, even though its README still calls it a
"skeleton". Several stubs and inconsistencies remain.
Stubs (raise an error if reached)¶
Unimplemented functions
| Item | Location | Impact |
|---|---|---|
parse_broadcast |
ai/src/protocol/parser.py:102 |
Raises NotImplementedError. Inbound message K, text broadcasts are not handled end-to-end: sound-based rally is not realized. |
ForkState (4 methods) |
ai/src/strategy/states/fork.py:27,33,37,41 |
All methods raise NotImplementedError. FORK is registered in the FSM but no transition leads to it; entering it would crash. The reproduction strategy (Fork/Connect_nbr) is unimplemented. |
tile_index_to_relative_coord |
ai/src/state/vision.py:20 |
Dead stub: the equivalent geometry is implemented inline in WorldMap.update_from_look. Never called, so no runtime effect. |
See IA > Strategy (FSM) and IA > Protocol layer.
Implemented but not wired in¶
Present and tested, but with no caller
The entire team/ package (crypto.py, protocol.py, decoy.py) is
implemented and covered by tests, but is only referenced from within
team/ itself: there is no caller in the network or strategy code.
Encrypted team comms and decoys are therefore not actually used at
runtime. See IA > Team coordination.
Other implemented-but-unused items:
pathfinding.bfs_toric— full toric BFS, no caller.pathfinding.direction_from_sound— maps K (0–8) to a direction, unused (tied to the absence of sound-based rally).Client.flush_output— implemented but never called from the main loop.CommandQueue._callbacks— stored byadd_callbackbut never read (effectively dead).ConnectNbrResult— message type never produced (becauseForkStateis a stub).config.DEFAULT_HOST— unused constant.
Probable bug: food unit comparison¶
Food thresholds: count vs time units
The food-threshold comparisons compare drone.food (a food count) against
FOOD_SURVIVAL_THRESHOLD * LIFE_PER_FOOD (a value in time units, e.g.
5 * 126 = 630). They therefore compare a count (typically a few units)
against a value in ticks (hundreds), so some transitions may effectively
never fire.
Affected in: survive, collect, incant_prep, incant
(ai/src/strategy/states/). See IA > Strategy (FSM).
Handshake fragility¶
do_handshake assumes a single grouped receive
In ai/src/network/connection.py (do_handshake, ~:65), the code assumes
that CLIENT-NUM and the X Y line arrive in a single recv
(splitlines()[0] / [1]). With TCP fragmentation, this can raise an
IndexError. See IA > Network & command queue.
Code / documentation mismatches¶
The code does not always match the docstrings/README
- I/O loop:
mainusesselect-with-timeout polling (select.select([...], [], [], 0.1)), not theselectorsmodule, contrary to the docstrings and theREADME. The main loop is a non-blockingwhile 1, not a busy-wait-free event loop. - README FSM diagram: the historical diagram (sound-based RALLY,
EXPLOREas the default state, aFORKloop) does not match the implementation:RALLYis coordinate-based, the initial state issurvive, andFORKis unreachable.
See IA > Decision loop and IA > Strategy (FSM).
Debug leftovers and configuration¶
Items to clean up
- Leftover debug
print()calls:ai/src/strategy/states/collect.py:50and:95,ai/src/strategy/states/incant_prep.py:77. pyproject.toml: the wheel target[tool.hatch.build.targets.wheel]referencespackages=["src/zappy_ai"], a non-existent directory. The wheel build is thus misconfigured — with no impact, since the client is run directly (via./zappy_ai), not installed.
Server (C++)¶
Food representation mismatch
The food quantity does not have the same representation depending on the consumer:
- the AI receives food in the
Inventoryasunits * 126(server/srcs/commands/CmdInventory.cpp:12); - the GUI receives, via
pin, the raw unit count (server/srcs/protocol/GUIProtocol.cpp:100).
Furthermore, the Player.hpp comment describes food as 1260 ticks, which
does not match the 10-unit model (1 unit consumed every 126 ticks). The
total duration is equivalent (10 × 126 = 1260); only the representation
differs. See Server > Players, teams & eggs.
Server events / commands
smg: the GUI eventsmgis defined inGUIProtocolbut no server call site emits it (appears unused).Connect_nbr: the command returns the count of remaining (unhatched) team eggs rather than a separately tracked count of free connection slots. The approximation is reasonable but is not, strictly speaking, a dedicated free-slot counter.
GUI (C++ / Raylib)¶
Raylib version not pinned
The Raylib version is pinned nowhere (build files, docs, binary). The
build assumes a system-installed libraylib (dynamic link
-lraylib -lGL ...) and a GL / GLSL 330-capable driver (the recolor.frag
shader targets #version 330). There is no vendoring, find_package,
pkg-config or FetchContent. The
GUI > Installing Raylib page therefore describes
a generic install (distribution package or build-from-source).
Dead code and ignored messages
gui/raylib/Window.*: thin wrapper that is not compiled (absent from theMakefileSRCS) and not used — dead/legacy code.mct: the handler is a no-op (the server expandsmctinto per-tilebct).sst: not handled by the GUI (no handler).- The GUI handles only the 21 messages registered in
MessageParser. Server-emittedsst/suc/sbpare ignored — which is consistent since the GUI only ever sendsGRAPHIC.
Player info panel (PlayerCard) stubbed
The 2D PlayerCard panel is wired in but inoperative: _focusedPlayerId
(Renderer3D.hpp:53) is never set (stays -1). The "focused player"
branch therefore never runs, and the card is always drawn empty, with the
hardcoded name "Salut" (PlayerCard.cpp:20).
Assets and camera shortcuts
- Assets: many on-disk asset folders are unused; only 13 animation
folders plus the shader, the font and the
playerCardelements are loaded. - Camera: the
READMEkey table is partly inconsistent with the actualIsoCameracode. Trust the code and the in-app hint ("W/S height | A/D radius | Q/E orbit").
See GUI > Rendering.
Build / documentation drift¶
Two AI directories
Two AI directories coexist:
ai/is the live AI (real Python code,zappy_ai, tests, docs);ia/is legacy / dead (only a shell script and empty directories, no.py).
The root Makefile correctly references ai/. The ia/ directory can be
ignored.
CI and docs
- CI: the
Jenkinsfiledoes not build or test the GUI: it only builds and tests the server (build, cppcheck, doctest, coverage) and runs the AI pytest suite. The only GitHub workflow (.github/workflows/mirror.yml) merely mirrors the repository. - Missing doc:
gui/README.mdreferences adocs/GUI_protocol.mdfile that does not exist.