Server/Client Protocol (RPC?)

Started by
1 comment, last by Antheus 15 years, 5 months ago
I have experience in networking (sockets), databases (sql), graphics (opengl/xna), interpreted languages (python/lua), input (keyboard/mouse), gui (wxwidgets/winforms/codejock), libraries, game loops, etc. I'm looking to tie it all together and write a multiplayer engine/game. I'm unsure how to go about communicating between the client and the server. I believe I have a good idea how the client/server structure is organized (send command, wait for results). I know that games like Diablo II are using custom struct protocols where the first byte is the packet id, next two bytes are length, etc. I've seen games like Age of Conan use XML-RPC for their client updater. Assume TCP (not custom UDP). So what do you guys think? Should I just start creating and documenting my own packet protocol and commands? Should I be using RPC as the base for all communication? XML-RPC (heavy)? I want to know what progress there has been on knowing what works best. Thanks in advanced, I'm vague on this (I came across one link about RPC & MMORPGs).
010001000110000101100101
Advertisement
In sacred 1 + 2 we use a custom format, the bare minimum packet has a header with an id, a few flags an some routing information (where did the packet come from last, where did it originate from & where is it supposed to go).

The "where should it go" can be represented by an ID, or by a 'virtual id',
something like "all clients in range" or "other clients in range (all except the client where it originated from) or "all clients" (for global updates)

Then we do something like Kernel::pushEvent (myEvent), which collects all events of one frame in a list. At the end of the frame, we handle all the events.

We hide the routing by having a few function like "toServer, onServer and fromServer". To-server is called when a client is about to send it to the server, onServer is only called by the server, and fromServer is called when an event is received from the server.

So now you can do something a damage-event: "client post-event(eg do 10 damage), in toServer, we display the value (for a responsive game) and do the transmit, we receive it on the server so onerver is called, server will validate damage with own calculation and if all ok, transmit it to all clients in range", client received it, applied it & displays value (if not originating client because that on already displayed it in toServer)

If the server decided it was not ok (eg because the client was trying to cheat)
it can decide not to relay, or kick the player, or whatever...

As a sidenote, if a player cheats client-side, then - because we display the value already in "toServer", it looks like he succeeded. Even though the server is running the calculation again and the "apply" in fromserver is correct.
If the damage resulted in a kill, it is flagged by the server, so no matter what the client thinks the health is, the creature dies if the flag is set.

That's a really brief overview of how things are handled in our engine.
visit my website at www.kalmiya.com
Quote:Original post by Dae

I've seen games like Age of Conan use XML-RPC for their client updater.


Unless I'm mistaken, someone mentioned they use Ace library for networking on AoC (unless I mixed up with another project).

Quote:Thanks in advanced, I'm vague on this (I came across one link about RPC & MMORPGs).


Canonical RPC (blocking + thread-pool workers) is not ideal choice for this type of networking. Typically, you'd just want a simple messaging system. If you want to avoid rolling your own, then AMI (asynchronous method invocation) in various libraries can be used for this purpose. Some also provide publish/subscribe mechanisms.

Quote:Should I just start creating and documenting my own packet protocol and commands?


Packet protocol is almost always a consequence, defined by whatever serialization you use. Once you know what kind of functionality you need, express it in API (functions/messages/etc). Then, simply provide a way to serialize those and voila - you have packets. Encode, encrypt, compress them as needed.

If interoperability is your primary goal (different versions, language and platform-agnostic client/server pairs), then defining API externally may help. But again, focus on the functionality or API you need. See here for such approach.

As far as processing the messages, the simplest way is still networked loop. While other methods can be used, they will inevitably result in more complications than needed. So regardless of what approach you choose, favor:
Quote:Then we do something like Kernel::pushEvent (myEvent), which collects all events of one frame in a list. At the end of the frame, we handle all the events.
instead of typical automated event dispatching performed by RPC libraries.

This topic is closed to new replies.

Advertisement