After testing it for months in a live setting and ironing out the few issues that appeared after pushing this system to the extreme, I am comfortable releasing it to the public. No-frills serialization and deserialization of Instances (targeting ones creatable by F3X), with the option to easily add more through the creation of new Types.
There are only three functions provided by the module:
Serialize({Instance, Instance, Instance}): DataString
Deserialize(DataString or BitBuffer): {Instance, Instance, Instance}
GetEpochNumberFromData(DataString): BufferEpoch, Buffer
Serialize and Deserialize are self-explanatory, and take the data given and perform the inverse of each other. GetEpochNumberFromData is a way to get the Epoch number, which can be used to determine which version of this module to use in case there are multiple versions of data present. It also returns the Buffer, which can be directly passed to the Deserialize function in place of the data string to prevent it from being decoded from Base91 twice.
Base91 encoding is used as it is the highest base that is datastore compatible, along with waits being implemented at certain parts of the code to prevent threads from yielding when deserializing multiple millions of instances.
Project GitHub w/ default Rojo setup:
Example of a game that uses this (full map saving system):
Utilizes rstk’s BitBuffer module:
I am considering switching this to using the Buffer primitive in the future, however, this code was written long before that was released, and in my use cases, parenting instances and replicating them takes much much longer than deserialization does. Parallelization where possible is also under consideration, but for the same reasons, I never needed to make this change.
TODO: add benchmarks to post