Why is my playerdata module not saving? (Datastore2)

So when writing my playerdata module which works with tables and datastore 2 it simply wouldn’t save. The datastore2 module is up-to-date, saveinstudio is enabled and this also doesn’t work on the actual roblox client. Weirdly, getting the table does work as one time it randomly did save, and i do not know why. Everytime after that the table was changed. When i print the changed table in the setdata function it is changed. The actual :Set() function of the datastore2 seems to be the problem.

The error “Not running script because past shutdown deadline” seems to be also coming from datastore2 and hangs my roblox studio everytime i try to stop the game. Besides that datastore prints “PLAYER left, saved DATA”

Weirdly the simulator example on the datastore2 api does work in the same game, working with the same module. Here’s the code:

local httpsService = game:GetService("HttpService")
local DataStore2 = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("DataStore2"))
DataStore2.Combine("DATA", "playerData")

local playerModule = {}
local defaultTable = {
	["xp"] = 0,
	["coins"] = 0,
	["crystals"] = 0,
	["inventory"] = {}, --item = {amount}
	["storage"] = {},
	["placedOnPlot"] = {}, --{item, pos, upgrades}
}

--[[
local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("plrData")
nicknameStore:RemoveAsync(388243015)
--]]

--defaultTable = httpsService:JSONEncode(defaultTable)

--Credit to Forummer, Thanks!
local function SetTableFromIndices(t, is, v) --table, table of indices, value.
	for i = 1, #is - 1 do
		if not t[is[i]] then t[is[i]] = {} end
		t = t[is[i]]
	end
	t[is[#is]] = v
end

function playerModule.GetDataTable(plr)
	local plrDataStore = DataStore2("playerData", plr)
	local plrDataTable = plrDataStore:GetTable(defaultTable)
	print(plrDataTable)
	return plrDataTable
end

function playerModule.GetData(plr, indices)
	local data = playerModule.GetDataTable(plr)
	local result = data
	for i, v in pairs(indices) do
		result = result[v]
		if result == nil then
			warn("No value exist for this index table:"..httpsService:JSONEncode(indices))
			result = nil
			break
		end
	end
	return result
end

function playerModule.SetData(plr, indices, setTo)
	local plrDataStore = DataStore2("playerData", plr)
	local data = playerModule.GetDataTable(plr)

	SetTableFromIndices(data, indices, setTo)
	print(data)

	plrDataStore:Set(data)
end

function playerModule.Increment(plr, indices, increment)
	local dataValue = playerModule.GetData(plr,indices) or 0
	
	if type(dataValue) ~= "number" and type(dataValue) == nil then
		error("The value for these indices is not a number:"..httpsService:JSONEncode(indices).."(Type:"..typeof(dataValue)..")")	
	end
	dataValue += increment
	
	playerModule.SetData(plr, indices, dataValue)
end

--[[
game.Players.PlayerRemoving:Connect(function(plr)
	local plrDataStore = DataStore2("playerData", plr)
	plrDataStore.Save()
end)

game:BindToClose(function()
	for i, v in pairs(game.Players:GetChildren()) do
		local plrDataStore = DataStore2("playerData", v)
		plrDataStore.Save()
	end
end)
--]]

return playerModule

I dont even think i have to json encode and decode it. I tried that and it stil doesn’t work.

@Kampfkarren can you maybe help me with this please?

Try Get other than GetTable…?

.

As i said, there’s nothing wrong with getting the table. I tried this and it obviously didn’t work. Gettable just checks if every index exists in the savedata than just checking if it is nil. Saving is where it goes wrong i think because that “Not running script because past shutdown deadline” seems to be the cause, although i have no idea how to fix that.

Edit: i found a bug within my own code, in the script in the pickaxe i found that i was saving everything within “backpack” instead of “inventory”. I fixed this and it still doesn’t save when leaving. Weirdly enough if you save the datastore with :Save() it does save. So the problem really only exists when you leave the game or the game closes.

1 Like

Update 2: i wipped up this quick script

local DataStore2 = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("DataStore2"))
DataStore2.Combine("DATA", "playerData")
game.Players.PlayerAdded:connect(function(plr)
	plr.Chatted:connect(function(msg)
		if msg then
			if msg:lower()=="save" then
				print("hi")
				local plrDataStore = DataStore2("playerData", plr)
				plrDataStore.Save(plrDataStore)
			end
		end
	end)
end)

thay when you say save it saves your data. Suprisingly, it does save! This confirms my suspicions about not saving specifically when leaving or the game closing.

Update 3: My suspicions are now fully confirmed. Datastore 2 does not save when leaving, even if it says EVERYWHERE that it does, (guess those are lies) so you have to make a script yourself that does that:

local DataStore2 = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("DataStore2"))
DataStore2.Combine("DATA", "playerData")

local closing = false

game.Players.PlayerAdded:Connect(function(plr)
	if closing then return end
	local plrDataStore = DataStore2("playerData", plr)
	plrDataStore.Save(plrDataStore)
end)

game:BindToClose(function()
    closing = true
	for i, v in pairs(game.Players) do
		local plrDataStore = DataStore2("playerData", v)
		plrDataStore.Save(plrDataStore)
	end
end)

I have never used Datastore2, but I think that this means when trying to save the save gets cached and it will ACTUALLY get saved when the player leaves.

It doesn’t save when the player leaves like i said

It does save, did you set saveInStudio to true?

I said it right here in the post, besides, the issue is fixed. Did you even read the post?

1 Like

DataStore2 normally saves, as an extra check I save the value every time it changes, DataStore2 won’t send the request until the player leaves.

I know that. But that is not what happens, even though everything says that it does. Otherwise i wouldn’t have this issue… And otherwise i couldn’t fix it… Please dont reply to this topic anymore, it is solved

1 Like

LAST UPDATE:
Sorry for the bump, but today i found the actual issue.
For some reason, when datastore2 is called via another modulescript it doesn’t save. I honestly didn’t even think of this once when debugging, but you just have to call datastore2 in a normal script. That’s it. Just because i used a modulescript that called datastore2 it somehow didn’t work. Here’s the script:

local DataStore2 = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("DataStore2"))
DataStore2.Combine("DATA", "playerData")

game.Players.PlayerAdded:Connect(function(plr)
        --bruh
	local plrDataStore = DataStore2("playerData", plr)
end)

In other words:

--We have to do this outside of the modulescript so that datastore2 saves properly
local plrDataStore = DataStore2("playerData", plr)