Why are you using an obscure data type to pack your data instead of simply directly sending a binary string which would not only reduce your bandwith usage even further but be faster to run as well as it would simplify your code.
You also run the risk that roblox might change the replication behavior for these data types down the line.
Great post! Awesome work on the game so far, itās looking real cool.
As a couple others have referenced, Roblox backported Lua 5.3ās string.pack
and string.unpack
in August 2020 (more than a year after my original topic). Combined with table.concat
, these functions allow you to easily encode and decode an entire list of values to and from one compact binary string. The savings you would get going from your current setup to this approach are relatively minuscule, but preparing data to go over the wire is perhaps the most appropriate use for string.pack
on Roblox right now. it certainly suits the task better than these funny int16 vectors. Nevertheless, I appreciate your appreciation of my wild hack
Other people have mentioned using binary packing in lieu of a Vector2int16 but for your case that would actually up the bandwidth! The footprint of a string is 5 + n
bytes (where n
is the length of the string) compared to a set 5
for Vector2int16.
In your case, if you changed nothing else, you would end up with a 7 byte payload if you sent a stringā¦ At which point you may as well just send the number outright.
This is only true for very small packets in which case bandwidth wouldnāt be an issue anyway.
For large payloads assuming your own numbers are correct if you were to send for example a packet with a size of 300 bytes you would end up with a bandwidth usage of 305 bytes for a binary string, 350 bytes if you are sending an array of 50 Vector3Int16 and 375 bytes if you are sending an array of 75 Vector2Int16 plus some additional overhead due to sending an array instead of a single string.
I didnāt think of that! Definitely something Iāll have to try out!
Thanks! Iāll definitely check out the string thing soon too
I use to do something like this. Someone told me it was bad practice, which didnāt make sense. But reading your topic, I may come back to this and redo my frameworks to include byte channel streams to manage.
Obviously still some bad practices in regards to how some packets are being used lol but the main idea behind byes is here I think?
Correct me if Iām wrong because I donāt want to backtrack
Also try and ignore all those bad requires. This was very early code practice on the Roblox platform.
Just want to validate that the pattern I had is in line with this article.
Thanks for the read
At first glance, looks good! As long as itās saving bandwidth
Yes thatās why I said āin [the OPās] caseā. Obviously the math works out to being more efficient the more data you add - thatās very basic math. Itās more efficient for every case but one where youāre sending a single Vector2int16ā¦ Which is what the OP seems to be suggesting that theyāre doing.
Given that, it seems pertinent to mention it.
The number of Vector2int16s sent depends on how many units are moving! In most cases there are more than a couple units moving so the string idea is not a bad idea in theory. Iāll have to test it out though!
Wow, great read, wish there were more posts like this. I like some of the unthought of optimizations you used, now I think I may explore the same optimizations aswell for my games.
Thanks!
- This is fired when the value changes to the relevant clients. This consumes basically no bandwidth in comparison to moving units, so we didnāt take any particular steps to optimize this as itās not worth it.
- We can take a part that is part of terrain and calculate the height of terrain based on the partās bounding box. We then save this data so that we donāt need to recalculate.
- Yep, we use animation controllers. We then just throw in some of Robloxās walking/running animations and can modify the parts we need.
I donāt know if I just overlooked this in the post but how do you override Robloxās replication system?
Since we donāt use parts on the server, no replication is done automatically. Positions are stored inside scripts (for example, Unit.Position = SomePositionHere), and we can control when we send position updates to clients.
You only update goal positions when the actual goal changes right? Ie they reached a node. Then delay a bit and interpolate on the client. This is what I do and it works great
We send position updates for moving units at about 10 FPS. We canāt just set a goal position because units can be pushed and stuff. Collisions and everything is simulated on the server and replicated to the client; all the client does is smooth out movement between replication steps
How does this work with combat and/or projectile combat? What about hit detection? Calculating distance to check for every hit seems kinda redundant to me, and you canāt trust the client to make these calculations, but they are the only ones who can.
I feel this system is very specific for this type of RTS, but good job on being able to optimize your game to this degree.
This is very specific to our game as I mentioned! The optimizations definitely wouldnāt work for many other kinds of games. For an RTS, however, these optimizations work well since anything important is done on the server.
This is some big brain crap right here. Probably the most networking optimized thing Iāve ever seen. Great job!
what method did you use for smoothing out the movement on the client?