• How reliable are usermessages, and is there any length limit for sending strings?
    28 replies, posted
I'm thinking about remaking Bomberminge from scratch, as using prop_dynamics for all the crates scattered on the map was definitely not a good idea, plus it would generate reliable snapshot overflows on large maps with many players. So I thought about using only one entity which would handle collisions for all players, and draw all the crates clientside. The idea would be to encode the position of every crates into a string, then send it to the client when they join, and update it using usermessages every time a crate is broken. So far, I can turn a 30x30 grid into a less than 100 characters long string. Better than 900 times god know how many bytes for storing position, angle, color, model, for every crate, right? Now, is it safe to send this to a client through a usermessage, or should I cut it into smaller parts and send them successively? And most importantly, can I send a usermessage every time a crate is broken, so the client generates gibs and no longer draws that crate? Is there any acknowledgement system that makes sure the client receives that message, or should I attempt to do one myself using concommands? Yeah, I know I could have tried it by myself, but there is less than one month left to the contest, I didn't do shit for a month, and I'd like to know if I'm going the right way or not. I have always been absolutely terrible at network optimization, prediction and that kind of stuff.
255 bits is the limit, I believe. Very reliable.
As I understand, they won't be received by a client if said client is experiencing a lot of lag. Not sure if that's true though but it's what I've been told.
[QUOTE=DarkSpider;19999218]As I understand, they won't be received by a client if said client is experiencing a lot of lag. Not sure if that's true though but it's what I've been told.[/QUOTE] Any message won't be received if the client is timing out. There's nothing you can do to stop that except checking on the client if a message was received when expected.
[QUOTE=|FlapJack|;19999151]255 bits is the limit, I believe. Very reliable.[/QUOTE] 255 bytes isn't it?
[QUOTE=NullPoint;19999351]255 bytes isn't it?[/QUOTE] Could well be. I just thought that sounded a little big though.
It is possible that clients will not receive usermessages, as the server does not know when a client didn't get the message because the client doesn't give any kind of confirmation whether they got it or not.
[QUOTE=|FlapJack|;19999380]Could well be. I just thought that sounded a little big though.[/QUOTE] I just checked, It is definitely 255 bytes.
I suppose, each ascii character takes up a byte, so it must be 255 bytes. [b]Edit[/b]: Sappin mah automerge.
V Look below V
Not sure but I think the name takes up bytes too.
[QUOTE=Gbps;19999636]It's UTF-8, so it takes 2 bytes.[/QUOTE] It's UTF-8, so it's a variable length encoding. All the characters can take from 1 to 4 bytes. There's also a lot of mis-information in this thread, I've explained this a bit in two posts: [url]http://www.facepunch.com/showpost.php?p=19576443&postcount=31[/url] [url]http://www.facepunch.com/showthread.php?t=705037[/url] Strings are n bytes + 1 for the null terminator. You have 252 bytes to work with. You can only fit a 251 byte string. Not that I recommend it.
Ok, thanks for the clarification ^^
[QUOTE=Gbps;19999449]It is possible that clients will not receive usermessages, as the server does not know when a client didn't get the message because the client doesn't give any kind of confirmation whether they got it or not.[/QUOTE] Yeah, I'm thinking about making the clients reply using a concommand or something, so the server makes sure they received all the needed data. [QUOTE=AzuiSleet;20000461]It's UTF-8, so it's a variable length encoding. All the characters can take from 1 to 4 bytes. There's also a lot of mis-information in this thread, I've explained this a bit in two posts: [url]http://www.facepunch.com/showpost.php?p=19576443&postcount=31[/url] [url]http://www.facepunch.com/showthread.php?t=705037[/url] Strings are n bytes + 1 for the null terminator. You have 252 bytes to work with. You can only fit a 251 byte string. Not that I recommend it.[/QUOTE] Okay, I guess I'll just cut my string into small parts and send them one after each other, making sure the client didn't miss any of them. Anyway, it only does that every time a new round starts, so even if it's slow, that shouldn't cause too much of a problem, at least this shit waiting time Fretta inserts at the beginning of each round will have an use here. Thanks for the clarification!
This is the life long problem because, by doing what you just said, you're pretty much replicating datastream, so when that happens to me, I use datastream. People need to stop being scared of datastream.
[QUOTE=Gbps;20005163]This is the life long problem because, by doing what you just said, you're pretty much replicating datastream, so when that happens to me, I use datastream. People need to stop being scared of datastream.[/QUOTE] Yeah, about datastream, I strongly considered using it, but I wasn't sure whether this is really what I need. Gotta look at the source code and see if it does cut strings into small parts before sending them.
There's nothing wrong with the datastream assuming you use it correctly. Using the datasteam for a short, long or small string of course, is exceptionally dumb.
[QUOTE=|FlapJack|;20010149]There's nothing wrong with the datastream assuming you use it correctly. Using the datasteam for a short, long or small string of course, is exceptionally dumb.[/QUOTE] But medium strings are a-ok?
Anything that's over the 251 byte limit of a usermessage, it's saving you pointless code.
[QUOTE=|FlapJack|;20010149]There's nothing wrong with the datastream assuming you use it correctly. Using the datasteam for a short, long or small string of course, is exceptionally dumb.[/QUOTE] [QUOTE=Lexic;20010381]But medium strings are a-ok?[/QUOTE] Bahahah, took me a while to understand that you were talking about "shorts", "longs", and "small strings", and not "short, long and small strings". :v: Okay, then that's pretty much what I need, thanks.
[QUOTE=_Kilburn;20020328]Bahahah, took me a while to understand that you were talking about "shorts", "longs", and "small strings", and not "short, long and small strings". :v:[/QUOTE] ...Oh, well I guess that make rather more sense. I did wonder why he said short twice. :downs:
[QUOTE=NullPoint;19999462]I just checked, It is definitely 255 bytes.[/QUOTE] Correct for default GMod. I personally also set sv_usermessage_maxsize to a higher value, but never checked if you can get around the 255 bytes limit.
[QUOTE=|FlapJack|;19999151]255 bits is the limit, I believe. Very reliable.[/QUOTE] [b]255 Bytes[/b], 252 if you push it to the limit in the usermessage (due to 3byte pooling lost to the name) Usermessage = 3bytes + data Usermessage = length of name bytes + 1 null byte + data 252 is the most you can safely send.
Bytes are the standard unit in computers. Even a boolean variable (which is just true/false and could be represented with a single bit) uses a whole byte (8 bits) worth of memory.
[QUOTE=theJ89;20024576]Bytes are the standard unit in computers. Even a boolean variable (which is just true/false and could be represented with a single bit) uses a whole byte (8 bits) worth of memory.[/QUOTE] not in networking, if it's encoded along with a bitstream. Which is why datastream is cool, it totally makes sending bools optimized for network transport!
[QUOTE=Lau;20025447]not in networking, if it's encoded along with a bitstream. Which is why datastream is cool, it totally makes sending bools optimized for network transport![/QUOTE] datastream encodes everything as a string. It is neither optimized nor efficient. However, it is reliable.
I think he means his own datastream, that rehab thing I saw somewhere?
If you're interested in the networking used in gmod's usermessages, here's what it generally is (from gm_transmittools): [code] switch(value.type) { case NWTYPE_CHAR: if(luavalue != NULL && luavalue->isNumber()) packet.write.WriteChar(luavalue->GetInt()); else packet.write.WriteChar(0); break; case NWTYPE_BOOL: if(luavalue != NULL) packet.write.WriteOneBit(luavalue->GetBool()); else packet.write.WriteOneBit(false); break; case NWTYPE_SHORT: if(luavalue != NULL && luavalue->isNumber()) packet.write.WriteShort(luavalue->GetInt()); else packet.write.WriteShort(0); break; case NWTYPE_FLOAT: if(luavalue != NULL) packet.write.WriteFloat(luavalue->GetFloat()); else packet.write.WriteFloat(0); break; case NWTYPE_NUMBER: if(luavalue != NULL && luavalue->isNumber()) packet.write.WriteLong(luavalue->GetInt()); else packet.write.WriteLong(0); break; case NWTYPE_ENTITY: // ehandle packet.write.WriteLong(ResolveEHandleForEntity(luavalue)); break; case NWTYPE_VECTOR: if(luavalue != NULL) { Vector *vec = (Vector *)luavalue->GetUserData(); if(vec != NULL) { packet.write.WriteBitVec3Coord(*vec); break; } } packet.write.WriteBitVec3Coord(Vector(0,0,0)); break; case NWTYPE_ANGLE: // angle packet.write.WriteBitAngles(QAngle(1,1,1)); break; case NWTYPE_STRING: packet.write.WriteOneBit(0); // no pooling if(luavalue != NULL && luavalue->isString() && luavalue->GetString() != NULL) packet.write.WriteString(luavalue->GetString()); else packet.write.WriteString(""); break; } [/code] Gmod's usermessages are far more optimized than datastream, simply because it does all the bit twiddling and the bools are 1 bit.
[url]http://gmod-haza.googlecode.com/svn/trunk/PIPE-Lanes/garrysmod/[/url] If you want serious networking. Clients will require gm_luasockets thou.
Sorry, you need to Log In to post a reply to this thread.