Skip to main content
gamedev.net
🔒 Locked

Client/Server Combat Message list

Started by EmpireProductions Nov 18, 2009 at 5:52 AM 7 replies 1.7k views
Original Post
EmpireProductions
EmpireProductions
I am making a list of all the messages needed to be sent between client and server that are combat related. Here is the list and if you have any suggestions, or if I missed any, or if you would do it differently please let me know! SERVER_ATTACK - Sent from client to server in order to attack a NPC or other character. Upon receiving this message the server will handle the attack event through the combat manager. CLIENT_ATTACKSUCCESS - Once the server is finished with the calculations if the attack was a success the server will send the client this message and the client will handle the visuals for the attack and do whatever else is needed for the attack. CLIENT_ATTACKFAILED - If the attack failed then the server will send this message to the client and the client will handle it accordingly. CLIENT_ISDEAD - If the player or NPC is killed this message will be broadcast to all clients so the clients can handle the death (show the visual if with in view, or whatever else) CLIENT_KILLEDTARGET - Sent to the attacking client in the event that they killed their target. Allows the client to handle level up and experiance gain as well as anything else needed. SERVER_LOOT - Sent from client to server to bring up the loot screen and update the players inventory. CLIENT_RESPAWN - Sent from server to client to notify the client that they have respawned and to give the client the location where they should respawn to. CLIENT_ATTACKED - Sent from server to client to notify the client that they are being attacked.
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
Antheus
Antheus
Quote:
Sent to the attacking client in the event that they killed their target. Allows the client to handle level up and experiance gain as well as anything else needed.


You will probably not want to do this on client.

For sake of simplicity, let client be able to receive only object property changes. So messages will look something like this:
// 123 = enemy, 22 = player[o:123, p:health, v:23][o:22, animation, "attack_success"][o:123, p:health, v:13][o:22, animation, "attack_success"][o:123, p:health, v:2][o:22, animation, "attack_failed"][o:123, p:health, v:0][o:22, animation, "attack_success"][o:123, animation: "death"][o:123, model: "dead_monster"][o:22, p:exp, v: 562] // was 542[o:22, p:level, v: 11] // was 10[o:22, animation, "level_up"]


Obviously, encoding of this information in an efficient manner is left as exercise to the reader. For flexibility you could send strings (for animation and model names), and use some form of per-connection hash to cache the values, or you could encode them in some external resource file shared between server and client.

In above, p:, v: means set(property, value), whereas animation or model are similar to RPC call: setAnimation(), setModel().

In some designs, they could be literally implemented like that. Send name of either property to be changed, or function to be invoked with required parameters.
EmpireProductions
EmpireProductions
What I meant by handle level up and experiance is display the text for the player to see. All math equations for figuring that stuff out will be done on the server. The a Player data structure will be sent to the client with the updated stats.
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
hplus0603
hplus0603
Here's my list of messages:

Client -> Server:
1. Request property change (property-path, value)
2. Invoke service (service, arguments)

Server -> Client:
1. Property changed (property-path, value)
2. Invoke event handler (handler, arguments)
3. Object created (object-id, property-values)
4. Object deleted (object-id)

That's all you need. Your game will, over time, add a number of different objects, properties, services and event handlers. Trying to define a message field in some specific message for each of these will, over time, become unmaintainable, so it's probably better to build an infrastructure that allows this to grow.

Here's an example of how one such protocol can be structured:
draft LESS protocol
enum Bool { True, False, FileNotFound };
smr
smr
Quote:
Original post by hplus0603
Here's my list of messages:

Client -> Server:
1. Request property change (property-path, value)
2. Invoke service (service, arguments)


What do you do in the event that the change was rejected? On the client I would probably assume requests will be granted to hide latency. How does the client know to return the value to the server's version? Do you flag the property as dirty for that client so that it'll be sent on the next update?
Kylotan
Kylotan
I would assume you could set up an event handler for that. (Method 2.) The server could have a generic notification that it sends which tells the client that a given property wasn't changed. Or, it could just overwrite that property by sending down the actual value.
hplus0603
hplus0603
Quote:
What do you do in the event that the change was rejected?


Easiest is to ignore that case. Slightly slicker is to send back a property update message with the old value.

When you know the exact version of software and schema used on both ends of a connection, this is a simple problem, by the way. That's why MMOs generally require client patches with server updates. Meanwhile, if you want to support heterogenous clients/peers, you'll have to add some versioning to the system. In the LESS description I argue that a schema description with known semantics for known quantities, and a subscription based event/property/object viewing system will be robust, efficient, and not terribly hard to implement.
enum Bool { True, False, FileNotFound };
kyoryu
kyoryu
And LESS isn't that different, at a high level, from REST...

The only problem with 'set this property' type messages is that they introduce a ton of race conditions.

If two players want to increase the current value of something (which is 3) by one, they'll both send messages to the server requesting a new value of 4 - and the server really has no way to know that the value should really now be 5.

I think you get this, I'm more clarifying for the use of others.

Sending state changes is probably best left only to values that the client is either authoritative over, or pseudo-authoritative (only that specific client that will modify) over.

Apart from something like LESS, what can also work is a system where you define messages as classes that can be serialized, or just a generic text command (or even a combination).
hplus0603
hplus0603
Quote:
Original post by kyoryu
And LESS isn't that different, at a high level, from REST...


You mean, apart from the part where REST is state-less and LESS is explicitly about replicating a shared state?

Quote:
The only problem with 'set this property' type messages is that they introduce a ton of race conditions.


The race condition exists in the world, so you have to resolve that at your point of authority. Messages aren't instant. That's one of the annoying parts of doing networked simulation development.

Quote:
Sending state changes is probably best left only to values that the client is either authoritative over, or pseudo-authoritative (only that specific client that will modify) over.


In LESS, the model is that the authority sends "state changed" whereas clients may send "request change," or may call RPC functions, and the server makes up its mind. If the change is delta, then you want an RPC. If the change is fixed ("set the color of this to red") then requesting a new value is fine -- one of the racing requests will win, and the other won't.

This is a good point, though -- in lockless OLTP systems, you generally send "the value I saw was X, and I now want it to be Y" and the server will fail the request if the value is now Z (letting you know that it's now Z) and you get to make up your mind and re-try at the client level. Maybe that should be added to the "request change" message. Or maybe "request change" should be dropped in favor of known RPC. The draft is still very much up for comments and feedback.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.