Hello there.
This is my first post, so please tell me if I posted it in the wrong spot or if I did anything wrong. Thanks!
I am trying to save tools with DataStore2. I’ve tried doing it myself, and I’ve also searched it up on YouTube to no avail.
Leaderstats Script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Votes = ReplicatedStorage:WaitForChild("VotesEnableDisable")
local DataStore2 = require(script.Parent.DataStore2)
DataStore2.Combine("DATA", "Wins", "Tools")
game:GetService("Players").PlayerAdded:Connect(function(Player)
local WinsStore = DataStore2("Wins", Player)
local ToolStore = DataStore2("Tools", Player)
local Tools = {}
game:GetService("ReplicatedStorage").PlayerAdded:FireAllClients()
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
ReplicatedStorage.PlayerDied:FireAllClients(Player.Name)
end)
end)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Value = WinsStore:Get(0)
Wins.Parent = Leaderstats
local InRound = Instance.new("BoolValue")
InRound.Name = "InRound"
InRound.Parent = Player
local Afk = Instance.new("BoolValue")
Afk.Name = "Afk"
Afk.Parent = Player
WinsStore:OnUpdate(function(NewWins)
Wins.Value = NewWins
end)
ToolStore:OnUpdate(function(NewTool)
table.insert(Tools, 1, NewTool.Name)
end)
Leaderstats.Parent = Player
for _, ToolName in pairs(Tools) do
ReplicatedStorage[ToolName]:Clone().Parent = Player.Backpack
end
end)
Shop Script:
local BuyEvent = game:GetService("ReplicatedStorage"):WaitForChild("BuyItem")
local DataStore2 = require(script.Parent.DataStore2)
BuyEvent.OnServerEvent:Connect(function(Player, ToolName)
local ToolStore = DataStore2("Tools", Player)
local Tool = game:GetService("ServerStorage"):FindFirstChild(ToolName)
if Tool then
if Player.leaderstats.Wins.Value >= script[ToolName].Value and not Player.StarterGear:FindFirstChild(ToolName) then
Tool:Clone().Parent = Player.StarterGear
Tool:Clone().Parent = Player.Backpack
ToolStore:Set(Tool, true)
end
else
Player:Kick("No exploiting please.")
end
end)
Thank you for your time.
You cannot save instances or userdata, they must be in a data type supported for saving. If your tools aren’t uniquely created tools by players (meaning that the tools were made by you or a developer in comparison to objects a player has made in game if they are able to do so) then you can just get the name of the tool then save it. When the player joins back, you check for their data and the names of the tools will be there then you find the tools again.
In cases where you have to save specially unique objects that aren’t made by you or a fellow developer, you have to get data on the instance in form that you can read. This is called serialization.
3 Likes
I don’t think you read the code carefully enough. I used “.Name”.
I see you are attempting to save with a Tool
instance? Here is what Tool is:
local Tool = game:GetService("ServerStorage"):FindFirstChild(ToolName)
Do you then perhaps mean: ToolStore:Set(ToolName, true)
?
1 Like
So I use
ToolStore:Set(Tool.Name, true)
and remove the “.Name” in
table.insert(Tools, 1, NewTool.Name)
?
1 Like
I am not familiar with Datastore2 so I am treating it similarly to Datastore normally but if that is just like a :SetAsync
method in real datastore then technically yes but you have a ToolName
parameter you can use instead of Tool.Name
.
1 Like
Okay, I will try that. Thanks.
1 Like
Nope. The script did not work.
Unfortunately, I don’t know how your code works otherwise as I focused on the second script but in general, you can’t save an Instance directly to datastore so while it may not have solved your problem, keep in mind to not save any userdata values like an Instance.
Well yes, as with all datastores you cannot datastore any instances, this includes tools. In short, strings, numbers and arrays(tables) are your primary data storing data types… Now to get a background of what’s going on here. First off, put DataStore2 up at the TOP OF YOUR SCRIPT bit of advice there, as it’s easier to get a read on it. print out every response from the OnServerEvent for me. So
BuyEvent.OnServerEvent:Connect(function(Player, ToolName)
local ToolStore = DataStore2("Tools", Player)
local Tool = game:GetService("ServerStorage"):FindFirstChild(ToolName)
if Tool then
print("Tool found!")
if Player.leaderstats.Wins.Value >= script[ToolName].Value and not Player.StarterGear:FindFirstChild(ToolName) then
Tool:Clone().Parent = Player.StarterGear
Tool:Clone().Parent = Player.Backpack
print("Setting "..tool.Name.." to the player's tool store")
ToolStore:Set(Tool.Name, true)
end
else
Player:Kick("No exploiting please.")
end
end)
ALSO
DataStore2’s documentation specifically says to use DataStore2.Combine() with every datastore. So pleaseuse that right after you require the DataStore2 Module.
DataStore2.Combine(“ToolStore”, “DATA”) along with all the other stores you are going to be using. Note that it also states that using over 2 can throttle the store so I would suggest using either one datastore and constructing the store in a table format.
Thanks! What should I change to the Leaderstats script?
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Votes = ReplicatedStorage:WaitForChild("VotesEnableDisable")
local DataStore2 = require(script.Parent.DataStore2)
DataStore2.Combine("DATA", "Wins", "Tools")
game:GetService("Players").PlayerAdded:Connect(function(Player)
local WinsStore = DataStore2("Wins", Player)
local ToolStore = DataStore2("Tools", Player)
local Tools = {}
game:GetService("ReplicatedStorage").PlayerAdded:FireAllClients()
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
ReplicatedStorage.PlayerDied:FireAllClients(Player.Name)
end)
end)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Value = WinsStore:Get(0)
Wins.Parent = Leaderstats
local InRound = Instance.new("BoolValue")
InRound.Name = "InRound"
InRound.Parent = Player
local Afk = Instance.new("BoolValue")
Afk.Name = "Afk"
Afk.Parent = Player
WinsStore:OnUpdate(function(NewWins)
Wins.Value = NewWins
end)
ToolStore:OnUpdate(function(NewTool)
table.insert(Tools, 1, NewTool.Name)
end)
Leaderstats.Parent = Player
for _, ToolName in pairs(Tools) do
ReplicatedStorage[ToolName]:Clone().Parent = Player.Backpack
end
end)
? What do you mean by that? I’m a bit confused.
What should I change to the script that saves and handles the OnUpdate function and creates the leaderboard?
Basically, what should I change to this?
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Votes = ReplicatedStorage:WaitForChild("VotesEnableDisable")
local DataStore2 = require(script.Parent.DataStore2)
DataStore2.Combine("DATA", "Wins", "Tools")
game:GetService("Players").PlayerAdded:Connect(function(Player)
local WinsStore = DataStore2("Wins", Player)
local ToolStore = DataStore2("Tools", Player)
local Tools = {}
game:GetService("ReplicatedStorage").PlayerAdded:FireAllClients()
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
ReplicatedStorage.PlayerDied:FireAllClients(Player.Name)
end)
end)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Value = WinsStore:Get(0)
Wins.Parent = Leaderstats
local InRound = Instance.new("BoolValue")
InRound.Name = "InRound"
InRound.Parent = Player
local Afk = Instance.new("BoolValue")
Afk.Name = "Afk"
Afk.Parent = Player
WinsStore:OnUpdate(function(NewWins)
Wins.Value = NewWins
end)
ToolStore:OnUpdate(function(NewTool)
table.insert(Tools, 1, NewTool.Name)
end)
Leaderstats.Parent = Player
for _, ToolName in pairs(Tools) do
ReplicatedStorage[ToolName]:Clone().Parent = Player.Backpack
end
end)
Well if you plan on adding more to your game I’m pretty sure 2 datastores will work but anything beyond that will have a risk of throttle. But if you’re asking what you should change the datastore to then I would suggest using a array(table) instead of a number. However it should work fine if you’re only using 2 but in the long run, if you want to add any more stores to the game it’s a risk I believe.
What do you mean? I’m pretty much asking what I should change to that script?
This:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Votes = ReplicatedStorage:WaitForChild("VotesEnableDisable")
local DataStore2 = require(script.Parent.DataStore2)
DataStore2.Combine("DATA", "Wins", "Tools")
game:GetService("Players").PlayerAdded:Connect(function(Player)
local WinsStore = DataStore2("Wins", Player)
local ToolStore = DataStore2("Tools", Player)
local Tools = {}
game:GetService("ReplicatedStorage").PlayerAdded:FireAllClients()
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
ReplicatedStorage.PlayerDied:FireAllClients(Player.Name)
end)
end)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Value = WinsStore:Get(0)
Wins.Parent = Leaderstats
local InRound = Instance.new("BoolValue")
InRound.Name = "InRound"
InRound.Parent = Player
local Afk = Instance.new("BoolValue")
Afk.Name = "Afk"
Afk.Parent = Player
WinsStore:OnUpdate(function(NewWins)
Wins.Value = NewWins
end)
ToolStore:OnUpdate(function(NewTool)
table.insert(Tools, 1, NewTool.Name)
end)
Leaderstats.Parent = Player
for _, ToolName in pairs(Tools) do
ReplicatedStorage[ToolName]:Clone().Parent = Player.Backpack
end
end)
Well I told you how to fix it. You should at least try to do it yourself before asking me.
I’ve tried it and it didn’t get fixed.
Leaderstats:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Votes = ReplicatedStorage:WaitForChild("VotesEnableDisable")
local DataStore2 = require(script.Parent.DataStore2)
DataStore2.Combine("DATA", "Wins", "Tools")
game:GetService("Players").PlayerAdded:Connect(function(Player)
local WinsStore = DataStore2("Wins", Player)
local ToolStore = DataStore2("Tools", Player)
local Tools = {}
game:GetService("ReplicatedStorage").PlayerAdded:FireAllClients()
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
ReplicatedStorage.PlayerDied:FireAllClients(Player.Name)
end)
end)
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
local Wins = Instance.new("IntValue")
Wins.Name = "Wins"
Wins.Value = WinsStore:Get(0)
Wins.Parent = Leaderstats
local InRound = Instance.new("BoolValue")
InRound.Name = "InRound"
InRound.Parent = Player
local Afk = Instance.new("BoolValue")
Afk.Name = "Afk"
Afk.Parent = Player
WinsStore:OnUpdate(function(NewWins)
Wins.Value = NewWins
end)
ToolStore:OnUpdate(function(ToolName)
table.insert(Tools, 1, ToolName)
end)
Leaderstats.Parent = Player
for _, ToolName in pairs(Tools) do
ReplicatedStorage[ToolName]:Clone().Parent = Player.Backpack
end
end)
Shop:
local DataStore2 = require(game:GetService("ServerScriptService"):WaitForChild("DataStore2"))
DataStore2.Combine("DATA", "Wins", "Tools")
local BuyEvent = game:GetService("ReplicatedStorage"):WaitForChild("BuyItem")
BuyEvent.OnServerEvent:Connect(function(Player, ToolName)
local ToolStore = DataStore2("Tools", Player)
local Tool = game:GetService("ServerStorage"):FindFirstChild(ToolName)
if Tool then
if Player.leaderstats.Wins.Value >= script[ToolName].Value and not Player.StarterGear:FindFirstChild(ToolName) then
Tool:Clone().Parent = Player.StarterGear
Tool:Clone().Parent = Player.Backpack
ToolStore:Set(ToolName, true)
end
else
Player:Kick("No exploiting please.")
end
end)
1 Like
That’s a bit weird why it’s not working and I don’t know.