--- /dev/null
+Introduction
+
+Empire is designed as a smart server with dumb clients. An Empire
+client need to know nothing about the game. Even telnet would do. In
+fact, emp_client is just as a slightly specialized telnet.
+
+In such a design, presentation is in the server, and it is designed
+for human consumption. Ideally, presentation and logic are cleanly
+separated, for easy selection between different presentations.
+There's no such separation in the Empire server, and separating them
+now would be a herculean effort.
+
+Thus, smart clients have to work with output designed for humans.
+That's not especially hard, just an awful lot of tedious work, and the
+result gets easily broken by minor changes in output format, which
+humans hardly notice.
+
+Instead of making smart clients parse output of commands designed for
+humans, one can add commands designed for machines. Such commands can
+share the code implementing game rules with their counterparts for
+humans. To do that cleanly means separating logic and presentation.
+Implementing them with their own copy of the code is no good --- how
+would you ensure that the two copies implement precisely the same game
+rules?
+
+Except for commands that actually don't do anything. There's a useful
+class of such commands: commands to show game configuration and state
+without altering it. The only game rules involved are those that
+govern who gets to see what. Ensuring that those are satisfied is
+tractable.
+
+Empire has had one such command since the beginning: dump. Empire
+4.0.6 added more: sdump, ldump, pdump and ndump. 4.0.7 added lost and
+support for incremental dumps. These commands have served smart
+clients well. However, they cover just the most important part of the
+game state (sectors, ships, planes, land units, nukes), and no game
+configuration. They are not quite complete even for what they attempt
+to cover. Finally, their output is harder to parse than necessary.
+
+The xdump command is designed to be the dump to end all dumps.
+
+Like many good ideas, xdump has secondary uses. Dumping game state as
+text can be one half of a game export/import facility. Useful to
+migrate games to different machines or even, with some text mangling
+perhaps, different server versions. We will see below that xdump
+isn't quite sufficient for that, but it's a start.
+
+If you can import game state, you can import game configuration, or in
+other words: customize your game. As we will see, configuration files
+have different requirements, which xdump doesn't satisfy without some
+extensions.
+
+If game import code can edit everything, then a deity command capable
+of editing everything is possible. Proof-of-concept code exists (not
+in the tree yet).
+
+
+Analysis of the data to dump
+
+Game state consists of a fixed set of table files (sector, ship, ...),
+telegram files, and a few miscellaneous files. Game configuration
+consists of a fixed set of configuration tables and scalar parameters.
+
+A table is an ordered set of records (table rows). All records have
+the same fields (table columns), which are statically typed.
+
+Fields may be integers, floating-point numbers, x- or y-coordinates,
+symbols and symbol sets encoded as integers in a way specific to the
+server version, and character arrays. Configuration table fields may
+be pointers to zero-terminated strings, null pointers allowed. No
+other pointers occur. Unions do not occur.
+
+
+Requirements analysis
+
+Requirements:
+
+* Capable to dump all tables.
+
+* Can do incremental dumps.
+
+* Output is text.
+
+* Output is reasonably compact.
+
+* Output is trivial to parse. Triviality test: if it's easy in AWK, C
+ (no lex & yacc, just stdio), Lisp (just reader) and Perl (base
+ language, no modules), then it's trivial enough.
+
+* Output identifies itself.
+
+* Output is self-contained; symbol encoding is explicit.
+
+* KISS: keep it simple, keep it stupid.
+
+Non-requirements:
+
+* Generality. We're not trying to design a general mechanism for
+ dumping C data.
+
+* Completeness. We're not trying to dump stuff other than tables.
+
+* Abstraction. We're not trying to hide how things are stored in the
+ server. When storage changes, xdump output will change as well, and
+ consumers need to be updated. This is not because abstraction
+ wouldn't be nice to have, just because we don't feel up to the task
+ of designing one.
+
+
+Principles of Design
+
+Traditional dumps have a dump function for every table. These
+functions are simple, but exceedingly dull and repetitive.
+
+The selector code works differently. Each table has a descriptor,
+which among other things defines a dictionary of selector descriptors.
+A selector descriptor describes a field (table column) visible to
+players. This is what we call meta-data (data about data). The
+selector code knows nothing about the individual tables, it just
+interprets meta-data. That's smart, as it keeps the dull, repetitive
+parts in more easily maintainable meta-data rather than code.
+
+xdump follows the selector design, and uses the existing selector
+meta-data. This requires extending the meta-data to configuration
+tables, which weren't previously covered. It also requires some
+generalization of selector descriptors, so that all fields can be
+covered.
+
+To sum up, meta-data consists of a table of tables, and for each table
+a table of selectors (table of columns, so to speak). It is specific
+to the server version and how it is compiled on the host.
+
+To interpret a table xdump, you need its meta-data, because without it
+you have no idea what the columns mean. As meta-data is just a bunch
+of tables, xdump can dump it. But now you need meta-meta-data to make
+sense of the meta-data. Fortunately, meta-meta-data is the same for
+all xdumps, and therefore the recursion terminates with a single
+meta-meta-table.
+
+xdump dumps symbols and symbol sets as integers. To decode them, you
+need to know what the symbol numbers and symbol set bits mean. For
+this purpose, field meta-data includes the table ID of a symbol table.
+A symbol table is a table of value-name pairs, with the value in the
+leftmost column. You decode a symbol value by looking it up in the
+symbol table. You decode a symbol set value by looking up its bits
+(powers of two) in the symbol table.
+
+Some integer fields are actually keys in other tables. For instance,
+ship field type is a key in the table of ship types ship-chr, and
+plane field ship is a key in the ship table. Key value -1 is special:
+it's a null key. Meta-data encodes these table reference just like
+for symbols: the meta-data has the ID of the referenced table, and
+that table has the key in the leftmost column. Obviously, that
+leftmost column is a table key as well, referencing the table itself.
+
+A table with its key in the leftmost column can be dumped partially.
+Without such a key, you need to count records to find the record
+index, and that works only if you can see a prefix of the complete
+table.
+
+The special table "ver" collects all scalar configuration parameters
+in a single record. It does not occur in the table of tables.
+
+
+Syntax of xdump command
+
+See info xdump.
+
+
+The xdump output Language
+
+Because the output is to be parsed by machines, it needs to be
+precisely specified. We use EBNF (ISO 14977) for syntax, except we
+use '-' in meta-identifiers and omit the concatenation symbol ','.
+
+ table = header { record } footer ;
+ header = "XDUMP" space [ "meta" space ] name space timestamp newline ;
+ name = name-chr { name-chr } ;
+ name-chr = ? ASCII characters 33..126 ? ;
+ timestamp = intnum ;
+ footer = "/" number newline ;
+ record = [ fields ] newline ;
+ fields = field { space field } ;
+ field = intnum | flonum | string ;
+ intnum = ? integer in printf %d format ? ;
+ flonum = ? floating-point in printf %g format ? ;
+ string = "nil"
+ | '"' { str-char } '"' ;
+ str-char = "\\" octal-digit octal-digit octal-digit
+ | ? ASCII characters 33..126 except '"' and '\\' ? ;
+ octal-digit = ? '0'..'7' ? ;
+ space = ' ' ;
+ newline = ? ASCII character 10 ? ;
+
+Notes:
+
+* The syntax for flonum is debatable. Precise conversion between
+ floating-point and decimal is hard, and C libraries are not required
+ to be precise. Using C99's %a format for flonum would avoid the
+ issue, but some programming environments may have trouble converting
+ that back to floating-point. We may change to %a anyway in the
+ future. Clients are advised to accept both.
+
+* Strings syntax could perhaps profit from the remaining C escape
+ sequences. Except for '\"': adding that would complicate regular
+ expressions matching the string, and thus violate the `trivial to
+ parse' requirement
+
+* Space is to be taken literally: a single space character. Not a
+ non-empty sequence of whitespace.
+
+Semantics:
+
+* The table name in the header is one of the names in xdump table.
+
+* The timestamp increases monotonically. It has a noticeable
+ granularity: game state may change between an xdump and the next
+ timestamp increase. If the table has a timestamp field, clients can
+ xdump incrementally by using a conditional ?timestamp>T, where T is
+ one less than the timestamp received with the last xdump of that
+ table.
+
+ Timestamp values are currently seconds since the epoch, but this
+ might change, and clients are advised not to rely on it.
+
+* The number in the footer matches the number of records.
+
+* Fields match their meta-data (see Meta-Data below).
+
+* "nil" represents a null string (which is not the same as an empty
+ string). Otherwise, fields are to be interpreted just like C
+ literals.
+
+
+Meta-Data
+
+Table meta-data is in xdump table. Fields:
+
+* uid: The table ID, key for xdump table. IDs depend on the server
+ version; clients should not hard-code them. This is the leftmost
+ field.
+
+* name: The table name. Clients may identify tables by name.
+
+Field meta-data for table T is in xdump meta T. The order of fields
+in the xdump T matches the order of records in xdump meta T. Fields
+of xdump meta T are:
+
+* name: The field name. Matches the selector name. Clients may
+ identify fields by name. This is the leftmost field.
+
+* type: The field's data type, a symbol. Clients should use this only
+ as key for the symbol table. Symbols are:
+ - "d", field uses intnum syntax
+ - "g", field uses flonum syntax
+ - "s", field uses string syntax
+ - "c", field uses string syntax
+
+* flags: The field's flags, a symbol set. Flags are:
+ - "deity", field visible only to deities
+ - "extra", field not to be dumped
+ - "const", field cannot be changed (see xundump below)
+ - "bits", field is a symbol set, field type must encode symbol "d",
+ field table must not be -1.
+
+* len: If non-zero, then the record encodes an array with that many
+ elements. If field type encodes symbol "c", it is a character
+ array, which is dumped as a single string field. Else, the array is
+ dumped as len fields.
+
+* table: Key for xdump table. Unless -1, it defines the table
+ referenced by the field value. Field type must encode symbol "d"
+ then.
+
+Symbol table fields:
+
+* value: The symbol's encoding as integer. If the symbol can be
+ element of a symbol set, this is a power of two.
+
+* name: The symbol's name.
+
+
+Notes on xdump Implementation
+
+Overall impact on the server code is low.
+
+To keeps xdump simple, storage of game state and game configuration
+tables has been unified under the common empfile abstraction, making
+nxtitem-iterators and selectors equally applicable to all tables.
+
+xdump required a few extensions to meta-data, which may become useful
+in other places as well:
+
+* Selectors can now deal with arrays (revived struct castr member
+ ca_len). Not yet available on the Empire command line.
+
+* Selector meta-data can now express that a selector value is a key
+ for another table (new struct castr member ca_table). The selector
+ code doesn't use that, yet.
+
+* Selector flag NSC_EXTRA to flag redundant selectors, so that xdump
+ can ignore them.
+
+Meta-data is in empfile[] (table meta-data), src/lib/global/nsc.c
+(selector meta-data), src/lib/global/symbol.c (symbol tables). The
+command is in src/lib/commands/xdump.c, unsurprisingly.
+
+
+Hints on Using xdump in Clients
+
+Let's explore how to dump a game. To make sense of a table, we need
+its meta-data, and to make sense of that table, we need meta-meta
+data. So we start with that:
+
+ [14:640] Command : xdump meta meta
+ XDUMP meta meta 1139555204
+ "name" 3 4 0 -1
+ "type" 5 4 0 32
+ "flags" 6 12 0 33
+ "len" 8 4 0 -1
+ "table" 9 4 0 -1
+ /5
+
+To interpret this table, we have to know the field names and their
+meanings. Clients hard-code them. They should be prepared to accept
+and ignore additional fields, and to cope with changes in field order,
+except they may rely on "name" coming first.
+
+A word on hard-coding. Clients hard-code *names*. The numbers used
+for table IDs and to encode symbols are none of the client's business.
+
+The encoding doesn't normally change within a game. Except when the
+game is migrated to a sufficiently different server. That's a
+difficult and risky thing to do, especially as there are no tools to
+help with migrating (yet). Clients may wish to provide for such
+changes anyway, by decoupling the client's encoding from the server's,
+and dumping fresh meta-data on login. Incremental meta-data dump
+would be nice to have.
+
+So we don't know how symbol type and symbol set flags are encoded. To
+decode them, we need their symbol tables. However, we need flags and
+type only for tables we don't know, and there's one more table we do
+know, namely the table of tables. Let's dump that next, starting with
+its meta-data:
+
+ [31:640] Command : xdump meta table
+ XDUMP meta table 1139556230
+ "uid" 9 0 0 26
+ "name" 3 4 0 -1
+ /2
+
+Because xdump table is referenced from elsewhere (xdump meta meta
+field table), the leftmost field must contain the key. Thus, the
+leftmost field's meta-data field table must be the table ID of xdump
+table itself. Let's try it:
+
+ [30:640] Command : xdump 26 *
+ XDUMP table 1139556210
+ 0 "sect"
+ 1 "ship"
+[...]
+ 9 "nat"
+[...]
+ 16 "sect-chr"
+ 17 "ship-chr"
+[...]
+ 26 "table"
+[...]
+ /45
+
+It worked! Mind that the special table "ver" is not in the table of
+tables.
+
+Now dump the two symbol tables we postponed. Because xdump accepts
+table IDs as well as names, we don't have to know their names:
+
+ [14:640] Command : xdump meta 32
+ XDUMP meta meta-type 1139555298
+ "value" 9 4 0 -1
+ "name" 3 0 0 -1
+ /2
+
+ [15:640] Command : xdump 32 *
+ XDUMP meta-type 1139555826
+ 1 "d"
+ 2 "g"
+ 3 "s"
+ 4 "d"
+ 5 "d"
+ 6 "d"
+ 7 "d"
+ 8 "d"
+ 9 "d"
+ 10 "d"
+ 11 "d"
+ 12 "d"
+ 13 "g"
+ 14 "c"
+ /14
+
+ [15:640] Command : xdump meta 33
+ XDUMP meta meta-flags 1139555303
+ "value" 9 4 0 -1
+ "name" 3 0 0 -1
+ /2
+
+ [24:640] Command : xdump 33 *
+ XDUMP meta-flags 1139555829
+ 1 "deity"
+ 2 "extra"
+ 4 "const"
+ 8 "bits"
+ /4
+
+We now have complete meta-meta information:
+
+ name type flags len table
+ -----------------------------------------
+ name s (const) 0
+ type d (const) 0 meta-type
+ flags d (bits const) 0 meta-flags
+ len d (const) 0
+ table d (const) 0
+
+Dumping the remaining tables is easy: just walk the table of tables.
+Here's the first one:
+
+ [36:640] Command : xdump meta 0
+ XDUMP meta sect 1139556498
+ "owner" 6 0 0 9
+ "xloc" 10 0 0 -1
+ "yloc" 11 0 0 -1
+ "des" 4 0 0 16
+[...]
+ /69
+
+A whole load of tables referenced! Only one of them (not shown above)
+is a symbol table.
+
+owner references table nat. No surprise.
+
+xloc and yloc together reference the sector table, but that's not
+expressed in meta-data (yet).
+
+Let's stop here before this gets too long and boring. Experiment
+yourself! Check out example Perl code src/xdump.pl.
+
+
+Analysis of xdump as Configuration File Format
+
+xdump makes a lousy configuration format because it is unwieldy to
+edit for humans. That's because configuration files have different
+requirements than dumps:
+
+* Can be edited by humans with common tools, including text editors
+ and spreadsheets.
+
+ Using text editors requires a nice fixed-width table layout.
+ Spreadsheet import requires trivial field separation. Tab character
+ field separator or fixed width columns should do. The syntax should
+ allow all that, but not require it.
+
+ Trouble spots:
+
+ - xdump's rigid horizontal and vertical spacing makes it impossible
+ to align things visually.
+
+ - xdump uses one line per record, which can lead to excessively long
+ lines.
+
+ - xdump's string syntax requires octal escape for space.
+
+ - No comment syntax.
+
+* Each table is self-contained. You don't have to look into other
+ tables to make sense of it.
+
+ This conflicts with xdump's separation of data and meta-data. You
+ need the table's meta-data to identify fields, and the referenced
+ symbol tables to decode symbols.
+
+* Easy to parse. Don't compromise legibility just to please some dumb
+ tool, though.
+
+Since we're trying to apply xdump to the configuration file problem,
+we get an additional requirement:
+
+* Reasonably close to xdump. Translation between machine-readable and
+ human-readable should be straightforward, if meta-data is available.
+
+This leads to a human-readable dialect of the xdump language.
+
+
+Human-Readable xdump Language
+
+Fundamental difference to basic, machine-readable xdump: the rigid
+single space between fields is replaced by the rule known from
+programming languages: whitespace (space and tab) separates tokens and
+is otherwise ignored. The space non-terminal is no longer needed.
+
+Rationale: This allows visual alignment of columns and free mixing of
+space and tab characters.
+
+Comments start with "#" and extend to the end of the line. They are
+equivalent to a newline.
+
+Rationale: Follow econfig syntax.
+
+Tables with a record uid in the leftmost field can be `split
+vertically' into multiple parts. Each part must contain the same set
+of records. The leftmost field must be repeated in each part. Other
+fields may be repeated. Repeated fields must be the same in all
+parts. Naturally, the parts together must provide the same fields as
+a table that is not split.
+
+Rationale: This is the cure for long lines. Line continuation would
+be simpler, but turns out to be illegible. Requiring record uid is
+not technically necessary, as counting records works the same whether
+a table is split or not. Except humans can't count. Perhaps this
+should be a recommendation for use rather than part of the language.
+
+EBNF changes:
+
+* Header and footer:
+
+ header = "config" name newline { colhdr } newline ;
+ colhdr = identifier [ "(" ( intnum | identifier ) ")" ] [ "..." ] ;
+ footer = "/config" newline ;
+
+ If colhdr ends with "...", the table is continued in another part,
+ which shall follow immediately.
+
+ Rationale:
+
+ - The xdump needs to identify itself as human-readable, hence change
+ from "XDUMP" to "config".
+
+ - The timestamp in the header is useless for the applications we
+ have in mind for human-readable xdumps. The number of records in
+ the footer is of marginal value at best, and a pain for humans to
+ update.
+
+ - The column header is due to the self-containedness requirement.
+ It contains just the essential bit of meta-data: the column name.
+
+* Symbolic fields:
+
+ field = intnum | flonum | string | symbol | symset ;
+
+ Rationale:
+
+ - Syntax for symbols and sets of symbols is due to the
+ self-containedness requirement. Machine-readable xdump gets away
+ with just numbers, which have to be decoded using meta-data.
+
+* Friendlier numbers and strings:
+
+ flonum = ? floating-point in scanf %g format ? ;
+ str-char = "\\" octal-digit octal-digit octal-digit
+ | ? ASCII characters 32..126 except '"' and '\\' ? ;
+
+ Rationale:
+
+ - Machine-readable floating-point syntax is too rigid. Accept
+ everything that scanf does. Could also change intnum to %i
+ format, which accepts octal and hexadecimal in C syntax, but that
+ seems not worth the documentation bother.
+
+ - Machine-readable syntax requires \040 instead of space in strings
+ to allow trivial splitting into fields. This is unacceptable here
+ due to the legibility requirement, hence the change to str-char.
+
+* Parse nil as symbol:
+
+ string = '"' { str-char } '"' ;
+
+ Rationale: This is a technicality required to keep the parse
+ unambiguous.
+
+* Symbols:
+
+ symbol = identifier ;
+ symset = "(" { symbol } ")" ;
+
+ The special symbol "nil" is to be interpreted as null string.
+
+ Rationale:
+
+ - The symbol set syntax is the simplest that could work. We need to
+ allow space between the symbols for legibility anyway, so why not
+ make it the delimiter. A stop token is required to find the end
+ of the field, and a start token is useful for distinguishing
+ between symbol and symset. Bracketing with some kind of
+ parenthesis is an obvious solution.
+
+The resulting sub-language for records is a superset of
+machine-readable sub-language for records.
+
+
+See src/lib/global/*.config for examples.
+
+Human-readable xdump still has its shortcomings:
+
+* Symbolic references work only with symbol tables. Consider sect-chr
+ selector prd, which is a key for table product. xdump should
+ support use of product selector sname values as keys. Same for
+ product selectors ctype and type, which should support item selector
+ mnem values as keys.
+
+* item selector pkg is an array indexed by values in symbol table
+ packing. The column header should support symbolic index values
+ rather than numbers.
+
+
+Notes on Table Configuration Implementation
+
+econfig key custom_tables lists table configuration files. At this
+time, reading a custom table merges it with the built-in table, then
+truncates the result after the last record read from the custom table.
+
+Some of the tables are rather ugly in C, and cumbersome to edit. We
+thus moved them to configuration files (src/lib/global/*.config). The
+server reads them from builtindir before reading custom tables.
+
+The code dealing with these files is in src/lib/common/conftab.c.
+
+Actual work is done by src/lib/common/xundump.c, which accepts both
+human-readable and machine-readable input. The parser is not precise;
+it accepts human-readable syntax even within tables whose header marks
+them machine-readable.
+
+Configuration tables contain values that are not meant to be
+customized. For instance, meta-data and symbol tables reflect the
+encoding of C language constructs in the server. Selector flag
+NSC_CONST marks them, so that the code can prohibit changes.
+
+All tables are checked against meta-data on server startup by
+ef_verify(). More elaborate checking would be nice, and probably
+requires additional meta-data.
+
+
+Appendix: Empire 3 C_SYNC --- A Cautionary Tale
+
+Clients are just as important as the server, and it's too darn hard to
+write a good client. In 1995, Ken Stevens decided to do something
+about it.
+
+Ken cast the problem as a data synchronization problem. Quote C_SYNC
+RFC 5.1, section `Abstract':
+
+ This is a specification for a new method of synchronizing game data
+ in the Empire client with data in the server.
+
+and section `Objectives':
+
+ This new mode of communication between the server and the client will
+ be called C_SYNC communication and will satisfy the following 6
+ criterea:
+
+ (1) Output format will be version independent. So if someone is
+ using an old EmpireToolkit, then it will still work with a newer
+ version of the server.
+
+ (2) Every C_SYNC message will be a self-contained packet. i.e. the
+ client will not need to depend on previous messages (header messages)
+ to determine the meaning of a C_SYNC message.
+
+ (3) A C_SYNC message will be able to represent any of the
+ player-accessible data that is contained in the server database (e.g.
+ enemy ships, nations).
+
+ (4) Bandwidth will be minimized (i.e. the format will be as
+ concise as possible) while remaining human readable (i.e. no
+ binary messages). [Note that data compression may be added at a later
+ date, but if it is added, it will be added on a separate port to
+ maintain backwards compatability.]
+
+ (5) The client will be able to tell the server whether it wants
+ to receive C_SYNC messages and whether these messages can be sent
+ asynchroniously (via "toggle sync" and "toggle async" respectively).
+
+ (6) A portable ANSI C EmpireToolkit will be made available for
+ parsing C_SYNC messages and managing the data they contain.
+
+C_SYNC worked by hooking into ef_write() & friends so it could
+`synchronize' the client on game state changes.
+
+Sounds jolly good, doesn't it?
+
+Well, it was a failure, and Wolfpack ripped it out right away. Quote
+the change log:
+
+ Changes to Empire 4.0.0 - Initial release
+ * Initial Wolfpack release - Long live the Wolfpack!!!!
+[...]
+ * Removed C_SYNC. This is done for 2 reasons. 1) None of us like it or
+ wish to support it. 2) We envision a better scheme for doing similar
+ things will come along.
+
+But *why* did it fail? Just because Steve McClure hated it? Nope.
+C_SYNC failed for several different reasons, each of them bad, but
+only the last one is truly fundamental.
+
+a. Lack of a rigorous and complete definition. The RFC is long on
+ syntax, but short on semantics. For instance, the unit type was
+ encoded as a number. Unit characteristics happened to be dumped in
+ an order that matched these numbers, but that wasn't defined
+ anywhere.
+
+b. Overly complicated syntax. Trouble with encoding of strings.
+
+c. Buggy implementation. Malformed C_SYNC messages, duplicate
+ messages, missing messages, semantically incorrect messages, you
+ name it.
+
+d. Change of crew before it was finished. Wolfpack took over and
+ understandable wasn't interested in this half-finished mess.
+
+None of the above is a fundamental, inherent flaw of the idea. The
+next one is more serious:
+
+e. It failed to achieve objective (4), and therefore slowed down
+ clients too much to be of use in real-time combat. When you fired
+ from a bunch of ships, C_SYNC would push complete records for all
+ the ships and the target to you. Most of that data is redundant.
+
+ That's because C_SYNC didn't transmit state changes, it
+ resynchronized state, and the pieces of state it could transmit
+ were too large.
+
+ The network was slower then. But let's not be complacent. I/O is
+ slow. Always was, most likely ever will be.
+
+ Maybe sending the messages out of band (separate TCP stream) would
+ help. Maybe not.
+
+And here comes the killer:
+
+f. The data to sync is not readily available the server.
+
+ Yup. Think about it. The game state on the server is *not* the
+ same as on the client. The server grants the client a carefully
+ limited view on certain parts of server game state on certain
+ events.
+
+ To be complete, a machine readable protocol must disclose as much
+ information as the human readable output. Tracking server game
+ state changes cannot do that alone. For instance, lookout tells
+ you ship#, owner and location. That event does not trigger any
+ state change on the server!
+
+ To be correct, a machine readable protocol must disclose no more
+ information than the human readable output. When you observe a
+ server game state change, you can only guess what event triggered
+ it, and what it disclosed to which player. You're stuck with
+ conservative assumptions. That's the death knell for completeness.
+ Correct assumptions will be non-obvious, so correctness is
+ non-obvious, too, hence hard to achieve and maintain.
+
+ Bottom line: tracking server state change cannot support a complete
+ client protocol for hard theoretical reasons, and I believe it
+ cannot support a correct one for practical reasons.
+
+Oddly enough, people criticized C_SYNC for all the flaws it had (and
+some it hadn't), except for f.
+
+What now? Throw up our hands in despair and give up? Nah. Ken tried
+a shortcut, and it didn't work. That doesn't mean there's no way at
+all. I believe the only way to get this done right is by tracking
+*events*. Whenever something is printed to a player, be it live
+connection or telegram, we need to transmit precisely the same
+information in machine readable form. Much more work.
+
+xdump shares valuable ideas with C_SYNC, e.g. using selector
+meta-data. It is, however, much more modest in scope. We're pretty
+sure we can get it right and get it done in a reasonable time frame.