That’s not quite answering my question… I’m more asking what is it about quaternions that makes them always more optimal for data storage? Axis-angle is also 4 numbers, so that’s not it, but maybe it’s something like “you don’t need as much precision to store the real part of the quaternion” or “it’s faster to convert to/from quaternion than it is to do the same for axis-angle”?
Anyway I was just checking whether there was a real reason to use quaternions over axis-angle, or whether you just forgot / didn’t bother mentioning a viable alternative option. But clearly there is some reason which I am not privy to
I have a pea brain and had to look into string.pack and string.unpack just to understand how this would be used in development, but for those who are already familiar with it, it looks very promising!
Glad we’re getting some more developer-oriented updates lately
(and for other pea brains out there, it looks like a way to compress/encrypt data so it takes up less space essentially)
The nice property which quaternions get you is that they’re a naturally symmetrical representation so you can encode all of the components in the same way which avoids unintentionally biasing the distribution of representable values.
I think buffers not having a cursor by default to be a smart choice. If you’ve ever had to create a non-cursor buffer from a cursor buffer, you’d be stoked.
My brain genuinely can’t wrap around how I would make a very efficient writei24 and readi24 function. Are you able to provide this? Thank you so much.
EDIT: figured it out!
local function writei24( b: buffer, offset: number, value: number ): ()
buffer.writei16( b, offset, value//2^8 )
buffer.writeu8( b, offset+2, value )
end
local function readi24( b: buffer, offset: number ): number
return 2^8*buffer.readi16( b, offset ) + buffer.readu8( b, offset + 2 )
end
For signed 24 bit integers the most straightforward way is to just use a temp buffer. The only complication is sign-extending the value:
local TempBuffer = buffer.create(4)
local function writei24(b: buffer, o: number, value: number)
buffer.writei32(TempBuffer, 0, value)
-- Chopping off the most significant byte has no affect if the value is
-- within the i24 range.
buffer.copy(b, o, TempBuffer, 0, 3)
end
local function readi24(b: buffer, o: number): number
buffer.copy(TempBuffer, 0, b, o, 3)
-- Sign extend
buffer.writeu8(TempBuffer, 3, if buffer.readu8(TempBuffer, 2) >= 128 then 0xFF else 0)
return buffer.readi32(TempBuffer, 0)
end
EDIT: I’d have to benchmark to see whether your implementation or this is faster. I was trying to avoid the division but the extra branch in my version may make that counterproductive in practice.
Kinda wished buffers were bit-based. I sometimes dont rlly need 8 bit buffers, but smaller than it, but maybe that kind of optimization is too extreme, either way this is gonna be the golden age of networking in roblox!
Regarding both of these, could we see buffer support for MessagingService? This is pretty similar to DataStore support I can imagine, it would be very cool to see. Compression & encoding designed for storage in DataStores and for transmission over MessagingService would be incredibly useful.
I can forsee a lot of interesting tech utilizing buffers over MessagingService as a capability in addition to DataStores alone, because it’d increase the bandwidth we can get and the amount of data we can theoretically send.
It would be interesting to allow cross-server spectating or match previews for example.
This update allows for 8 bit integers. Do you know the optimisation capabilities here? This has to be the best update to come from Roblox that I have ever encountered. It also allows for over 200 variables (technically), since you can use the offset to read and write to different variables. This. Is. Epic.
Are there plans to add API functions for reading/writing varints to buffers (buffer.readvarint/buffer.writevarint)? I feel this would be a very simple solution to people’s compression demands. While implementing these functions on our own is possible, the algorithm is probably not straightforward to most people and a native implementation would be much faster considering Luau lacks bitwise operations.
Please allow us to manipulate single bits. Some functions to read and write numbers of arbitrary bit size would go along nicely with that. Even if hardware doesnt support it, it’s useful. That extra freedom would be great, but it’s also worth noting that this would lend itself to more dynamic code. The current read/write functions are good but I don’t always want bit size hardcoded.
I don’t mean to ask this in a passive aggressive way, but does “cannot currently” imply that attribute implementation is in-the-works or has attribute compatibility been banished to the backburner?
Are there plans to allow for buffer.fill to be able to use values larger than 8 bits?
I’m writing a compression utility that needs to be able to write individual bits, my current approach is to split the bits in N bytes and write each byte in a loop, however I had the idea to use buffer.fill in order to fill in the bits all at once getting rid of the loop but to my disappointment buffer.fill only uses the first 8 bits of the value passed to it.
Attribute implementation is not even in the backburner, there are no plans to add it right now.
I guess ‘currently’ was a bad choice of word to use there.
No.
Filling custom repeated sequences of bytes can be implemented similar to how string.rep works: if the pattern is 4 bytes, first you copy 4 bytes to make 8, then you copy 8 to make 16 and so on. Only a few buffer.copy operations are required to fill megabytes of data this way.
I just successfully migrated from the BitBuffer module to this luau’s buffer for my network library.
Thank you Luau team. I hope this improves performance.