Handshake¶
On connection, the server immediately sends WELCOME\n to any new client
(PendingClient, server/srcs/network/PendingClient.cpp). The client's first
line then determines its type:
- if it is the reserved keyword
GRAPHIC, the client becomes a GUI; - otherwise, the line is read as a team name: the client becomes an AI if an egg is still available in that team.
All routing is handled by ClientSessionManager
(server/srcs/core/ClientSessionManager.cpp).
AI handshake¶
sequenceDiagram
participant AI as zappy_ai
participant S as Server
S->>AI: WELCOME
AI->>S: <team-name>
Note over S: hatch an egg of the team
S->>AI: <CLIENT-NUM> (remaining slots)
S->>AI: <X> <Y> (world size)
The client sends its team name. If the team exists and at least one egg is free, the server:
- hatches an egg into a new player (
Player); - replies
<CLIENT-NUM>\n: the number of remaining slots in the team, i.e. the number of eggs still available after hatching; - replies
<X> <Y>\n: the width and height of the world.
(ClientSessionManager.cpp:123-127.)
Failure¶
Unknown team or no available egg
If the team name is unknown or the team has no egg left, the server replies
ko\n and closes the connection (ClientSessionManager.cpp).
Example (success)¶
Here team team1 had 6 eggs: after hatching, 5 remain, and the world is
10 × 10.
AI side
The AI client waits for the exact string WELCOME, sends the team name,
then reads CLIENT-NUM and X Y. The implementation assumes these last two
lines arrive in the same packet (splitlines()), which is fragile under TCP
fragmentation — see AI connection and
Known limitations. Reference:
ai/src/network/connection.py (do_handshake).
GUI handshake¶
sequenceDiagram
participant GUI as zappy_gui
participant S as Server
S->>GUI: WELCOME
GUI->>S: GRAPHIC
S->>GUI: msz X Y
S->>GUI: sgt T
loop for each team
S->>GUI: tna <team-name>
end
loop for each tile (mct → bct)
S->>GUI: bct X Y q0 q1 q2 q3 q4 q5 q6
end
loop for each player
S->>GUI: pnw #id X Y O L N
S->>GUI: plv #id L
S->>GUI: pin #id X Y q0..q6
end
loop for each egg
S->>GUI: enw #egg #player X Y
end
As soon as it receives GRAPHIC, the server performs a full initial dump of
the world state, in this order (ClientSessionManager.cpp:31-66):
msz X Y— map size;sgt T— current frequency/time unit;tna <name>— one message per team;- the whole map:
sendMctiterates over all tiles and emits onebctper tile (the GUI therefore never receives an aggregatedmct, see the warning below); - for each already-present player:
pnw, thenplv, thenpin; - for each existing egg:
enw.
Example (excerpt)¶
C -> S : GRAPHIC
S -> C : msz 10 10
S -> C : sgt 100
S -> C : tna team1
S -> C : tna team2
S -> C : bct 0 0 1 0 0 0 0 0 0
S -> C : bct 1 0 0 1 0 0 0 0 0
...
S -> C : bct 9 9 0 0 0 0 0 0 0
S -> C : pnw #1 4 5 2 1 team1
S -> C : plv #1 1
S -> C : pin #1 4 5 10 0 0 0 0 0 0
S -> C : enw #3 #-1 7 2
In pnw #1 4 5 2 1 team1, player #1 is at (4,5), oriented 2 (East), level
1, team team1. The detailed format of each event is given in
GUI ↔ Server.
mct always expanded into bct
The server never emits a consolidated mct event: it "explodes" it into a
series of bct (one per tile). On the GUI side, the onMct handler exists
but is deliberately a no-op. See Known limitations.