EZBuffer : Manage Buffers Easily!

A while ago I made this module to make writing and reading buffers easy out of my curiosity of them. After some thought and finally having the ability to post on DevForum for the first time I’d open it up to the public for those who may find themselves dealing with buffers!

Why use EZBuffer?

  • Comes with a built in read/write cursor
  • Can make dealing with buffers a lot easier
  • Dynamic resizing writing functions included
  • Easily moddable, it’s just a basic bridge module

(Module provided after tutorial explanation)

So, how do we even use it?
I can give you a basic explanation and examples!
(Dump() is absolutely not required and advised against in usage outside of debugging and learning)

local EZBuffer = require(script.EZbuffer)

local MyBuffer = EZBuffer.new(4)
MyBuffer:write("i8", 0)
MyBuffer:write("u8", 255)
MyBuffer:write("i16", 1400)

MyBuffer:dump()

Now, what if we aren’t too sure how many bytes we need? That’s where the dynamics come into play!

local MyBuffer = EZBuffer.new(2)
MyBuffer:write("i8", 0) -- Writing is all compact to :write(itype), see extra info in comments for more
MyBuffer:write("u8", 255)

MyBuffer:writeDynamic("i16", 455)
MyBuffer:dump()

Writing a string? Got you covered!

local MyBuffer = EZBuffer.new(10)
MyBuffer:writeStringDynamic("Hello World!") -- Can ALSO be just WriteString if you can predict it's size
MyBuffer:dump()

– Reading is very similar to writing, except we are, of course, reading instead

local MyBuffer = EZBuffer.new(10)
MyBuffer:writeStringDynamic("Hello World!")

MyBuffer:position(0) -- Now we are at the start!
local Remaining = MyBuffer:remaining() -- This function tells you how far the buffer goes since the start!
print(MyBuffer:readString(Remaining)) -- Showing you that you can read strings as well!

Of course you can also just use :read() to read bytes normally, above I just showed a string example

local MyBuffer = EZBuffer.new(10)
MyBuffer:writeStringDynamic("Hello World!")
MyBuffer:position(0)

print(string.char(MyBuffer:read("u8")))

Here is another example, where we store an RGB color within just 3 bytes! (And show an example of chaining)

local MyBuffer = EZBuffer.new(3)
MyBuffer:write("u8", 255):write("u8", 0):write("u8", 146) -- Chaining is supported here!
MyBuffer:dump()

Sorry if these aren’t the best examples, but I am sure you can get the point!

Extra Note:
! To pull the actual buffer, do MyBuffer:getBuffer()

local result = MyBuffer:getBuffer()

Module: https://create.roblox.com/store/asset/74638794833287/EZbuffer

1 Like

Just a brief rundown / extra info:

Read/Write types - bytes

  • i8 / u8 = 1 byte
  • i16 / u16 =2 bytes
  • i32 / u32 / f32 = 4 bytes
  • f64 = 8 bytes

Starter functions (Creates a new EZBufferInstance):

-EZBuffer.new(size)
Creates a new EZBufferInstance with said size

-EZBuffer.fromBuffer(existing)
Creates a new EZBufferInstance from pre-existing buffer

-EZBuffer.fromString(string)
Creates a new EZBufferInstance from a string


–EZBuffer:read(itype)
Reads data from a buffer.

–EZBuffer:readString(length)
Reads a string from a buffer

–EZBuffer:write(itype, data)
Writes data to the buffer.

–EZBuffer:writeString(str)
Writes a string to the buffer.

–EZBuffer:writeDynamic(itype, data)
Writes data to the buffer. Extends as needed

–EZBuffer:writeStringDynamic(str)
Writes a string to the buffer. Extends as needed

–EZBuffer:getBuffer()
Returns the current buffer.

–EZBuffer:position(newOffset)
Sets the position of the buffer. If no argument is provided, it returns the current position.

–EZBuffer:skip(bytes)
Skips the offset by the bytes

–EZBuffer:remaining()
Returns the amount of remaining bytes

–EZBuffer:extend(amount)
Extends the buffer by the amount of bytes added to the current scale.

–EZBuffer:edge()
Used to trim the edge of the buffer from the current offset.
(Not recommended unless you know what you are doing)

–EZBuffer:sedge()
Trims the buffer by removing trailing zero bytes (empty data)
(Not recommended unless you know what you are doing)

–EZBuffer:dump()
Dumps the current buffer info to the console.
(Recommended Debug Use Only: Very Heavy, Floods Console)

–EZBuffer:GetDump()
Dumps the current buffer info to the console.
(Recommended Debug Use Only: Returns the same contents that dump uses)

1 Like

Any videos of this in use please?

1 Like

Oh yeah, sure thing, once I ever have time to I will make a video explaining how to use this (and showcasing it’s use). Thank you for your feedback!

This is pretty convenient, I can’t lie, and I can definitely see someone using EZBuffer to learn more about buffers easily, but… This kind of negates their raw performance, which is, quite literally, the entire reason why developers use buffers in the first place.

More specifically, your dynamic methods allocate tons of memory and create a lot of garbage for the GC. Additionally, wrapping a native library like buffer into a metatable turns simple VM instructions into more complex chains that slow things down (for example, reading/writing from a buffer natively is a single instruction; in EZBuffer, it’s a metatable lookup + table lookup + multiple if/elseif/else’s + a table write). It might seem negligible, but it all adds up over time.

Nice work, but stick to normal buffers or tables if you need convenience. After all, Roblox engineers knew what they were doing when providing us with these wonderful native libraries :slight_smile:

1 Like

Thank you for your feedback, it means a lot for me, in terms of the dynamic writing, I do plan to fix it up a little later down the line by doing the same method vectors in C++ by growing more then the needed amount.

In terms of where I am using this, I’m using it to shrink build saves into a buffer, so far shrinking a matter of 158 blocks into 2.31 KiB