]> git.pond.sub.org Git - empserver/blob - doc/xdump
doc/xdump: Fix definition of identifier in grammar
[empserver] / doc / xdump
1 Introduction
2
3 Empire is designed as a smart server with dumb clients.  An Empire
4 client need to know nothing about the game.  Even telnet would do.  In
5 fact, empire-client is little more than a slightly specialized telnet.
6
7 In such a design, presentation is in the server, and it is designed
8 for human consumption.  Ideally, presentation and logic are cleanly
9 separated, for easy selection between different presentations.
10 There's no such separation in the Empire server, and separating them
11 now would be a herculean effort.
12
13 Thus, smart clients have to work with output designed for humans.
14 That's not especially hard, just an awful lot of tedious work, and the
15 result gets easily broken by minor changes in output format, which
16 humans hardly notice.
17
18 Instead of making smart clients parse output of commands designed for
19 humans, one can add commands designed for machines.  Such commands can
20 share the code implementing game rules with their counterparts for
21 humans.  To do that cleanly means separating logic and presentation.
22 Implementing them with their own copy of the code is no good --- how
23 would you ensure that the two copies implement precisely the same game
24 rules?
25
26 Except for commands that actually don't do anything.  There's a useful
27 class of such commands: commands to show game configuration and state
28 without altering it.  The only game rules involved are those that
29 govern who gets to see what.  Ensuring that those are obeyed is
30 tractable.
31
32 Empire has had one such command since the beginning: dump.  Empire
33 4.0.6 added more: sdump, ldump, pdump and ndump.  4.0.7 added lost and
34 support for incremental dumps.  These commands have served smart
35 clients well.  However, they cover just the most important part of the
36 game state (sectors, ships, planes, land units, nukes), and no game
37 configuration.  They are not quite complete even for what they attempt
38 to cover.  Finally, their output is harder to parse than necessary.
39
40 The xdump command is designed to be the dump to end all dumps.
41
42 Like many good ideas, xdump has secondary uses.  Dumping game state as
43 text can be one half of a game export/import facility.  Useful to
44 migrate games to different machines or even, with some text mangling
45 perhaps, different server versions.  We will see below that xdump
46 isn't quite sufficient for that, but it's a start.
47
48 Means to import game configuration let you customize your game without
49 recompiling the server.  As we will see, configuration files have
50 different requirements, which xdump doesn't satisfy without some
51 extensions.
52
53 If game import code can edit everything, then a deity command capable
54 of editing everything is possible.  Proof-of-concept code exists (not
55 in the tree yet).
56
57
58 Analysis of the data to dump
59
60 Game state consists of a fixed set of table files (sector, ship, ...),
61 telegram files, and a few miscellaneous files.  Game configuration
62 consists of a fixed set of configuration tables and scalar parameters.
63
64 A table is an ordered set of records (table rows).  All records have
65 the same fields (table columns), which are statically typed.
66
67 Fields may be integers, floating-point numbers, x- or y-coordinates,
68 symbols and symbol sets encoded as integers in a way specific to the
69 server version, and character arrays.  Configuration table fields may
70 be pointers to zero-terminated strings, null pointers allowed.  No
71 other pointers occur.  Unions do not occur.
72
73
74 Requirements analysis
75
76 Requirements:
77
78 * Capable to dump all tables.
79
80 * Can do incremental dumps.
81
82 * Output is text.
83
84 * Output is reasonably compact.
85
86 * Output is trivial to parse.  Triviality test: if it's easy in AWK, C
87   (no lex & yacc, just stdio), Lisp (just reader) and Perl (base
88   language, no modules), then it's trivial enough.
89
90 * Output identifies itself.
91
92 * Output is self-contained; symbol encoding is explicit.
93
94 * KISS: Keep it simple, stupid.
95
96 Non-requirements:
97
98 * Generality.  We're not trying to design a general mechanism for
99   dumping C data.
100
101 * Completeness.  We're not trying to dump stuff other than tables.
102
103 * Abstraction.  We're not trying to hide how things are stored in the
104   server.  When storage changes, xdump output will change as well, and
105   consumers need to be updated.  This is not because abstraction
106   wouldn't be nice to have, just because we don't feel up to the task
107   of designing one.
108
109
110 Principles of Design
111
112 Traditional dumps have a dump function for every table.  These
113 functions are simple, but exceedingly dull and repetitive.
114
115 The selector code works differently.  Each table has a descriptor,
116 which among other things defines a dictionary of selector descriptors.
117 A selector descriptor describes a field (table column) visible to
118 players.  This is what we call meta-data (data about data).  The
119 selector code knows nothing about the individual tables, it just
120 interprets meta-data.  That's smart, as it keeps the dull, repetitive
121 parts in more easily maintainable meta-data rather than code.
122
123 xdump follows the selector design, and uses the existing selector
124 meta-data.  This requires extending the meta-data to configuration
125 tables, which weren't previously covered.  It also requires some
126 generalization of selector descriptors, so that all fields can be
127 covered.
128
129 To sum up, meta-data consists of a table of tables, and for each table
130 a table of selectors (table of columns, so to speak).  It is specific
131 to the server version and how it is compiled on the host.
132
133 To interpret a table xdump, you need its meta-data, because without it
134 you have no idea what the columns mean.  As meta-data is just a bunch
135 of tables, xdump can dump it.  But now you need meta-meta-data to make
136 sense of the meta-data.  Fortunately, meta-meta-data is the same for
137 all xdumps, and therefore the recursion terminates with a single
138 meta-meta-table.
139
140 xdump dumps symbols and symbol sets as integers.  To decode them, you
141 need to know what the symbol numbers and symbol set bits mean.  For
142 this purpose, field meta-data includes the table ID of a symbol table.
143 A symbol table is a table of value-name pairs, with the value in the
144 leftmost column.  You decode a symbol value by looking it up in the
145 symbol table.  You decode a symbol set value by looking up its bits
146 (powers of two) in the symbol table.
147
148 Some integer fields are actually keys in other tables.  For instance,
149 ship field type is a key in the table of ship types ship-chr, and
150 plane field ship is a key in the ship table.  Key -1 is special: it's
151 a null key.  Meta-data encodes these table reference just like for
152 symbols: the meta-data has the ID of the referenced table, and that
153 table has the key in the leftmost column.  Obviously, that leftmost
154 column is a table key as well, referencing the table itself.
155
156 A table with its key in the leftmost column can be dumped partially.
157 Without such a key, you need to count records to find the record
158 index, and that works only if you can see a prefix of the complete
159 table.
160
161
162 Syntax of xdump command
163
164 See info xdump.
165
166
167 The xdump output Language
168
169 Because the output is to be parsed by machines, it needs to be
170 precisely specified.  We use EBNF (ISO 14977) for syntax, except we
171 use '-' in meta-identifiers and omit the concatenation symbol ','.
172
173     table = header { record } footer ;
174     header = "XDUMP" space [ "meta" space ]
175              identifier space timestamp newline ;
176     identifier = id-char1 { id-char } ;
177     id-char1 = ? ASCII letter ? ;
178     id-char = ? ASCII characters 33..126 except '"#()<>=' ? ;
179     timestamp = intnum ;
180     footer = "/" number newline ;
181     record = [ fields ] newline ;
182     fields = field { space field } ;
183     field = intnum | flonum | string ;
184     intnum = ? integer in printf %d format ? ;
185     flonum = ? floating-point in printf %g format ? ;
186     string = "nil"
187            | '"' { str-char } '"' ;
188     str-char = "\\" octal-digit octal-digit octal-digit
189              | ? ASCII characters 33..126 except '"' and '\\' ? ;
190     octal-digit = ? '0'..'7' ? ;
191     space = ' ' ;
192     newline = ? ASCII character 10 ? ;
193
194 Notes:
195
196 * The syntax for flonum is debatable.  Precise conversion between
197   floating-point and decimal is hard, and C libraries are not required
198   to be precise.  Using C99's %a format for flonum would avoid the
199   issue, but some programming environments may have trouble converting
200   that back to floating-point.  We may change to %a anyway in the
201   future.  Clients are advised to accept both.
202
203 * Strings syntax could perhaps profit from the remaining C escape
204   sequences.  Except for '\"': adding that would complicate regular
205   expressions matching the string, and thus violate the `trivial to
206   parse' requirement
207
208 * Space is to be taken literally: a single space character.  Not a
209   non-empty sequence of white-space.
210
211 Semantics:
212
213 * The table identifier in the header is one of the names in xdump table.
214
215 * The timestamp increases monotonically.  It has a noticeable
216   granularity: game state may change between an xdump and the next
217   timestamp increase.  If the table has a timestamp field, clients can
218   xdump incrementally by using a conditional ?timestamp>T, where T is
219   one less than the timestamp received with the last xdump of that
220   table.
221
222   Timestamp values are currently seconds since the epoch, but this
223   might change, and clients are advised not to rely on it.
224
225 * The number in the footer matches the number of records.
226
227 * Fields match their meta-data (see Meta-Data below).
228
229 * "nil" represents a null string (which is not the same as an empty
230   string).  Otherwise, fields are to be interpreted just like C
231   literals.
232
233
234 Meta-Data
235
236 Table meta-data is in xdump table.  Fields:
237
238 * uid: The table ID, key for xdump table.  IDs depend on the server
239   version; clients should not hard-code them.  This is the leftmost
240   field.
241
242 * name: The table name.  Clients may identify tables by name.
243
244 Field meta-data for table T is in xdump meta T.  The order of fields
245 in the xdump T matches the order of records in xdump meta T.  Fields
246 of xdump meta T are:
247
248 * name: The field name.  Matches the selector name.  Clients may
249   identify fields by name.  This is the leftmost field.
250
251 * type: The field's data type, a symbol.  Clients should use this only
252   as key for the symbol table.  Symbols are:
253   - "d", field uses intnum syntax
254   - "g", field uses flonum syntax
255   - "s", field uses string syntax
256   - "c", field uses string syntax
257
258 * flags: The field's flags, a symbol set.  Flags are:
259   - "deity", field visible only to deities
260   - "bits", field is a symbol set, field type must encode symbol "d",
261     field table must not be -1.
262   - "hidden", field value is masked for contact when option HIDDEN is
263     enabled.  Masked values are replaced by -1.
264
265 * len: If non-zero, then the record encodes an array with that many
266   elements.  If field type encodes symbol "c", it is a character
267   array, which is dumped as a single string field.  Else, the array is
268   dumped as len fields.
269
270 * table: Key for xdump table.  Unless -1, it defines the table
271   referenced by the field value.  Field type must encode symbol "d"
272   then.
273
274 Symbol table fields:
275
276 * value: The symbol's encoding as integer.  If the symbol can be
277   element of a symbol set, this is a power of two.
278
279 * name: The symbol's name.
280
281
282 Notes on xdump Implementation
283
284 Overall impact on the server code is low.
285
286 To keeps xdump simple, storage of game state and game configuration
287 tables has been unified under the common empfile abstraction, making
288 nxtitem-iterators and selectors equally applicable to all tables.
289
290 xdump required a few extensions to meta-data, which may become useful
291 in other places as well:
292
293 * Selectors can now deal with arrays (revived struct castr member
294   ca_len).  Not yet available on the Empire command line.
295
296 * Selector meta-data can now express that a selector value is a key
297   for another table (new struct castr member ca_table).  The selector
298   code doesn't use that, yet.
299
300 * Redundant selectors can be marked so that xdump ignores them (new
301   struct castr member ca_dump).
302
303 Meta-data is in empfile[] (table meta-data), src/lib/global/nsc.c
304 (selector meta-data), src/lib/global/symbol.c (symbol tables).  The
305 command is in src/lib/commands/xdump.c, unsurprisingly.
306
307
308 Hints on Using xdump in Clients
309
310 Let's explore how to dump a game.  To make sense of a table, we need
311 its meta-data, and to make sense of that table, we need meta-meta
312 data.  So we start with that:
313
314     [3:640] Command : xdump meta meta
315     XDUMP meta meta 1464554085
316     "name" 3 0 0 -1
317     "type" 8 0 0 33
318     "flags" 8 8 0 32
319     "len" 7 0 0 -1
320     "table" 8 0 0 26
321     /5
322
323 To interpret this table, we have to know the field names and their
324 meanings.  Clients hard-code them.  They should be prepared to accept
325 and ignore additional fields, and to cope with changes in field order,
326 except they may rely on "name" coming first.
327
328 A word on hard-coding.  Clients hard-code *names*.  The numbers used
329 for table IDs and to encode symbols are none of the client's business.
330
331 The encoding doesn't normally change within a game.  Except when the
332 game is migrated to a sufficiently different server.  That's a rare
333 event.  Clients may wish to provide for such changes anyway, by
334 decoupling the client's encoding from the server's, and dumping fresh
335 meta-data on login.  Incremental meta-data dump would be nice to have.
336
337 So we don't know how symbol type and symbol set flags are encoded.  To
338 decode them, we need their symbol tables.  However, we need flags and
339 type only for tables we don't know, and there's one more table we do
340 know, namely the table of tables.  Let's dump that next, starting with
341 its meta-data:
342
343     [3:640] Command : xdump meta table
344     XDUMP meta table 1464554085
345     "uid" 8 0 0 26
346     "name" 3 0 0 -1
347     /2
348
349 Because xdump table is referenced from elsewhere (xdump meta meta
350 field table), the leftmost field must contain the key.  Thus, the
351 leftmost field's meta-data field table must be the table ID of xdump
352 table itself.  Indeed, its value matches the one we got in xdump meta
353 meta.  Let's try to dump the table:
354
355     [5:640] Command : xdump 26 *
356     XDUMP table 1464554085
357     0 "sect"
358     1 "ship"
359 [...]
360     8 "nat"
361 [...]
362     18 "sect-chr"
363     19 "ship-chr"
364 [...]
365     26 "table"
366 [...]
367     /47
368
369 It worked!
370
371 Now dump the two symbol tables we postponed.  Because xdump accepts
372 table IDs as well as names, we don't have to know their names:
373
374     [5:640] Command : xdump meta 33
375     xdump meta 33
376     XDUMP meta meta-type 1464554085
377     "value" 8 0 0 -1
378     "name" 3 0 0 -1
379     /2
380
381     [6:640] Command : xdump 33 *
382     XDUMP meta-type 1464554085
383     1 "d"
384     2 "g"
385     3 "s"
386     4 "d"
387     5 "d"
388     6 "d"
389     7 "d"
390     8 "d"
391     9 "d"
392     10 "d"
393     11 "d"
394     12 "g"
395     13 "c"
396     /13
397
398     [7:640] Command : xdump meta 32
399     XDUMP meta meta-flags 1464554085
400     "value" 8 0 0 -1
401     "name" 3 0 0 -1
402     /2
403
404     [7:640] Command : xdump 32 *
405     XDUMP meta-flags 1464554085
406     1 "deity"
407     8 "bits"
408     16 "hidden"
409     /3
410
411 We now have complete meta-meta information:
412
413     name  type         flags  len  table
414     -----------------------------------------
415     name     s       (const)    0
416     type     d       (const)    0  meta-type
417     flags    d  (bits const)    0  meta-flags
418     len      d       (const)    0
419     table    d       (const)    0  table
420
421 Dumping the remaining tables is easy: just walk the table of tables.
422 Here's the first one:
423
424     [7:640] Command : xdump meta 0
425     XDUMP meta sect 1464554085
426     "owner" 5 0 0 8
427     "xloc" 9 0 0 -1
428     "yloc" 10 0 0 -1
429     "des" 4 0 0 18
430 [...]
431     /78
432
433 A whole load of tables referenced!  Only one of them (not shown above)
434 is a symbol table.
435
436 owner references table nat.  No surprise.
437
438 xloc and yloc together reference the sector table, but that's not
439 expressed in meta-data (yet).
440
441 Let's stop here before this gets too long and boring.  Experiment
442 yourself!  Check out example Perl code scripts/xdump.pl.
443
444
445 Analysis of xdump as Configuration File Format
446
447 xdump makes a lousy configuration format because it is unwieldy to
448 edit for humans.  That's because configuration files have different
449 requirements than dumps:
450
451 * Can be edited by humans with common tools, including text editors
452   and spreadsheets.
453
454   Using text editors requires a nice fixed-width table layout.
455   Spreadsheet import requires trivial field separation.  Tab character
456   field separator or fixed width columns should do.  The syntax should
457   allow all that, but not require it.
458
459   Trouble spots:
460
461   - xdump's rigid horizontal and vertical spacing makes it impossible
462     to align things visually.
463
464   - xdump uses one line per record, which can lead to excessively long
465     lines.
466
467   - xdump's string syntax requires octal escape for space.
468
469   - No comment syntax.
470
471 * Each table is self-contained.  You don't have to look into other
472   tables to make sense of it.
473
474   This conflicts with xdump's separation of data and meta-data.  You
475   need the table's meta-data to identify fields, and the referenced
476   symbol tables to decode symbols.
477
478 * Easy to parse.  Don't compromise legibility just to please some dumb
479   tool, though.
480
481 Since we're trying to apply xdump to the configuration file problem,
482 we get an additional requirement:
483
484 * Reasonably close to xdump.  Translation between machine-readable and
485   human-readable should be straightforward, if meta-data is available.
486
487 This leads to a human-readable dialect of the xdump language.
488
489
490 Human-Readable xdump Language
491
492 Fundamental difference to basic, machine-readable xdump: the rigid
493 single space between fields is replaced by the rule known from
494 programming languages: white-space (space and tab) separates tokens
495 and is otherwise ignored.  The space non-terminal is no longer needed.
496
497 Rationale: This allows visual alignment of columns and free mixing of
498 space and tab characters.
499
500 Comments start with "#" and extend to the end of the line.  They are
501 equivalent to a newline.
502
503 Rationale: Follow econfig syntax.
504
505 Tables with a record uid in the leftmost field can be `split
506 vertically' into multiple parts.  Each part must contain the same set
507 of records.  The leftmost field must be repeated in each part.  Other
508 fields may be repeated.  Repeated fields must be the same in all
509 parts.  Naturally, the parts together must provide the same fields as
510 a table that is not split.
511
512 Rationale: This is to let you avoid long lines.  Line continuation
513 syntax would be simpler, but turns out to be illegible.  Requiring
514 record uid is not technically necessary, as counting records works the
515 same whether a table is split or not.  Except humans can't count.
516 Perhaps this should be a recommendation for use rather than part of
517 the language.
518
519 EBNF changes:
520
521 * Header and footer:
522
523     header = "config" identifier newline colhdr newline ;
524     colhdr = { identifier [ "(" ( intnum | identifier ) ")" ] } [ "..." ] ;
525     footer = "/config" newline ;
526
527   If colhdr ends with "...", the table is continued in another part,
528   which shall follow immediately.
529
530   Rationale:
531
532   - The xdump needs to identify itself as human-readable, hence change
533     from "XDUMP" to "config".
534
535   - The timestamp in the header is useless for the applications we
536     have in mind for human-readable xdumps.  The number of records in
537     the footer is of marginal value at best, and a pain for humans to
538     update.
539
540   - The column header is due to the self-containedness requirement.
541     It contains just the essential bit of meta-data: the column names.
542
543 * Symbolic fields:
544
545     field = intnum | flonum | string | symbol | symset ;
546
547   Rationale:
548
549   - Syntax for symbols and sets of symbols is due to the
550     self-containedness requirement.  Machine-readable xdump gets away
551     with just numbers, which have to be decoded using meta-data.
552
553 * Friendlier numbers and strings:
554
555     flonum = ? floating-point in scanf %g format ? ;
556     str-char = "\\" octal-digit octal-digit octal-digit
557              | ? ASCII characters 32..126 except '"' and '\\' ? ;
558
559   Rationale:
560
561   - Machine-readable floating-point syntax is too rigid.  Accept
562     everything that scanf does.  Could also change intnum to %i
563     format, which accepts octal and hexadecimal in C syntax, but that
564     seems not worth the documentation bother.
565
566   - Machine-readable syntax requires \040 instead of space in strings
567     to allow trivial splitting into fields.  This is unacceptable here
568     due to the legibility requirement, hence the change to str-char.
569
570 * Parse nil as symbol:
571
572     string = '"' { str-char } '"' ;
573
574   Rationale: This is a technicality required to keep the parse
575   unambiguous.
576
577 * Symbols:
578
579     symbol = identifier ;
580     symset = "(" { symbol } ")" ;
581
582   The special symbol "nil" is to be interpreted as null string.
583
584   Rationale:
585
586   - The symbol set syntax is the simplest that could work.  We need to
587     allow space between the symbols for legibility anyway, so why not
588     make it the delimiter.  A stop token is required to find the end
589     of the field, and a start token is useful for distinguishing
590     between symbol and symset.  Bracketing with some kind of
591     parenthesis is an obvious solution.
592
593 The resulting sub-language for records is a superset of
594 machine-readable sub-language for records.
595
596 See src/lib/global/*.config for examples.
597
598
599 Notes on Table Configuration Implementation
600
601 econfig key custom_tables lists table configuration files.  At this
602 time, reading a custom table merges it with the built-in table, then
603 truncates the result after the last record read from the custom table.
604
605 Some of the tables are rather ugly in C, and cumbersome to edit.  We
606 thus moved them to configuration files (src/lib/global/*.config).  The
607 server reads them from builtindir before reading custom tables.
608
609 The code dealing with these files is in src/lib/common/conftab.c.
610
611 Actual work is done by src/lib/common/xundump.c, which accepts both
612 human-readable and machine-readable input.  The parser is not precise;
613 it accepts human-readable syntax even within tables whose header marks
614 them machine-readable.
615
616 Symbolic index values in column headers are not implemented.  They
617 occur in item selector pkg, which is an array indexed by values in
618 symbol table packing.
619
620 Configuration tables contain values that are not meant to be
621 customized.  For instance, meta-data and symbol tables reflect the
622 encoding of C language constructs in the server.  Such selectors are
623 marked (struct castr member ca_dump), so that the code can prohibit
624 changes.
625
626 All tables are checked against meta-data on server startup by
627 ef_verify().  More elaborate checking would be nice, and probably
628 requires additional meta-data.
629
630
631 Appendix: Empire 3 C_SYNC --- A Cautionary Tale
632
633 Clients are just as important as the server, and it's too darn hard to
634 write a good client.  In 1995, Ken Stevens decided to do something
635 about it.
636
637 Ken cast the problem as a data synchronization problem.  Quote C_SYNC
638 RFC 5.1, section `Abstract':
639
640   This is a specification for a new method of synchronizing game data
641   in the Empire client with data in the server.
642
643 and section `Objectives':
644
645   This new mode of communication between the server and the client will
646   be called C_SYNC communication and will satisfy the following 6
647   criterea:
648
649   (1) Output format will be version independent.  So if someone is
650   using an old EmpireToolkit, then it will still work with a newer
651   version of the server.
652
653   (2) Every C_SYNC message will be a self-contained packet.  i.e. the
654   client will not need to depend on previous messages (header messages)
655   to determine the meaning of a C_SYNC message.
656
657   (3) A C_SYNC message will be able to represent any of the
658   player-accessible data that is contained in the server database (e.g.
659   enemy ships, nations).
660
661   (4) Bandwidth will be minimized (i.e. the format will be as
662   concise as possible) while remaining human-readable (i.e. no
663   binary messages).  [Note that data compression may be added at a later
664   date, but if it is added, it will be added on a separate port to
665   maintain backwards compatability.]
666
667   (5) The client will be able to tell the server whether it wants
668   to receive C_SYNC messages and whether these messages can be sent
669   asynchroniously (via "toggle sync" and "toggle async" respectively).
670
671   (6) A portable ANSI C EmpireToolkit will be made available for
672   parsing C_SYNC messages and managing the data they contain.
673
674 C_SYNC worked by hooking into ef_write() & friends so it could
675 `synchronize' the client on game state changes.
676
677 Sounds jolly good, doesn't it?
678
679 Well, it was a failure, and Wolfpack ripped it out right away.  Quote
680 the change log:
681
682   Changes to Empire 4.0.0 - Initial release
683    * Initial Wolfpack release - Long live the Wolfpack!!!!
684 [...]
685    * Removed C_SYNC.  This is done for 2 reasons.  1) None of us like it or
686       wish to support it.  2) We envision a better scheme for doing similar
687       things will come along.
688
689 But *why* did it fail?  Just because Steve McClure hated it?  Nope.
690 C_SYNC failed for several different reasons, each of them bad, but
691 only the last one is truly fundamental.
692
693 a. Lack of a rigorous and complete definition.  The RFC is long on
694    syntax, but short on semantics.  For instance, the unit type was
695    encoded as a number.  Unit characteristics happened to be dumped in
696    an order that matched these numbers, but that wasn't defined
697    anywhere.
698
699 b. Overly complicated syntax.  Trouble with encoding of strings.
700
701 c. Buggy implementation.  Malformed C_SYNC messages, duplicate
702    messages, missing messages, semantically incorrect messages, you
703    name it.
704
705 d. Change of crew before it was finished.  Wolfpack took over and
706    understandable wasn't interested in this half-finished mess.
707
708 None of the above is a fundamental, inherent flaw of the idea.  The
709 next one is more serious:
710
711 e. It failed to achieve objective (4), and therefore slowed down
712    clients too much to be of use in real-time combat.  When you fired
713    from a bunch of ships, C_SYNC would push complete records for all
714    the ships and the target to you.  Most of that data is redundant.
715
716    That's because C_SYNC didn't transmit state changes, it
717    resynchronized state, and the pieces of state it could transmit
718    were too large.
719
720    The network was slower then.  But let's not be complacent.  I/O is
721    slow.  Always was, most likely ever will be.
722
723    Maybe sending the messages out of band (separate TCP stream) would
724    help.  Maybe not.
725
726 And here comes the killer:
727
728 f. The data to sync is not readily available on the server.
729
730    Yup.  Think about it.  The game state on the server is *not* the
731    same as on the client.  The server grants the client a carefully
732    limited view on certain parts of server game state on certain
733    events.
734
735    To be complete, a machine-readable protocol must disclose as much
736    information as the human-readable output.  Tracking server game
737    state changes cannot do that alone.  For instance, lookout tells
738    you ship#, owner and location.  That event does not trigger any
739    state change on the server!
740
741    To be correct, a machine-readable protocol must disclose no more
742    information than the human-readable output.  When you observe a
743    server game state change, you can only guess what event triggered
744    it, and what it disclosed to which player.  You're stuck with
745    conservative assumptions.  That's the death knell for completeness.
746    Correct assumptions will be non-obvious, so correctness is
747    non-obvious, too, hence hard to achieve and maintain.
748
749    Bottom line: tracking server state change cannot support a complete
750    client protocol for hard theoretical reasons, and I believe it
751    cannot support a correct one for practical reasons.
752
753 Oddly enough, people criticized C_SYNC for all the flaws it had (and
754 some it hadn't), except for f.
755
756 What now?  Throw up our hands in despair and give up?  Nah.  Ken tried
757 a shortcut, and it didn't work.  That doesn't mean there's no way at
758 all.  I believe the only way to get this done right is by tracking
759 *events*.  Whenever something is printed to a player, be it live
760 connection or telegram, we need to transmit precisely the same
761 information in machine-readable form.  Much more work.
762
763 xdump shares valuable ideas with C_SYNC, e.g. using selector
764 meta-data.  It is, however, much more modest in scope.  We're pretty
765 sure we can get it right and get it done in a reasonable time frame.