Sunday, 18 January 2015

Client<-->Server communication using your own custom messages (SimpleNetworkWrapper)

Although vanilla uses NetHandlerPlayClient and NetHandlerPlayServer for sending packets, you should not use these when modding.  The SimpleNetworkWrapper is provided for this purpose.

To skip straight to sample code, click here (example 60).

In many cases, you won’t need to create custom packets to keep your client and server code synchronised.  The vanilla code and Forge code do this in a number of ways already:
  • Creation, Removal, Movement, health, actions etc for Entities.  This is accomplished for new Entities by Forge packet EntitySpawnPacket.  You can define a custom handler for this using EntityRegistration.setCustomSpawning().
  • Removal or placement of Blocks
  • Adding DataWatcher variables to your Entity (see here)
  • Containers (Inventory, furnace, etc)
If none of these meet your needs and you need to send custom messages, there are three key components to know about:
  1. IMessage, which represents the message you want to send (for example - a client message to the server might indicate "launch a projectile at location [x,y,z]).  The IMessage provides methods to
    * convert the member variables to a serialised format (ByteBuffer) for transmission, and
    * convert the ByteBuffer back to member variables on the receiving side
  2. IMessageHandler, which is called on the receiving side when your IMessage arrives for processing
  3. SimpleNetworkWrapper, which you use to define a channel for your communications as well as to register your IMessage and IMessageHandler.
The IMessage and IMessageHandler are closely coupled.  When registering them with SimpleNetworkWrapper, you need to provide a unique byte ID to identify the message type and its corresponding handler.

The generation, transmission, and receipt of a message (from Client to Server) is illustrated in the diagram below.  Sending a message from Server to Client follows the same pattern.

WARNING! The networking code is multithreaded and your MessageHandler needs to be very careful what it does to avoid crashing the game or introducing subtle, intermittent problems.  See here.

SimpleNetworkWrapper also provides a number of methods you can use to send messages to the appropriate audience, for example
  • sendToServer() - from client to server
  • sendTo(player) - from server to single client
  • sendToAllAround() - send to all nearby clients
  • sendToDimension() - send to all clients in given dimension
  • etc

Further Links

~Client<-->Server communication
    Vanilla Client<-->Server Communication
    Client<-->Server communication using your own custom messages (SimpleNetworkWrapper)
    Thread safety with Network Messages

No comments:

Post a Comment