Hi. I’m not gonna explain every detail, but I have a system to save a ‘thing’ when they hover over a button and press a certain key, to a DataStore. But this would never work because it’s unnecessarily sending DataStore requests over and over, which ROBLOX doesn’t allow anyway because;
DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests
I want it so it adds this ‘thing’ to a table beforehand and have it save the table when they leave, but idrk how to do that. I thought about just making the table a variable, but then wouldn’t that just overwrite a player’s data with someone elses? idk I’m pretty crap at datastores and if anyone could help me that’d be great. Sorry for the bad explanation, I’m not comfortable with sharing what I’m working on exactly
function save.OnServerInvoke(player, thing)
local dict
local success, erm = pcall(function()
dict = fstore:GetAsync(player.UserId)
end)
if success then
local check1 = table.find(dict, button)
if not check1 then
dict[#dict + 1] = button
else
table.remove(dict, check1)
end
dataSave(player, dict)
return true
else
warn(erm)
return false
end
end
Hi, here is an example saving backpack items (In a table) When the player leaves. Note: Please test it in-game not studio.
local DataStoreService = game:GetService("DataStoreService")
local ToolsDataStore = DataStoreService:GetDataStore("ToolsDataStore")
function PlayerJoined(Player)
local Success, KeyInfo
local ToolData
if ToolData ~= nil then
for i, data in ipairs(ToolData) do
local PlayerOwnsTool = Player.Character:FindFirstChild(data[1]) or Player.Backpack:FindFirstChild(data[1])
if ShopItems:FindFirstChild(data[1]) and PlayerOwnsTool == nil then
local ItemClone = ShopItems[data[1]]:Clone()
ItemClone.Handle.Quantity.Value = data[2]
ItemClone.Parent = Player.Backpack
elseif ShopItems:FindFirstChild(data[1]) and PlayerOwnsTool then
PlayerOwnsTool.Handle.Quantity.Value = data[2]
end
end
end
end
function PlayerLeft(Player)
local ToolTable = {}
for i,v in pairs(Player.Backpack:GetChildren()) do
table.insert(ToolTable,{v.Name, v.Handle.Quantity.Value})
end
if ToolTable ~= nil then
local Success, errorMessage = pcall(function()
ToolsDataStore:SetAsync(Player.UserId, ToolTable)
end)
if errorMessage then
warn(errorMessage)
end
end
end
game.Players.PlayerAdded:Connect(PlayerJoined)
game.Players.PlayerRemoving:Connect(PlayerLeft)
This was a great solution, but in my case I’m trying to get something in the player’s PlayerGui when they leave, which doesn’t work in server scripts. I tried using remotefunctions. Any alternatives??
You could probably use a Remote event and fire it when the Player leaves (Get the Name of the GUI) and save it into a table.
When the Player joins check the name of gui in a serverstorage folder (ServerStorage folder contains all your guis in game) if there was then clone it into the PlayerGui.
You could do like you said, and basically save their data to a dictionary every time it updates with a remote event so that you can update it when they leave. It would just have to be a dictionary of dictionaries, i.e.
Actually, I’ve thought a better idea you don’t have to use RemoteEvents just loop through the PlayerGui when the Player leaves and save the name of the Gui in a table…
Also add a folder inside of ServerStorage called “GUIS” with all your GUIS in game
When the Player joins back loop through the table and check if there name of an instance in the table is equal to a child of the GUIS Folder (In ServerStorage) and if they are equal then Clone the GUI to the Player Gui.
It is possible, it’s not working for you probably because you aren’t using game:BindToClose()…
But you could use the Remote event way as I mentioned before.
Done, but now it’s giving me a new error. It is now telling me that this: 104: Cannot store Array in data store. Data stores can only accept valid UTF-8 characters.
local data = {}
local function dataSetup(player)
local data1
local success, erm = pcall(function()
data1 = fstore:GetAsync(player.UserId)
end)
if success then
if not data1 then
data[player.UserId] = {}
else
data[player.UserId] = data1
load:FireClient(player, data1)
end
end
end
local function onSave(player, button)
local playerfavs = data[player.UserId]
if playerfavs then
if playerfavs[button] then
playerfavs[button] = nil
else
playerfavs[#playerfavs + 1] = button
end
end
end
local function playerLeft(player)
local dict = {}
local playerfavs = data[player.UserId]
for i, button in ipairs(playerfavs) do
dict[i] = button
end
if playerfavs then
local success, erm = pcall(function()
fstore:SetAsync(player.UserId, dict)
end)
if not success then
print(erm)
end
data[player.UserId] = nil
end
end
save.OnServerEvent:Connect(onSave)
Players.PlayerAdded:Connect(dataSetup)
Players.PlayerRemoving:Connect(playerLeft)
game:BindToClose(function()
for i, v in pairs(Players:GetChildren()) do
playerLeft(v)
end
end)