Popular Posts

Monday, January 2, 2012

NullpoMino Protocol 1.0 Specification

Here's a rough draft of the network protocol specification. I'm calling it RFC 1 (RFC stands for Request for Comments).

NullpoMino Protocol 1.0 Specification

This is the promised table of opcodes that I've come up with so far. I left some room in the game opcodes area for expansion, and I feel like it would probably be best if we could finalize the design of network games and their communication before this is set in stone.

NMP opcode table

When this proposal is acceptable, I'll begin work on a reference implementation server which uses the protocol.

2 comments:

  1. There may not be a need for a three-stage connection handshake. It seems perfectly sufficient to me to skip the server sending WELCOME and have the client send its version and any connect-options it wants which the server will then confirm or refuse.

    In general, I like bit packing for efficiency reasons, but binary protocols can be troublesome and hard to extend if done wrong. A generic encapsulation format for messages and message fields - that is, something that can be parsed whether or not you actually support the commands in question - seems most desirable. You might look at BitTorrent for an example of a similar thing. The intent is, rather than be like, "here function, have this chunk of binary data", you have already processed and validated the code and you pass it to the relevant function with proper parameterization, etc.

    A standard field for a timestamp (which could optionally go unused for some messages, but I don't see why it would need to) would be good, I think, since synchronization and latency are concerns. If every participant timestamps every message, we get useful information without requesting it explicitly.

    In fact, I'd like to see standard fields ala IRC for: timestamp, source, command, destination, [optional parameters], since these fields will be relevant in most cases. This will help with compatibility and organization.

    Some opcodes should have more information. For example, I assume KICKED is supposed to mean "YOU got kicked", but what gets sent when someone else gets kicked?

    Organizationally speaking, it can be useful to group kinds of responses like many protocols do, for example 400-series in HTTP for errors. With a hard limit of 256 commands, this is a bit trickier to organize, but you may see some utility in bit masking if you set bits for certain explicit meanings, for example: high bit = success or error, next bit or two might describe the target scope (channel, global, private), etc.

    I recently learned something useful about password hashes: USE BCRYPT :)

    In general, opcodes can be as verbose as necessary, since the way you're going about it will have them as constants in the source code rather than text transmitted on the wire. With that in mind:

    k-line and g-line actually have specific meanings that don't apply here; I'm fond of IRC, but even IRC users tend not to know the exact specifics of these commands ;)

    ACC can be misread as access instead of account

    GMACCGRB is one of the more convoluted entries

    There is a GETOPTS but no SETOPTS, assuming getopts is a list of voluntary options

    There are no provisions for managing who has access to do what to a room

    ECHO and PING are generally redundant

    GMTARGET inherently may not support multiple targets [forward-looking comment]

    One-byte opcodes 'for the first version' will make cross-version compatibility if there are ever more opcodes difficult

    In general, I think the list covers most things (and what it doesn't, will get covered when you run into it and are like, "oh, I need that"). As I was learning with databases, naming conventions can be extremely useful.

    I think you could benefit from taking advantage of naming conventions here, too. For example:

    ERROR_NO_ACCESS
    ERROR_ROOM_FULL
    ERROR_BAD_COMMAND

    REPLY_OK
    REPLY_USER_LIST

    EVENT_JOIN
    EVENT_PART
    EVENT_LOSE
    EVENT_MESSAGE

    ... and so on. This makes it both easier to understand what's going on and easier to find/use, as well as making some fundamentals clear for later additions.

    I took a preliminary couple passes down the list to see if I noticed anything left out, but it's 2am and I'm not confident I've given it due consideration yet, so stay tuned for more :)

    ReplyDelete
  2. One more point in favor of ts/source/cmd/target: the server can appropriately relay messages to their needed targets even if it doesn't know what they mean. This enables the server to be "out of the middle" for more items, which I think would be useful. A distinction may need to be made between commands that get passed directly to users (or rooms, etc.) as-is or ones that are intended for the server to parse. The mentioned bit masking technique might make this convenient.

    ReplyDelete