I want to save Exp,lvl,id,upgrades for weapons but i don't think normal datastore can do it

I want to create a datastore system to save how much xp does a weapon have, lvl, it’s initial id, upgrades (strings)

But idk how to do so, if i tried to use tables, saving the data of 200 weapon would cause dataloss, so it’s not possible to do so

Embed things like colons to separate parts of the table and then use String.Split when fetching the data. Ill send an example script.

example:

Datastore:SetAsync("yourkey", Weaponid..":"..weaponslevel..":".."CustomID="..customid)

Then you could decode by doing:

local data = Datastore:GetAsync("yourkey")
if data ~= nil then
   local splitdata = string.split(data, ":")
   for i, arg in pairs(splitdata) do
         if i == 1 then
                --data is the waponid
         elseif string.match(arg, "CustomID")
               --data is the CustomID and you can further split it using the "=" to find the value
         end
   end
end

As well as mentioned

which you can use with the method I showed for a very long encode. Here is the article if you wish to read it: Data Stores | Roblox Creator Documentation

1 Like

Why would it cause dataloss?
You can store 4,194,304b per key, that is 20971.52b per weapon!

Worst case scenario you would have to split weapons into multiple “pages” in the datastore. (or serialize and deserialize the data)

I didn’t thought of doing this, it’s great!

Do u mean 4Million Byte? Like writing a number or a character 4million times?

4mb, a little more than 4 million bytes.

So yes ~4 million characters, after your data has been converted to JSON that is.

Numbers are generally more than a byte. In Roblox Lua a number is 8 bytes. Letters are generally one byte, plus a small header to tell you how long the string is. That’s still a lot of storage space though. Four million letters or about a million numbers.

Data Limits of datastores


Datastores store data as a string using :JSONEncode().

So a number is stored as "123456789123456.789123456789" (30 bytes)
instead of 11001100 00000110 00100111 11000001 10000100 01001000 00111011 01000010 (8 bytes).

You could use something like BitBuffer to turn /\ that into something like "1'.r,L}>?F" (12 bytes), not quite 8 bytes but much better than 30!

1 Like

idk how to use BitBuffer, so i’ll just use regular numbers ig

They also have the string.pack function now for the same purpose. I didn’t know DataStores jsoned things that weren’t tables, good to know.

I don’t think OrderedDataStores are JSONed, but they don’t have a size limit (apart from the 8 byte number limit)

1 Like

Using BitBuffer is similar to what Va13Official said:

local toStore = BitBuffer.new()

-- depending on how much max exp a player can have, :WriteFloat32 might be enough
toStore:WriteFloat64(exp)

-- uint means that it cannot be negative
-- not negative + 16 bits means that the max level that can be stored like this is 65535
-- (also usually the level is calculated from the exp, so then you don't even have to save it)
toStore:WriteUInt(16, level)

-- not negative + 32 bits means that the id must be between 0 and 4,294,967,295
toStore:WriteUInt(32, id)

-- store the amount of upgrades (so we know how often to repeat :ReadString() when deserializing)
-- not negative + 8 means that it can have between 0 and 255 upgrades
toStore:WriteUInt(8, #upgrades)

for _,upgrade in ipairs(upgrades) do
    -- if you create a system to use numerical ids instead of strings you could save even more space
    toStore:WriteString(upgrade)
end

-- convert to serialized string that can be stored in a datastore
-- (128 would take less space, but certain characters like  would get turned into \u0003 which is 6 times as long!)
local forTheDatastore = toStore:ToBase91()

Then do the same but :Read... when loading it from the database (in order, otherwise you will get weird results)

well it won’t matter much anyways, i’m going to set a Max amount of weapons : 100, so it will take about 3KB only others data will be take about 1~5kb so it won’t have any effect ig