draugr_contrib /SDK/docs/en/PROTOCOL.md

Language MARKDOWN Lines 353
MD5 Hash 8c3715a61e9125abd9d1f8682a2b6e81
Repository https://bitbucket.org/ehvattum/draugr_contrib.git View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#SKYPORT AI COMPETITION PROTOCOL REV. 1
***

NOTE
----

If you have obtained this file through downloading the SDK, make sure you have
the latest versions. New versions of the SDK may be continuously released up
until the competition. You can read a brand-new, in-development version of this
document online at

https://github.com/Amadiro/Skyport-logic/blob/master/docs/en/PROTOCOL.md

SYNOPSIS
--------
This file describes the protocol **used by the AIs to communicate with the
Server.** The revision described in this protocol is **rev1**.
Note that lines prefixed with **">"** describe **"incoming"** data, that is, data
sent from the server to the AI client, while lines prefixed with **"<"**
describe **"outgoing"** data, that is, data the AI client sends to the server.
Note also that messages in this document are broken up into several lines
for clarity, and are adorned with explanatory comments. however, when they
are sent to the server, they need to be all on one single line without any
comments.

TRANSPORT
--------
The transport protocol used is **line-based TCP**. The server accepts UNIX-style
line-endings (\n) and windows-style line-endings (\r\n).
When reading from the socket, make sure that you **don't limit the length of
your lines**, as some packets may end up rather large.

CODEC & FORMAT
--------------
Codec used for all transmissions is a **line-based JSON format**. This has been
chosen to avoid the trouble of making a separate format and requiring the
AIs to implement a parser for it. **JSON is a simple, text-based format with
a syntax inspired by javascript**.
Read about JSON here: http://json.org/
At the bottom of the page, you will find a list of existing JSON parsers for
various languages. This protocol does not use any special JSON features, does
not require you to have capabilities like partial JSON parsing, and does not
require you to deal with special characters/unicode. However, chosing a JSON
parser that is reasonably fast may give you an advantage.

HANDSHAKE
---------
Handshake sent by the AI to establish the connection.
**Sent immediately upon connecting.** If no handshake is sent after 10 seconds,
the server will drop the connection.

    < {"message":"connect",
    <  "revision":REVISION,  // The protocol revision as integer, i.e. 1
    <  "name":NAME // The name of your AI. String with less than 16 letters.
    < }
    
If the handshake was successful, the server answers with
    
    > {"message":"connect",
    >  "status":true
    > }
    
Otherwise it will send an error.


GAMESTART
---------
Before the game starts, the server sends an **initial gamestate** to all AIs, with
the **TURN-NUMBER = 0** and no players. This gamestate looks otherwise **exactly like a normal gamestate**,
but should not be replied to. The server will reject all replies.
After the operator presses a button, an ENDTURN packet is sent, and the actual gameplay starts**.
The intent is to give all clients time to initialize and process the board, resources &
starting-positions into datastructures.

LOADOUT
-------
This is the loadout used by the AI to chose the weapons.

    < {"message":"loadout",
    <  "primary-weapon":"laser",    // can be "laser", "mortar", "droid"
    <  "secondary-weapon":"mortar", // ditto
    < }

The weapon loadout should be sent to the server by the AI after the GAMESTART
packet was sent, and before the first GAMESTATE packet is sent. If no loadout
is sent before the first GAMESTATE is sent, you are kicked off the server.
You cannot select the same weapon twice.

GAMESTATE
---------
Gamestate sent by the server to each of the AIs **every round**. You may use
any information contained in this packet to your advantage however you like.
If it is your turn (you are the first player in the rotating "players" list,)
**you have 3 seconds to reply with 3 actions packets.** Any actions you send
after the 3 seconds are over, are discarded. This means for instance that you
could send one action at 1s, another action at 2s, and the third action at 3s,
but the third action will likely arrive at the server-end after the cutoff
and will be discarded. The first two actions will still be carried out for you.
After a turn is over, the ENDTURN packet is sent.

    > {"message":"gamestate",
    >  "turn": TURN-NUMBER,  // turn-number starting at 1, i.e. this would be the TURN-NUMBERth turn.
    >  "map": MAP-OBJECT,         // object describing all tiles. See MAP-OBJECT below for details.
    >  "players":[PLAYER1, PLAYER2, ...] // rotating list of AIs in the game. This turn is PLAYER1s.
    > }

    
MAP-OBJECT
----------
     J-coordinate                      K-coordinate
      \                               /
       \                             /
        \                _____      /
         \         <0>  /     \  <0>
          \            /       \
           \     ,----(   0,0   )----.
            <1> /      \       /      \ <1>
         _____ /  1,0   \_____/  0,1   \_____
    <2> /      \        /     \        /     \  <2>
       /        \      /       \      /       \
      (   2,0    )----(   1,1   )----(   0,2   )
       \        /      \       /      \       /
        \_____ /  2,1   \_____/  1,2   \_____/
               \        /     \        /
                \      /       \      /
                 `----(   2,2   )----'
               .       \       /      .
              .         \_____/        .
             .                          .

The map-object looks as follows:
             
        
    > {"j-length": MAP-WIDTH-IN-J-DIRECTION // size of the map in the J-direction
    >  "k-length": MAP-WIDTH-IN-K-DIRECTION // size of the map in the K-direction
    >  "data": [ // the map data, one J-"column" at a time
    >          [TILE(0,0), TILE(0,1), TILE(0,2), ...],
    >          [TILE(1,0), TILE(1,1), TILE(1,2), ...],
    >          [TILE(2,0), TILE(2,1), TILE(2,2), ...]]
    > }

`TILE(j, k)` is the tile-type at coordinate (j, k).
`TILE(j, k)` is simply a string of one of the following types:
* "G" -- "GRASS"
* "V" -- "VOID"
* "S" -- "SPAWN"
* "E" -- "EXPLOSIUM"
* "R" -- "RUBIDIUM"
* "C" -- "SCRAP"
* "O" -- "ROCK"

See the docs/GAME.md file for a description of how each of these behaves.
The `TILE(j,k)` notation used here is simply to indicate that this tile
is at position (j,k), the (j,k) is not part of the actual protocol.
    
### EXAMPLE:

    > {"data": [                 // the map data, one J-"column" at a time
    >          ["G", "E", "S"],  // first J-column
    >          ["G", "R", "V"],  // second J-column
    >          ["C", "G", "G"]]  // third J-column
    > }
    
"extracts" to

     J-coordinate                      K-coordinate
      \                               /
       \                             /
        \                _____      /
         \         <0>  /     \  <0>
          \            /       \
           \     ,----(    G    )----.
            <1> /      \       /      \ <1>
         _____ /   G    \_____/   E    \_____
    <2> /      \        /     \        /     \  <2>
       /        \      /       \      /       \
      (    C     )----(    R    )----(    S    )
       \        /      \       /      \       /
        \_____ /   G    \_____/   V    \_____/
               \        /     \        /
                \      /       \      /
                 `----(    G    )----'
               .       \       /      .
              .         \_____/        .
             .                          .

PLAYER
------
    > {"name":"players-name",
    >  "primary-weapon":
    >    {"name":"laser", "level":1}, // "laser", "mortar", "droid", the number is the tier (1,2 or 3)
    >  "secondary-weapon":
    >    {"name":"mortar", "level":1},// ditto
    >  "health":20,                   // int from 0 to 100
    >  "score":120,                   // positive int (or 0)
    >  "position":"j,k"}              // position in j/k coordinates (global)
    
ENDTURN
-------
After a turn is over (the three-seconds deadline is over), an ENDTURN packet is sent. It is not
really necessary to react to the ENDTURN message in any way, it's merely a convenience message
so that all AIs know that the deadline for sending actions by the active player is over.

    > {"message":"endturn"}

    
COMPLETE EXAMPLE
----------------

TODO

ACTIONS (AI)
-----------
Actions that can be taken by the AI.

    > {"message":"action"
    >  "type":TYPE,
    >  ...
    > }

The following actions are valid:

### MOVEMENT/TACTICAL:
    
**Move** a tile:

    > {"message":"action", "type":"move",
    >  "direction":"up" // can be "up", "down", "right-up", "right-down", "left-up", "left-down"
    > }

**Upgrade** a weapon:
    
    > {"message":"action", "type":"upgrade", "weapon":"mortar"} // can be "mortar", "laser" or "droid"

**Mine** the current tile:

    > {"message":"action", "type":"mine"}
    
### ATTACK/OFFENSIVE:
    
Shoot the **laser**:
    
    > {"message":"action", "type":"laser",
    >  "direction":"up", // can be "up", "down", "right-up", "right-down", "left-up", "left-down"
    > }

Shoot the **mortar**:
    
    > {"message":"action", "type":"mortar",
    >  "coordinates":"3,2" // relative J,K coordinates from the players position
    > }

Launch the **droid**:
    
    > {"message":"action", "type":"droid",
    >  "sequence":["up", "rightUp", "rightDown", "down"] // sequence of directions
    > }

ACTIONS (Server)
----------------
Actions that are taken by the AI are validated by the server,
and then re-broadcasted to all AIs. For convenience, a "from" field is attached.

### EXAMPLES
    
**Moved** a tile:

    < {"message":"action", "type":"move",
    <  "direction":"up", // can be "up", "down", "right-up", "right-down", "left-up", "left-down"
    <  "from":"username" // user who performed the move
    < }
    
**Upgraded** a weapon:
    
    < {"message":"action", "type":"upgrade", "weapon":"mortar",
    <  "from":"username" // user who upgraded the mortar
    < }
        

ERRORS
------    
If the server encounters an error, either due to an invalid protocol command, or due to
an invalid move, it will send back an error object. The server may disconnect the AI that
provoked the error, depending on the severity.

Example:

    < {"error":"You need to send a handshake first"}

Error messages are not machine-readable and mainly meant for human debugging. Hence
the exact error-messages are not documented and may change. An AI should never rely
on some behaviour that provokes an error from the server.

DEATH:
------
If a player dies, his health is set to 0, but he may still be on the field. A player
with health 0 is not actually alive, and will be reset to his respective spawn-point
during the next round. A player with health 0 will never have a turn (the server will
refill the players health to 100 before he gets a turn again) and you can simply ignore
him. Hitting a tile with a dead player on it will not award you any points, or indeed
have any effect at large.

DISCONNECTING:
--------------
A disconnected AI will remain in the game, and continue to rack up penality points for
not doing anything. Killing the disconnected AI will still reward you with the normal
amounts of damage- and bonus-points. Once disconnected, you cannot re-connect, so you
should take care to not drop the connection under any circumstances.

EXAMPLE SESSIONS
----------------
The following example session demonstrates the communication between an AI and
the server in a one-on-one match on a very simple map.

    < {"message":"connect", "revision":1, "name":"you"}

    > {"message":"connect", "status":true}

    > {"message":"gamestate",
    >  "turn": 0,
    >  "map": {"j-length": 5,
    >          "k-length": 5,
    >          "data": [
    >                  ["R", "G", "V", "G", "V"],
    >                  ["G", "E", "G", "G", "S"],
    >                  ["G", "G", "O", "G", "G"],
    >                  ["S", "G", "G", "C", "G"]
    >                  ["V", "G", "V", "G", "G"]]
    >         },
    >  "players":[
    >             {"name":"playerA", "primary-weapon":{"name":"laser", "level":1},
    >               "secondary-weapon":{"name":"laser", "level":1}, "health":100,
    >               "score":0, "position":"4,0"},
    >             {"name":"you", "primary-weapon":{"name":"laser", "level":1},
    >              "secondary-weapon":{"name":"droid", "level":1}, "health":100,
    >              "score":0, "position":"0,4"},
    >            ]
    > }

                 __
              __/R \__
           __/G \__/G \__
        __/G \__/E \__/V \__
     __/S \__/G \__/G \__/G \__
    /V \__/G \__/O \__/G \__/V \
    \*_/G \__/G \__/G \__/S \*_/
       \__/V \__/C \__/G \__/
          \__/G \__/G \__/
             \__/G \__/
                \__/

                
Back to Top