Messages

Coordinator
Dec 9, 2007 at 8:03 PM
I was thinking that message types should be created in groups pertaining to the interface for which they'll be communicating. For example, all messages will be handled by the CameraInterface should be created in a single file, like CameraMsgs or something like that. If we have each message have its own class file we'd have a lot of files. We can certainly have each message get its own class, but within a single file.
Coordinator
Dec 9, 2007 at 8:06 PM
I'm curious where the message is handled. I see that it is added to a queue. Do we have a system in place to let the desired interface handle the message? I'm setting up the CameraInterface, for the moment I will have to forego messages I believe, but I'll be adding comments to all places that need to be converted to messages soon.
Coordinator
Dec 9, 2007 at 8:11 PM
Will we be able to pass references in our messages? This would keep us from making copies of large amounts of data. For example, if I want a message to return to me a list of a bunch of objects, I wouldn't need an entire list returned to me, just a reference would be fine.
Dec 9, 2007 at 8:20 PM
You determine the content of the message yourself, so pass by ref if you feel like it.

There is currently no way of specifying a target for a message, as messages are processed every cycle and there will a lo of messages/listeners this can be potentially expensive. I'm working on finding a better implementation than the one in now as it's too expensive.
Coordinator
Dec 9, 2007 at 8:26 PM
That's cool.

Maybe we could enumerate all interfaces, and then when we send a message specify the interface we need the message to go to. The message handler could send according to the interface ID in the message.
Dec 9, 2007 at 8:28 PM

LordIkon wrote:
Maybe we could enumerate all interfaces, and then when we send a message specify the interface we need the message to go to. The message handler could send according to the interface ID in the message.

I thought about it, but I still haven't gotten to the conclusion that that's the right way, I'm still exploring other options.
Dec 10, 2007 at 3:32 PM
Slight request Sturm, can we have a flag for every message type by default please? I need some flag to say if messages are local only or network also. At the minute the engine will send every message across the network. One bool per message could streamline the networking wuite a bit.
Dec 10, 2007 at 5:11 PM
How would you set this flag, what dertermines if a message should be on the local/remote? Wouldn't there be specific messages which should be send over the network?
Dec 10, 2007 at 6:05 PM

Sturm wrote:
How would you set this flag, what dertermines if a message should be on the local/remote? Wouldn't there be specific messages which should be send over the network?


I was thinking that when the message is created this falg is set. It basically just tells the network to ignore it or not. Any specific messages can be sent by directly calling a SendMessage function. Otherwise they should be network messages. This way any inout message that moves an entity can also be transmitted with little to no work required for that actual message type.
Dec 10, 2007 at 7:03 PM
Will there be messages which are send both to the client and the server, where only that bit differs? Could you describe the scenarios?
Dec 10, 2007 at 7:12 PM
Edited Dec 10, 2007 at 7:13 PM
Sure thing. Currently I see three message types, depending on the actual game:

  • Local message - Not sent over the network as it only applies locally. An example would be a camera rotation. Other clients would not need to know so it should not be sent.
  • Server Message - A message only for the server, to process. An example in a FPS could be a gun fire. Having the server process it would remove any cheating. Any game could be a new person joining
  • Client Message - Sent from the server to the clients, or in a peer to peer game, from client to client. To continue the above example, after the serve is done, the results of the gun being fired are sent out. When a person joins the server announces there start location, equipment, etc.

Really from the message class all I need would be a bool saying local or networked, or if we want to further split server and cleint messages in the class rather than the data, an int. 0 being local, 1 being client, and 2 being server. What do you all think??
Dec 10, 2007 at 7:51 PM
For me that sounds like 3 different message types, which should be used and not just a bool on the message, I guess that some messages should have a target etc in order to determine who the message is meant for (i.e. a player dies, you would need to know which player has died).
Dec 10, 2007 at 7:59 PM
I would leave that kind of thing for each game to implement, via the data part of the message. I dont know exactly how you envisioned the message system, so Ill go with your feelings on it.
Dec 11, 2007 at 4:28 AM
Today the messages got a type parameter, which is just an int. You could use that to specify your message, simply add another int to the list.
Dec 11, 2007 at 3:36 PM

Sturm wrote:
Today the messages got a type parameter, which is just an int. You could use that to specify your message, simply add another int to the list.


Nice one. Ill go under the assumption 0 is local, 1 is server, 2 is client and null is all. Unless anyone disagrees?
Coordinator
Dec 11, 2007 at 3:42 PM
Edited Dec 11, 2007 at 3:43 PM


mikelid109 wrote:
Nice one. Ill go under the assumption 0 is local, 1 is server, 2 is client and null is all. Unless anyone disagrees?


If we're going to do it like that, couldn't we enumerate those values? So we pass something like: BroadcastType.Client
Dec 11, 2007 at 3:43 PM
I would define those as constants somewhere, so they're not just magic numbers in the code.
Dec 11, 2007 at 3:47 PM
I disagree ;)

The type specifies the type of message to send, i.e.
Exit = 0;
KeyDown = 100;
KeyPress = 101;
KeyUp = 102;

so would have to define your own range for server/all messages.
Dec 11, 2007 at 4:09 PM
Sure thing with the enums. Ill add a second int that will hold the enumed type. Ill try and get to it tonight, mostly as a stop gap as I need something to go on.
Dec 11, 2007 at 4:50 PM
Done and uploaded as a patch. Up to you if you want to apply it (assuming it passes inspection :) ) or wait for my commit of the local networking.
Dec 11, 2007 at 5:47 PM
I declined the patch.

Firstoff do not post code which will not compile.

I think you misunderstood what I said. You have to create a new range for the individual messages. You have to define the messages which have to be send across the wire. For example KeyDown will not be send across the wire. So you need to define the messages which should be send across.

Can you give some examples of the different message types you are planning on sending?
Dec 11, 2007 at 6:26 PM
Sorry, didnt realise it didnt compile. I must have changed a bit after I checked. I get what you mean now. I was going to leave messages quite game specific, but have certain things handled by the engine. The ones I plan to always have the network do with no user intervention are:

  • Player joind/left
  • Object created/destroyed
  • Object rotation/posistion

Thats all that comes immediately to mind: have I missed any?

All others are just autmatically passed unless otherwise noted. How about the first 2000 types or so are local only?
Coordinator
Dec 11, 2007 at 6:47 PM
Edited Dec 11, 2007 at 6:50 PM
Do we really want one huge list of types?

Is it possible that each interface/manager has a list of types.

When you send the message you send an enumerated value for the interface, and an enumerated message type.

Example:

*CameraInterface (pseudocode only):
Msg CameraMsg;
MsgID = MsgType.StrafeCamera;
(CameraMsg as CamStrafeMsg).value = 0.5 * gameTime.ElapsedGametime.Milliseconds;
SendMessage(Msg, MgrType.CameraMgr);

This would keep us from having one huge list, and would let us split up the list of types into their respective manager classes. So I could keep all the messages and their types in the CameraInferface/Manager.
Dec 11, 2007 at 6:54 PM
I initially set the first 1000 as kernal messages but we can easily assign the first 2000 to kernel and then 2001-4000 as server messages and then 4001-6000 to broadcast messages.

So you would have
    RequestJoin = 2001;
    RequestLeave = 2002;
    RequestPlayerList = 2003;
 
    PlayerList = 4001;
Dec 11, 2007 at 7:00 PM

LordIkon wrote:
This would keep us from having one huge list, and would let us split up the list of types into their respective manager classes. So I could keep all the messages and their types in the CameraInferface/Manager.

You can keep all the type definition inside the camera class. It's still just an integer. I think that we should just be able to, when we relese, specify the range where they shouldn't create types (i.e. not below 1M)
Coordinator
Dec 11, 2007 at 7:36 PM
What if 3 different develops are creating message for their own seperate managers at the same time. Unless they've worked out a system where they each can create messages in their own pre-defined range, then they risk creating a message of the same ID, which could cause some very strange issues in the game.

Additionally, when creating new messages, if a pre-defined range for each interface wasn't set, then theyd be forced to check multiple places in the code to see if that message ID was already in use.
Dec 11, 2007 at 8:17 PM
The issue here is that there has to be a way of aligning all parts of the system, and across the wire. Having a system which would assign id's when requested or initialized, could be even more problematic as the same system could get a different ID on one client than on another. We would create different types for different messages, but I felt that this would be a little heavy as in most cases most of the messages have the same data. I choses integers as it seemed like the least intrusive and most performant solution.

I can rework this and see if i can create a better solution in order to bring messages around.
Jan 21, 2008 at 12:59 PM
Hi,

I was reading messaging system, to implement the game state system and i think the each Screen shoud listen um type message, not all of one. If each subsystem put you messages on queue and some messages type like a Mouse, Keyboard, Network, etc. The user would be subscribe to liste each message type, this would minimize number of listener of message queue. What you think about?
Jan 21, 2008 at 1:14 PM
You mean having each message receiver inform the messaging system of which message types it requires? The overhead of doing this sorting is most likely greater than just sending all messages everywhere and letting listeners ignore them if not interested.
Jan 21, 2008 at 1:39 PM
No, each system will post your messages, and will fire an específic listener like OnKeyboardMessage(IMessage), OnMouseListener(IMessage), etc, and only subscribed client will get this message. Today, all listeners have to check all messages posted on queue.

Jan 21, 2008 at 1:59 PM
So the message queue would hold a list of events? You would still need a MessageType range -> event mapping. A possible issue I see is what would you do with custom client messages? If they added their own message types for their game, they would need to go into the engine code to add new events. You could just wave your hands on that issue and provide a OnGenericMessage event, but that leaves you with a bit of inconsistency.

The basic question would be: which is faster? Sending every message to maybe 5-6 end points, or doing a look-up in a table to send to maybe 2-3 end points.

Still, it's a valid idea and I'll leave it to the rest of the team to comment on this and decide if its viable. Conceptually it's an interesting idea and I'm not sure which would be "easier" to use. We could provide both. The message queue could remain as it is, and we could provide a helper class that allows message sorting from MessageType -> event that client code can use.
Jan 21, 2008 at 5:16 PM
I agree with shaw, using specific events is not very extensible. We want to provide a unified message system. We will provide some interaction objects once we are having a scripting layer/programming model for games.

Raising events is prob a little slower than queuing for the messages. but I can't imagine that it's going to be a issue, as this is a cornerstone in the language and as long as we don't override the functionallity it should be optimized, though I don't know about the XBox framework.

I originally porposed the GetMessage interface (that is the reverse of the current implementation) but the decision was to do the eventing message. We can't really provide both as this would generate a lot of possible missuse or missunderstanding.
Jan 21, 2008 at 5:21 PM
My rule for Xbox: If it might be slow, then it's definitely painfully slow. If there's a chance it might be optimized, then its still slow, just mildly bearable. If efficient algorithms/methods exist for a certain language construct, they are implemented using a less efficient method on Xbox. :)
Jan 21, 2008 at 5:47 PM
LOL :)