Closed mreinstein closed 10 years ago
I've been thinking about how to do this for a couple days, and I think the best (only?) way would be to keep some sort of cache of each replicated object's properties.
Now that Wasabi supports nested objects, this is somewhat complicated. The best way I can think of is to take a deep copy of each object on the server during each update where a field changes, and traverse it in tandem with the real object to find the deltas.
This cache can live completely inside the Connection object, so at least it won't be as intrusive as wsbSerialNumber
and friends.
I think this ends up being between linear and O(n^2) time, depending on the frequency of attribute updates. Worst case is when no attributes are updated. All of that is fine since it's an option, but it's worth documenting.
An alternative idea I had was making a .wsbDirty
attribute, mark it false after an update is sent, and let the user mark it true as needed. I'm starting to feel guilty about intrusively hanging data on user's objects, but something like this would reduce it to O(n) and save a ton of memory, while also introducing the possibility of user error.
Thoughts?
Here's the algorithm I'm thinking of. This would be done every time an object is being sent over the wire:
bytesToSend = pack object
crc = crc32 bytesToSend
if crc != lastCrc
send bytesToSend
lastCrc = crc
I don't know if crc32 is the right algorithm, maybe theres a better choice. but the idea is that you generate a signature for the bytes you're about to send, and only send an object update if anything has changed. Granted this is not as efficient as sending partial objects, but for objects that dont change at all over several frames this will still be a pretty nice bandwidth savings, fairly simple to implement, has low memory requirements, and it's O(1).
Thoughts?
bonus points if this feature can be turned on/off for a given connection or server. :)
I like the checksum idea, because it's cheap, unobtrusive, and #20 requires checksums of some sort, anyway. I'm going to try that first and see how it performs.
Thanks, @mreinstein!
This turned out to be a really good idea. It actually saves CPU as well as bandwidth if there are enough objects not getting their data changed, because it's so expensive to prepare Bitstream contents for transmission.
Still working out how to configure it, though
Very cool, can't wait to use it :+1:
Are you going to publish a new version to npm soon? It seems like a lot of features and non-breaking improvements have been added since the 0.2.0 release. Assuming api didn't have any breaking changes we could bump to 0.3.0 :)
I was just thinking about that, in fact.
I'm building a small game that's more complex than the wasabi_example
to demonstrate the more advanced features (and stress test them). Once there's a bit of testing done "in the wild" I definitely want to publish as 0.3.0 :)
What would be a nice way to save even more bandwidth would be to specify a "send deltas" mode, where the serialization code tracks the last sent value, and only streams data if at least 1 field has changed.