Sera - Low-level schematized serialization library

Sera (Click for source code)

This is a Low-level schematized serialization library for Roblox for handling limited size dictionaries with primitive types. This library aims to do as few operations (table lookups, comparisons, etc.) as possible to achieve it’s result while staying a good-enough serialization library.

Sera’s intended purpose is to help with serialization schemas when handling high-efficiency game entity replication to clients. Note that this is not a module for beginners and you should at least know the basics of using the buffer class.

Perks:

  • Fast.
  • Efficient-enough representation of a dictionary inside a buffer.
  • Sera.Serialize, Sera.Push, Sera.DeltaSerialize and Sera.DeltaPush outputs can be combined inside a large buffer - Sera.Deserialize and Sera.DeltaDeserialize understand when an entry ends given a buffer and offset and returns a new offset for the developer to continue reading the buffer.
  • Sera.DeltaSerialize and Sera.DeltaPush treats a schema as an enumerator and serializes an incomplete dictionary with added (n + 1) bytes in the output where “n” is the number of fields present.

Limitations:

  • Schemas can only hold up to 255 fields in Sera and it’s going to stay that way - you may fork the project and easily change this for yourself.
  • Sera.Serialize and Sera.DeltaSerialize will fail if resulting buffer size is larger than the constant BIG_BUFFER_SIZE inside the Sera module - This value should be moderate, but within reason since that’s the memory Sera will take and never release during runtime.

Source Code (Single ModuleScript)
(Create a ModuleScript under ReplicatedStorage called Sera and paste the source code inside)

Longer Example Code

This is an experimental project - there will be no guarantees for backwards-compatibility on further updates

Short Example:


local Sera = require(game.ReplicatedStorage.Sera)

local Schema = Sera.Schema({
	Health = Sera.Int16,
	Position = Sera.Vector3,
	Name = Sera.String8,
})

local serialized, error_message = Sera.Serialize(Schema, {
    Health = 150,
    Position = Vector3.new(1001, 69, 0.1),
    Name = "loleris",
})

if error_message ~= nil then
    error(error_message)
end

local deserialized = Sera.Deserialize(Schema, serialized :: buffer)

print(`Serialized buffer size: {buffer.len(serialized :: buffer)} bytes`)
print(`Deserialized:`, deserialized)


:moneybag::moneybag::moneybag:
Consider donating R$ to the creator of Sera (Click here) if you find this resource helpful!

25 Likes

This module seems pretty helpful for decreasing the amount of data being replicated at once. However, it’s unclear to me why this would be preferable over the usual table. What are some specific use cases that you’ve found Sera useful for? When should we use this and when should we not?

1 Like

Roblox games have a modest budget for networking and data storage, so serialization only shines for projects with a lot of data throughput.

Serialization doesn’t make less efficient systems obsolete.

3 Likes

It would be interesting to see how the performance of this paired with remote events differs from popular networking resources such as Bytenet or Warp. Do you think this could be faster or possibly result in lower bandwidth due to its simplicity?

1 Like

I’ve been making individual benchmarks like creating new buffer objects VS running the serialization code again while making this library. I’m afraid of making any wrong claims, but it feels like, generally speaking, the buffer library seems faster than a handful of table lookups in most cases.

Your average game wouldn’t even benefit much from a network library with serialization, so I thought why not make a schema serdes library that doesn’t try to be solve-all library for everyone but a high-speed serdes utility where it still requires the developer to work with buffers.

This module is my swing at what I understand as “hella fast” in terms of Roblox lua, but I haven’t been working with buffers for that long so I might be wrong :stuck_out_tongue:

Regardless, my goal for this project is to create a super performant serializer that does not bother with miniscule compression gains.

5 Likes