CommandToServer/Client Questions
I've been making use of CommandToClient() calls to pass descriptive information from server to client for the T2RPG mod. I know enough about the CommandToClient() and CommandToServer() functions work to make use of them and write my own function calls. But I have a few questions.
If anyone happens to know answers to these any of these questions off the top of their head, I'd appreciate it.
1st question: Blocking. Do these functions block? That is, does the sender wait for a handshake back form the receiver before continuing in the script?
2nd question: Sequencing. Let's say I make 40 CommandToClient() calls via a for loop on the server. Will the data be received in the same order the messages were sent? Or is there a chance that, for example, CommandToClient message 27 is received and processed before message 26?
3rd question: Length. Is there a limit to how big of a message these functions can send? For example, say I pass it a really long string as a parameter. Is there a point that this string will be truncated along with the rest of the parameters?
Thanks.
If anyone happens to know answers to these any of these questions off the top of their head, I'd appreciate it.
1st question: Blocking. Do these functions block? That is, does the sender wait for a handshake back form the receiver before continuing in the script?
2nd question: Sequencing. Let's say I make 40 CommandToClient() calls via a for loop on the server. Will the data be received in the same order the messages were sent? Or is there a chance that, for example, CommandToClient message 27 is received and processed before message 26?
3rd question: Length. Is there a limit to how big of a message these functions can send? For example, say I pass it a really long string as a parameter. Is there a point that this string will be truncated along with the rest of the parameters?
Thanks.
Comments
serverCmd / clientCmd are more or less fire and forget events, they don't wait for any return statements.
You might be a little off (I may be entirely wrong here too) on the second point. If you're spamming events in one frame tick (IE: Ultra-fast loop that runs faster than ~74ms) it may be possible for event 27 to hit before 22 due to a network hiccup. I haven't poked too much into original TGE's net code to see if serverCmd/clientCmd are based on the engine's TCP or UDP module. If it's UDP then there is a chance of the occurrence, if it's TCP however, then no.
Dead on for the third one, max of 20 arguments and none of these can exceed 1024 characters. If at all possible, you'll want to stay as small as possible in events.
In terms of my second question, I suspect it would be UDP. The only evidence I have for support is that I only ever port forwarded UDP on my router for the server, and things still work. I didn't even know that T2 used TCP. That's what prompted me to ask this question, knowing that UDP does not grantee messages are received in order (I do a lot of network stuff for my day job).
It sounds like I need to send the array index along with the skill info the client, rather than assume the info is received in order. I've been replicating the array on the client side via a counter. That could lead to sync issues. Going to need to fix that, just in case.
Just as I was typing this response, I had an idea. Datablocks get sent to clients, right? What if I hardcoded a custom datablock (that's possible, right?) and put all the skill info there. Would a client sided script be able to access the information from there? Or is that not how the force works?
Also, 74ms....ultra fast?
http://gamedevs.org/uploads/tribes-networking-model.pdf
Don't use datablocks for this purpose. They're intended to be transmitted once during the connection process, and are generally not readable to client side scripts.
Do be aware that the maximum bandwidth consumption of RPC messages is under about 1.3 kB/s, and they're issued in a first-come first-served basis. Since RPC is used for a lot of functions (including chat messages), chronically exceeding this bandwidth budget for your own tasks leads to a pretty unpleasant experience for the client. Parameters to RPC messages are Huffman encoded (a variable length entropy code) with a frequency dictionary optimized around ordinary (case-sensitive) English text. If you need to send a lot of data over RPC, but use a small character set (e.g. just numeric values), you can get around a 30% improvement by using a 1:1 mapping from/to the highest frequency characters in the Huffman dictionary and the symbol set you're using.
The alternative was to have the client request the information from the server whenever the menu was opened. Or at least the portion of the info for that particular item. I didn't like that idea, since the menu is designed for the client to be able to quickly click through information, which could stress the server. So I figured I'd just have all the info available on the client side and have the server send all the info one time when the user connects.
I could take the easy route and hard code it on the client side. But I'm trying to avoid that for 2 reasons. 1.) So I don't have to write things twice every time I add a new skill or item. And 2.) It would allow 2 different RPG servers to have different items and skills, yet the clients can use the same scripts.
That said, there have been quite a few mods over the years that have used the fully dynamic approach to actively send menu options on each request, and while it would certainly be noticeably slower than a client cached listing, it wouldn't necessarily create undue stress on the server. Particularly if you were to use tagged strings for your list entries, the data the server needs to push is minimal and well within the bounds of a practical bandwidth budget for a player in a position to utilize a menu. Many of the game's default dialogs/huds are set up to be used in exactly this manner already (think the inventory hud's pack/item listings, the server admin options, the score hud, the player list -- the latter two of which automatically refresh from the server periodically while open), so it's a very commonly used model in server-side mods.