Networking¶
Question
You still sure you want to use networking in your game???
Networking in Isetta is completely messaging based, there are no Cmd
or Rpc
or SyncVar
s like in Unity. Our example networking level and NetworkTestComponent
is the best place for you to get started.
A few things to definitely note:
- When implementing a network message class, you need to define both the
Serialize
and theCopy
functions.Serialize
MUST returntrue
at the end of the function--otherwise your client will disconnect every time you try to send the message and you won't know why! - Each of the serialization functions we use come from yojimbo, and they're the following:
serialize_int
: Serializes an integervalue
and compresses that within the range ofmin
andmax
serialize_bits
: Serializes the number ofbits
of a 32-bitvalue
serialize_bool
: Serializes a booleanvalue
using bitsserialize_float
: Serializes a floatvalue
serialize_uint32
: Serializes a 32-bit unsigned integervalue
serialize_uint64
: Serializes a 64-bit unsigned integervalue
by serializing the low and high 32 bitsserialize_double
: Serializes a doublevalue
by casting it to a 64-bit unsigned integer and serializing thatserialize_bytes
: Serializes an array ofbytes
from a given pointer todata
serialize_string
: Serializes astring
of a givenbuffer_size
serialize_object
: Serializes anobject
using aSerialize
member function of the object that takes in thestream
parameter
If you do use networking a lot, the team members in the room are probably the best documentation.
Essential API¶
yojimbo::Message
: The base class of the message objectsNetworkManager::StartHost("hostIP")
NetworkManager::StopHost()
NetworkManager::StartServer("serverIP")
NetworkManager::StopServer()
NetworkManager::StartClient("clientIP")
NetworkManager::StopClient()
NetworkManager::SendMessageFromClient<MyMessage>(Action<MyMessage*> messageInitializer)
where T inheritsyojimbo::Message
NetworkManager::RegisterClientCallback<MyMessage>(Action<yojimbo::Message*>)
NetworkManager::SendMessageFromServer<MyMessage>(int clientIndex, Action<MyMessage*> messageInitializer)
NetworkManager::RegisterServerCallback<MyMessage>(Action<int clientIndex, yojimbo::Message*>)
NetworkManager::.SendMessageFromServerToAll<MyMessage>(MyMessage*)
Code Snippets¶
Defining a HandleMessage
:
// HandleMessage simply sends an integer handle between 0 and 64 across the
// network
DEFINE_NETWORK_MESSAGE(HandleMessage)
// IMPORTANT: The Serialize function _must_ be a template around the Stream
// type, and it MUST return true at the end of the function. Otherwise the
// serialization will be assumed to have failed!
template <typename Stream>
bool Serialize(Stream* stream) {
// serialize_int is supplied by yojimbo, along with many other primitive
// type serialization functions
serialize_int(stream, handle, 0, 64);
return true;
}
// The Copy function must be overridden with boilerplate that copies the values
// from a given message. This is used for the general SendToAll functions that
// the NetworkManager has.
void Copy(const yojimbo::Message* otherMessage) override {
const HandleMessage* message =
reinterpret_cast<const HandleMessage*>(otherMessage);
handle = message->handle;
}
public:
int handle = 0; // Obviously we'll just use a handle
DEFINE_NETWORK_MESSAGE_END
Registering a callback for HandleMessage
on the client:
exampleClientHandleId =
NetworkManager::Instance().RegisterClientCallback<HandleMessage>(
[](yojimbo::Message* message) {
// We'll always have to cast our message into the message we're
// anticipating
HandleMessage* handleMessage = static_cast<HandleMessage*>(message);
LOG(Debug::Channel::Networking, "Server sends handle #%d",
handleMessage->handle);
// Depending on the handle, we can do something (we tore out a
// couple system here though)
if (handleMessage->handle == 0) {
LOG(Debug::Channel::Networking,
"Server says we should play the animation!");
}
if (handleMessage->handle == 1) {
LOG(Debug::Channel::Networking,
"Server says we should stop the animation!");
}
});