1 =========================================================================
3 =========================================================================
5 If delta is enabled for this packet the packet-payload (after the bytes
6 used by the packet-header) is followed by the delta-header. (See HACKING
7 to learn how to understand the packet-header.) The delta-header
8 is a bitvector which represents all non-key fields of the packet. If
9 the field has changed the corresponding bit is set and the field
10 value is so included in delta-body. The values of the unchanged fields
11 will be filled in from an old version at the receiving side. The old
12 version filled in from is the previous packet of the same kind that has
13 the same value in each key field. (If the packet's kind don't have any
14 key fields the previous packet of the same kind is used) If no old
15 version exists the unchanged fields will be assumed to be zero.
17 For bool field another optimization called bool-header-folding is
18 applied. Instead of sending an indicator in the bitvector if the given
19 bool values has changed (and so using 1 byte for the real value) the
20 actual value of the bool is transfered in the bitvector bit of this
23 Another optimization called array-diff is used to reduce the amount of
24 elements transfered if an array is changed. This is independent of the
25 delta-header bit i.e. it will only be used if the array has changed
26 its value and the bit indicates this. Instead of transferring the
27 whole array only a list of (index, new value of this index) pairs are
28 transferred. The index is 8bit and the end of this pair list is
29 denoted by an index of 255.
31 =========================================================================
33 =========================================================================
35 To further reduce the network traffic the (delta) packets are
36 compressed using the DEFLATE compression algorithm.
37 To get better compression results multiple packets are
38 grouped together and compressed into a chunk. This chunk is then
39 transfered as a normal packet. A chunk packet starts with the 2 byte
40 length field which every packet has. A chunk packet has no type. A
41 chunk packet is identified by having a too large length field. If the
42 length of the packet is over COMPRESSION_BORDER it is a chunk
43 packet. It will be uncompressed at the receiving side and re-feed into
46 If the length of the chunk packet can't be expressed in the available
47 space of the 16bit length field (>48kb) the chunk is sent as a jumbo
48 packet. The difference between a normal chunk packet and a jumbo chunk
49 packet is that the jumbo packet has JUMBO_SIZE in the size field and
50 has an additional 4 byte len field after the 2 byte len field. The
51 second len field contains the the size of the whole packet (2 byte
52 first length field + 4 byte second length field + compressed data).
53 The size field of a normal chunk packet is its size + COMPRESSION_BORDER.
55 Packets are grouped for the compression based on the
56 PACKET_PROCESSING_STARTED/PACKET_PROCESSING_FINISHED and
57 PACKET_FREEZE_HINT/PACKET_THAW_HINT packet pairs. If the first
58 (freeze) packet is encountered the packets till the second (thaw)
59 packet are put into a queue. This queue is then compressed and sent as
60 a chunk packet. If the compression would expand in size the queued
61 packets are sent uncompressed as "normal" packets.
63 The compression level can be controlled by the
64 FREECIV_COMPRESSION_LEVEL environment variable.
66 =========================================================================
68 =========================================================================
70 There are four file/filesets involved in the delta protocol:
71 1) the definition file (common/packets.def).
72 2) the generator (common/generate_packets.py).
73 3) the generated files (*/*_gen.[ch] or as a list
74 client/civclient_gen.c, client/packhand_gen.h, common/packets_gen.c,
75 common/packets_gen.h, server/hand_gen.h and server/srv_main_gen.c).
76 4) the overview (README.delta, this file)
78 The definition file lists all valid packet types with their
79 fields. The generator takes this as input and creates the generated
82 For adding and/or removing packets and/or fields you only have to
83 touch the definition file. If you however plan to change the generated
84 code (adding more statistics for example) you have to change the
87 =========================================================================
88 Changing the definition file
89 =========================================================================
92 1) choose an unused packet number. The generator will make sure that
93 you don't use the same number two times.
94 2) choose a packet name. It should follow the naming style of the
95 other packets: PACKET_<group>_<remaining>. <group> may be SERVER,
96 CITY, UNIT, PLAYER, DIPLOMACY and so on.
97 3) decide if this packet goes from server to client or client to server
98 4) choose the field names and types
99 5) choose packet and field flags
100 6) write the entry into the corresponding section of common/packets.def
102 If you add a field which is a struct (say "foobar") you have to write
103 the following functions: dio_get_foobar, dio_put_foobar and
107 1) add a mandatory capability
108 2) remove the entry from common/packets.def
112 1) add a mandatory capability
113 2) add a normal field line:
116 1) add a non-mandatory capability (say "new_version")
117 2) add a normal field line containing this capability in an add-cap
119 COORD x; add-cap(new_version)
123 1) add a mandatory capability
124 2) remove the corresponding field line
126 1) add a non-mandatory capability (say "cleanup")
127 2) add to the corresponding field line a remove-cap flag
129 After changing the definition file the generator has to be run. The
130 common/Makefile will take care of this. You don't need to run
131 autoconf/automake/configure.
133 =========================================================================
134 Capabilities and variants
135 =========================================================================
137 The generator has to generate code which supports different
138 capabilities at runtime according to the specification given in the
139 definitions with add-cap and remove-cap. The generator will find the
140 set of used capabilities for a given packet. Lets say there are two
141 fields with "add-cap(cap1)" and one field with an "remove-cap(cap2)"
142 flag. So the set of capabilities are cap1, cap2. At runtime the
143 generated code may run under 4 different capabilities:
144 - neither cap1 nor cap2 are set
145 - cap1 is set but cap2 isn't
146 - cap1 is not set but cap2 is
147 - cap1 and cap2 are set
149 Each of these combinations is called a variant. If n is the number of
150 capabilities used by the packet the number of variants is 2^n.
152 For each of these variant a seperate send and receive function will be
153 generated. The variant for a packet and a connection are calculated
154 once and then saved in the connection struct.