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
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
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.
: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!
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)
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