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. To get better compression results multiple packets are
37 grouped together and compressed into a chunk. This chunk is then
38 transfered as a normal packet. A chunk packet starts with the 2 byte
39 length field which every packet has. A chunk packet has no type. A
40 chunk packet is identified by having a too large length field. If the
41 length of the packet is over COMPRESSION_BORDER it is a chunk
42 packet. It will be uncompressed at the receiving side and re-feed into
45 If the length of the chunk packet can't be expressed in the available
46 space of the 16bit length field (>48kb) the chunk is sent as a jumbo
47 packet. The difference between a normal chunk packet and a jumbo chunk
48 packet is that the jumbo packet has JUMBO_SIZE in the size field and
49 has an additional 4 byte len field after the 2 byte len field. The
50 second len field contains the the size of the whole packet (2 byte
51 first length field + 4 byte second length field + compressed data).
53 Packets are grouped for the compression based on the
54 PACKET_PROCESSING_STARTED/PACKET_PROCESSING_FINISHED and
55 PACKET_FREEZE_HINT/PACKET_THAW_HINT packet pairs. If the first
56 (freeze) packet is encountered the packets till the second (thaw)
57 packet are put into a queue. This queue is then compressed and sent as
58 a chunk packet. If the compression would expand in size the queued
59 packets are sent uncompressed as "normal" packets.
61 The compression level can be controlled by the
62 FREECIV_COMPRESSION_LEVEL environment variable.
64 =========================================================================
66 =========================================================================
68 There are four file/filesets involved in the delta protocol:
69 1) the definition file (common/packets.def).
70 2) the generator (common/generate_packets.py).
71 3) the generated files (*/*_gen.[ch] or as a list
72 client/civclient_gen.c, client/packhand_gen.h, common/packets_gen.c,
73 common/packets_gen.h, server/hand_gen.h and server/srv_main_gen.c).
74 4) the overview (README.delta, this file)
76 The definition file lists all valid packet types with their
77 fields. The generator takes this as input and creates the generated
80 For adding and/or removing packets and/or fields you only have to
81 touch the definition file. If you however plan to change the generated
82 code (adding more statistics for example) you have to change the
85 =========================================================================
86 Changing the definition file
87 =========================================================================
90 1) choose an unused packet number. The generator will make sure that
91 you don't use the same number two times.
92 2) choose a packet name. It should follow the naming style of the
93 other packets: PACKET_<group>_<remaining>. <group> may be SERVER,
94 CITY, UNIT, PLAYER, DIPLOMACY and so on.
95 3) decide if this packet goes from server to client or client to server
96 4) choose the field names and types
97 5) choose packet and field flags
98 6) write the entry into the corresponding section of common/packets.def
100 If you add a field which is a struct (say "foobar") you have to write
101 the following functions: dio_get_foobar, dio_put_foobar and
105 1) add a mandatory capability
106 2) remove the entry from common/packets.def
110 1) add a mandatory capability
111 2) add a normal field line:
114 1) add a non-mandatory capability (say "new_version")
115 2) add a normal field line containing this capability in an add-cap
117 COORD x; add-cap(new_version)
121 1) add a mandatory capability
122 2) remove the corresponding field line
124 1) add a non-mandatory capability (say "cleanup")
125 2) add to the corresponding field line a remove-cap flag
127 After changing the definition file the generator has to be run. The
128 common/Makefile will take care of this. You don't need to run
129 autoconf/automake/configure.
131 =========================================================================
132 Capabilities and variants
133 =========================================================================
135 The generator has to generate code which supports different
136 capabilities at runtime according to the specification given in the
137 definitions with add-cap and remove-cap. The generator will find the
138 set of used capabilities for a given packet. Lets say there are two
139 fields with "add-cap(cap1)" and one field with an "remove-cap(cap2)"
140 flag. So the set of capabilities are cap1, cap2. At runtime the
141 generated code may run under 4 different capabilities:
142 - neither cap1 nor cap2 are set
143 - cap1 is set but cap2 isn't
144 - cap1 is not set but cap2 is
145 - cap1 and cap2 are set
147 Each of these combinations is called a variant. If n is the number of
148 capabilities used by the packet the number of variants is 2^n.
150 For each of these variant a seperate send and receive function will be
151 generated. The variant for a packet and a connection are calculated
152 once and then saved in the connection struct.