Suphi's DataStore Module

the first error says your trying to do a for loop with the value nil i was not able to see any for loops in the code you shared

the second error says your trying to get userid from nil so that shows that player is set to nil

1 Like

Good day sir thanks for reply, btw I wasn’t trying to find a way to fix that error. I want to know why the printed data send a value of nil or 0. What I really mean is the one with “Resources”, “Stats”, and “Leaderstats” at the first line.

1 Like

I don’t see a problem with the code you shared

2 Likes

I think the same too however the.

function module.Add (player, key, amount)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	if dataStore == nil then return end
	if dataStore.State ~= true then return end
	dataStore.Value[key] += amount
	dataStore.Resources[key].Value = dataStore.Value[key]
end

won’t work if the data didn’t have any value in it, however I think that would work because if didn’t have any value or it is their first time then the template would give a value from the template script like

local template = {
Level = 0,
}

I also edited the function to check if there is a value of 0 or nil

function module.Add (player, key, amount)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	if dataStore == nil then return end
	if dataStore.State ~= true then return end
	if dataStore.Value[key] == 0 or nil then
		dataStore.Value[key] = amount
	else
		dataStore.Value[key] += amount
	end
	dataStore.Resources[key].Value = dataStore.Value[key]
end

But it still didn’t work, what I did to solve that problem from the time being is by using this function first to give a default value before changing any data.

function module.Set (player, key, value)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	if dataStore == nil then return end
	if dataStore.State ~= true then return end
	dataStore.Value[key] = value
	dataStore.Resources[key].Value = value
end

Btw what is the use of the value in a template if it didn’t put a default value sir?
also the print from PlayerAdded in template script didn’t print either.

game.Players.PlayerAdded:Connect(function(player)
	local dataStore = DataStoreModule.new("Player", player.UserId)
	if dataStore:Open(template) ~= "Success" then print(player.Name, "failed to open") --didn't print this
	elseif dataStore:Open(template) == "Success" then print(player.Name, "Datastore was opened") nor this one.
	print(dataStore.State)
end

Could you do

print(dataStore.Value)

And showing me what it prints?

1 Like

I already know what cause the problem and it is indeed the way I change and read data.
I will share it here cause other people might need it.

Old Code

function module.Set (player, key, value)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	if dataStore == nil then return end
	if dataStore.State ~= true then return end
	dataStore.Value[key] = value
	dataStore.leaderstats[key].Value = dataStore.Value[key]
end

Updated and fix

function module.Set (player, key, value)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	if dataStore == nil then return end
	if dataStore.State ~= true then return end
	dataStore.Value.leaderstats[key] = value   -- I didn't know that I should have added leaderstats cause I didn't understand what that Value mean at first.
	dataStore.leaderstats[key].Value = dataStore.Value.leaderstats[key]
end
2 Likes

I have never used any sort of data store for my games, but this resource seems to be done by a very skilled and trusted programmer (No like, seriously have any of you checked out his channel, he has tons of good tutorials).

So I will definitely give this over a try, instead of just using DataStore2.

2 Likes

exactly, who would join a discord server just to see the documentation

How to clone the item inside ArmorInventory.
btw I only inserted a name like Spag.

dataStore

---This is the current code
local DataStoreModule = require(game.ServerScriptService.DataStore)
local ManagerLeaderstats = require(game.ServerScriptService.Managers.LEADERSTATS)
local ManagerResources = require(game.ServerScriptService.Managers.RESOURCES)
local Remotes = game.ReplicatedStorage:WaitForChild("REvents")

local ArmorInventory = {}---For armors and weapons
local PillPocket = {} ---Pill storage
local ScrollPocket = {}---Scrolls
local Void_Ring = {}----Materials & Quest Items

local function StateChanged(state, dataStore)
	if state ~= true then return end
	for index, name in ArmorInventory do
		dataStore.ArmorInventory[name].Value = dataStore.Value.ArmorInventory[name]
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local dataStore = DataStoreModule.find("Player", player.UserId)
	local ArmorInventory = Instance.new("Folder")
	ArmorInventory.Name = "ArmorInventory"
	ArmorInventory.Parent = player

	-- Clone the children of ArmorInventory
	for _, child in pairs(dataStore.Value.ArmorInventory:GetChildren()) do
		child.Name:Clone().Parent = player.ArmorInventory
		print("Clone Success")
	end

	local dataStore = DataStoreModule.new("Player", player.UserId)
	dataStore.ArmorInventory = ArmorInventory
	dataStore.StateChanged:Connect(StateChanged)
end)

I also don’t know how to access data if it is like this
For example

	Example = {
		ExampleData1 ={
			Speeds = {
				Walk = 0,
				Hit = 0,
			}
		},
		ExampleData2 ={
		
		},
		ExampleData3 ={
		
		},
	},

How to access the data like Walk

Would using memory stores for things like skill-based matchmaking or global shopping hurt me because this module would need the most, if not all, of the memory store usage due to memory store limits?

If you have 1 session per player this module uses

1 out of the 100 memorystore requests per player

that means if you have 100 players in your game it would use 100 out of 10,000 requests

if you have 1,000 players in your game it would use 1,000 out of 100,000 requests

if you have 100,000 players in your game it would use 100,000 out of 10,000,000 requests

here you can see SDM in a live game


and based on the math we know that SDM can take up a max of 1% of your player memorystore request limits

so this means that your free to use 99 memorystore requests per minute per player for anything you like

also don’t forget you also gets 1000 requests by default even when you have 0 players

also you can see that a single memorystore can only have a total of 100,000 requests but this is not a problem for SDM because every session uses a separate memorystore so each memorystore only uses 1 request per minute so it will never hit the 100,000 max


for data usage SDM only saves a 36 character unique id inside the memorystore and when the session is closed it is removed from the memorystore so while the player is online it will use 36 out of 1024 bytes per player

if you have 1000 players online it will use 36,000 out of 1,024,000 bytes

so this means that you have 988 bytes that your free to use per player

also don’t forget you get 65,536 bytes even if you have 0 players

SDM does not need to worry about the 8 days before re-evaluation because the data is deleted as soon as the session is closed so when the player exits the game the data is instantly removed from the memorystore

here you can see SDM in a live game


and based on the math we know that SDM can take up a max of 3.515625% of your player memorystore data limit


Conclusion

SDM will use 1% of your requests and 3.515625% of your data

1 out of 100 requests per player per minute
36 bytes out of 1024 bytes per player

this leaves you with
99 requests per player per minute + 1000 requests per minute
988 bytes per player + 65,536 bytes

4 Likes

Well i might start using this as ProfileService doesn’t support global leaderboards, any idea on how to do it with this module? Is It possible? I wanna make a couple top 100 leadeboards, could anybody help?

1 Like

Ordered datastore would be correct way to make a leaderboard

You would save the value inside the players datastore + inside the ordereddatastore separately

2 Likes

Thank you for your response. One more question: does SDM module have GDPR compliance?

1 Like

you can set the associated userids like this

local dataStore = DataStoreModule.new("Name", "Key")
if dataStore:Open() ~= "Success" then error("Failed to open datastore") end
dataStore.UserIds  = {123456} -- set the associated userids

Suphi’s DataStore Module 1.3 is now live

added [any]: any to the datastore type

very small update to just supresses the warning when using --!strict when saving custom data into the datastore object

1 Like

I suggest adding generic types to the module so that we can have a type safe Value key when interacting with the module rather than using type any. Great job btw, best DS wrapper by far

1 Like

How do we properly ensure the session lock is closed on a datastore before teleporting a player to another place in the universe? In profile service, we have listentohopready which releases and removes session lock in which case we teleport to another place then. Do we simply destroy the datastore first and then teleport? Also what case does the state of a datastore go from the inintal true back to false? If it does, should we kick the player to prevent duping?

the Close and Destroy methods will always be considered successful even if we are not able to connect to Roblox servers

so you should simply teleport them and then destroy the session in the player removing event like you normally do

when the player enters the new place if the session was successfully closed the new place should be able to open the new session instantly if the previous place was not able to connect to Roblox servers and close the session then the session will timeout after (0 to 5) minutes and only once the session has timed out will the new place be able to open the new session

as a side note if the previous server fails to close the session it wont give up instantly it will try 3 times and if all 3 times fail it will give up


when you create the datastore object the state will start as false / closed after you use the open method the state will change to true / open if you then use the close method the state will go back to false / closed and if you use the destroy method the state will change to nil / destroyed once destroyed it will be locked and can not be used anymore you will need to use the new constructer to make a new datastore object

make sure to destroy when you no longer need the datastore object so you don’t have a memory leak


there has been reports that when teleporting a player the player removing event does not always fire i personally have not seen this but that’s what iv been told

and I was told that changing PlayerRemoving to ChildRemoved fixed the problem

New Release 1.3