Handshake gives a good comparison that illustrates my earlier objections:

* Handshake builds a tree of MiniYaml, and then serializes it to a string that is the payload of an order.  This pr serialize the three objects into strings, and then assembles a second level of the yaml tree manually using a stringbuilder (fix: build a MiniYaml tree in Session.cs, following the examples of Tileset.Save or Map.Save)

* HandshakeRequest and HandshakeResponse implement both Serialize and Deserialize, which is balanced and separates concerns.  You have Client, ClientPing, and Global each implement only Serialize, and then deserialize them all inside a switch statement on Session (fix: Implement Deserialize methods in each of these three classes).