Hand-over protocol (without internal state transfer aka. animation support):

* The sending client initiates a hand-over by means of sending an "offer <id> <receiver>" command addressing the receiver and the sender's global vessel id. The receiver can be omitted, making a global offer to everybody.
* The sending client can list its offers by means of an empty "offer" command. "offer off <id>" will remove a running offer.
* The server adds the global object to the receiver's accept list. This enforces neighbour SI from the sender to the receiver.
* The server sends a "GINFO <id> O" to the receiver, signaling a new offer it could accept.
* The receiver client can list its acceptable offers by means of an empty "accept" command.
* The receiver client can accept a specific offer using the "accept <id> <local_id>" command, addressing the global id and the local id the receiver will use to send the info.
* The server checks if the offer is valid and if so, moves the global object from the sender to the receiver list. The sender list gets a temporary lock, so superfluous SIs can't re-add the object by mistake.
* The server removes the offer from the sender list and sends a "GINFO <id> A" to the sender, signaling an offer was accepted.
* The moment the receiver gets a success reply from the server, it removes the remote vessel, and adds the global id to its local id list, making received SI for the same id invalid.
* The moment the sender gets the accept signal, it removes the vessel from its local list, giving way to automatic SI remote vessel creation.
* The accept side of the system should be implemented in an integrated manner, as it needs received neighbour SIs to function properly. A quick possibility is to offer a local accept command that proxies the server command in order to filter the list and accept only received objects.
* The offering side of the system should be implemented in an integrated manner for symmetry reasons. Similar to the accept side, a local offer command can proxy the server command in order to augment the list (e.g. with vessel names) and display possible ids.

Notes:

* It must be robust to send foreign SI global ids that match local objects, so time overlap works here.
* Re-spawn during hand-over causes visual disappearance for remote machines.

Container idea:

* There is only one container client for multiple containers that could receive vessels.
* Once a client is offline, its vessels get offered to the container client, thus sent to all registered containers. This is not true for container clients themselves.
* Neighbour SI is generated by the server.
* The server immediately offers the vessels to the original user, so users with lost connection and quick restart immediately get their vessels back.
* A reconnecting client starts only with one dummy vessel, checks the accept list right after start, waits for all offers to be received, then accepts all of them coming from the container clients. Pending offers will be cleared and the appropriate vessels recollected immediately.
* Container only use OMPDefault vessels to save resources. The class and name is never used.
* Container vessels are always inactive, i.e. no thruster firing, no engine running. Once internal state transfer is done, this might be revisited.
* The landed state will receive a special treatment in order to get the gear down, perhaps by means of appropriate recorder commands.

Notes on messaging system:

* Send user messages as GINFO triggers instead of text

Notes on connection issues:

* Some NAT systems seem to display symmetric behavior not only on the receiving side, but on the sending side, too. This could be leveraged by means of using different sending ports to deliver packets to neighbors.
* In order to make the UDP P2P system more robust regarding symmetric NATs, the following session initiation protocol could be implemented:
  1. Use standard method to connect to server. Each client now has a working UDP and TCP system to communicate with the server.
  2. To connect 2 clients together (GI packets), first use the UDP port of the server connection as usual. However, send GI packets always to both clients, optionally sending a object-free one to a non-observing one.
  3. Since both clients get GI packets, they know to expect packets from the other client, too. If no packet is received within a certain time, signal this to the server, which will signal it to the other client.
  4. If a packet is received, use the packet's sender port to send packets too, regardless of what the server told you before. Signal the reception to the server, which will signal it to the other client. Unidirectional connection is considered established. Update neighbour information accordingly.
  5. If the server signals that no packet was received, use a different sender port instead of the fixed one, but stick to receipient information from the server. Signal that you've switched.
  6. If the server signals that the other client has switched, listen again.
  7. If no packet is received, signal again. Open an additional receiver socket with a different socket and send through it to the neighbour address. Send the socket's port with the signal.
  8. If the server again sends no packet receive signal, use the signaled port as receiver port. Signal that you are sending.
  9. If no packet is received, start scanning ports by means of opening and listening to them in circle steps around the starting port, while always sending packets through the to the other client.
  10. One client always starts with this procedure, while the other is waiting for contact. This is directed by the server.
  11. Established connection are cached at the server and reused the next time. Client disconnect will clear that cache.
  12. GI info and signaling should be refactored to TCP exchange.
 
 Notes on docking:
 * Still causing problems with jittering.
 * Still rotationally unstable.
 * Perhaps disabling docking completely and simulating it with attachments is a more rewarding approach.