|
Hello,
I'm having a hard time properly getting my Bool Values to save/load with the Data Store. I have Bool Values in the StarterGui that will turn the Value to true when purchased from the Shop:
hasGun = true
hasSword = true
etc.
Question: How do I get these to save and reload when the Data Store fires?
Here is my Data Store script that has been worked over several times now:
game.Players.ChildAdded:connect(function(newPlayer)
--Leaderstats Script, IntValues added for Cash, EXP, etc.
stats.Parent = newPlayer
local datastore = game:GetService("DataStoreService"):GetDataStore(newPlayer.Name.."Stats")
local stats = stats:GetChildren()
for i = 1, #stats do
stats[i].Value = datastore:GetAsync(stats[i].Name)
print("stat number "..i.." has been found")
end
local save_interval = 60 * 2 -- every 2 minutes
wait(save_interval)
while newPlayer.Parent do
local stats = newPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been auto-saved")
end
wait(save_interval)
end
end)
game.Players.ChildRemoved:connect(function(oldPlayer)
local datastore = game:GetService("DataStoreService"):GetDataStore(oldPlayer.Name.."Stats")
local stats = oldPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been saved")
end
end)
I've looked at wikis, forums, youtube, I'm just having a really hard time with it, and would appreciate some help. =/ Thanks in advance. |
|
AjastraJoin Date: 2017-08-01 Post Count: 1461 |
Why bother having a separate DataStore for each player, rather than just having a separate key? Also, if a player changes their name, they will not be able to load their data. Use the unique identifier, player.UserId.
Additionally, you should be packing all player data into a single table to be saved into the key, not a DataStore:SetAsync() call for every value.
|
|
|
Good sir...how do I do this? XD; I have found no tutorials for this, or how to get the bool values to save properly. |
|
|
Ever heard of table? You can store stuff in them. https://www.youtube.com/watch?v=dH6FkAIyHqU Table can be converted to JSON with the ########### to be stored in DataStore http://wiki.roblox.com/index.php?title=API:Class/HttpService |
|
AjastraJoin Date: 2017-08-01 Post Count: 1461 |
You can use this tutorial:
http://wiki.roblox.com/index.php?title=Saving_Player_Data
You don't need to JSON encode a table yourself to save it.
|
|
|
the real reason to json encode a table is so you can save arrays honestly
|
|
|
Is this the section I would rename with my boolValues?
function PlayerStatManager:ChangeStat(player, statName, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
Would it be:
function PlayerStatManager:ChangeStat(player, HasGun, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
function PlayerStatManager:ChangeStat(player, HasSword, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
? This still confuses. |
|
|
@_@ Roblox...why can't the script be as easy as adding:
--DataStore Setup
Load:player.Backpack
--PlayerRemoving
Save:player.Backpack
I don't understand why it has to be so roundabout. x_x; |
|
complexoJoin Date: 2009-01-07 Post Count: 1547 |
Hang on, you can't save a regular Roblox table?
How do I convert to and from a saveable format then? |
|
|
Okay, I've added some lines to my data store script, marked by the "ADDED BELOW/ADDED ABOVE" comments. It doesn't work. :D its frustrating, I see the boolValue is marked True after the purchase, I see its been added to Starter Gear and Backpack, but after the character dies, it remains in Starter Gear and disappears from Backpack.
How can I fix that?
stats.Parent = newPlayer
local datastore = game:GetService("DataStoreService"):GetDataStore(newPlayer.Name.."Stats")
local stats = stats:GetChildren()
for i = 1, #stats do
stats[i].Value = datastore:GetAsync(stats[i].Name)
print("stat number "..i.." has been found")
end
local save_interval = 60 * 2 -- every 2 minutes
wait(save_interval)
while newPlayer.Parent do
local stats = newPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been auto-saved")
end
wait(save_interval)
end
--ADDED BELOW
newPlayer.PlayerGui:WaitForChild("HasM9").Changed:Connect(function()
if newPlayer.PlayerGui.HasM9.Value == true then
local DataStorem9 = game:GetService("DataStoreService"):GetDataStore("HasM9")
game.ServerStorage.ToolStorage.M9:Clone().Parent = newPlayer.Backpack
DataStorem9:SetAsync(newPlayer.userId, true)
end
end)
--ADDED ABOVE
end)
game.Players.ChildRemoved:connect(function(oldPlayer)
local datastore = game:GetService("DataStoreService"):GetDataStore(oldPlayer.Name.."Stats")
local stats = oldPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been saved")
end
--ADDED BELOW
oldPlayer.PlayerGui:WaitForChild("HasM9").Changed:Connect(function()
if oldPlayer.PlayerGui.HasM9.Value == true then
local DataStorem9 = game:GetService("DataStoreService"):GetDataStore("HasM9")
DataStorem9:SetAsync(oldPlayer.userId, true)
end
end)
--ADDED ABOVE
end)
|
|
|
AjastraJoin Date: 2017-08-01 Post Count: 1461 |
You're still saving each data item in a separate key, why though? You should be saving all player data into a table.
You should save all player data into a single key as a table.
|
|
|
Thanks for the response, what would that look like? |
|
AjastraJoin Date: 2017-08-01 Post Count: 1461 |
|
|
|
Ajastra -
Is this the section I would rename with my boolValues?
function PlayerStatManager:ChangeStat(player, statName, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
Would it be:
function PlayerStatManager:ChangeStat(player, HasGun, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
function PlayerStatManager:ChangeStat(player, HasSword, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end |
|
|
you're over-complicating it |
|
|
graveyardposse - I'm sure you're right. If you have the correct answer, thats not a wiki link, I would be very appreciative. x.x; |
|
AjastraJoin Date: 2017-08-01 Post Count: 1461 |
If you're using value objects the principle of using a table is the same, perhaps you should review table basics to understand how to do this.
|
|
|
here's a very basic datastore example: (pseudo code)
--Script
local ds = game:GetService'DataStoreService':GetDataStore'Stats';
game:GetService'Players'.PlayerAdded:Connect(function(player)
--create storage for reading and writing to the stats
local t = ds:GetAsync(tostring(player.UserId)); --temp variable to limit requests
player.Kills = t.Kills or 0;
player.Wipeouts = t.Wipeouts or 0;
end); |
|
|
graveyardposse - Thanks for the response. The stats save just fine in my datastore script. :) Its the BoolValues for the weapons that don't. |
|
|
save a table inside the stat table called Tools and then save the tool names inside that table and load them from ServerStorage when the character is added |
|
|
graveyardposse & Ajasra - Like this?
stats.Parent = newPlayer
local datastore = game:GetService("DataStoreService"):GetDataStore(newPlayer.Name.."Stats")
local tools = game.ServerStorage.ToolStorage;-- ADDED FOR TOOLS
local stats = stats:GetChildren()
for i = 1, #stats do
stats[i].Value = datastore:GetAsync(stats[i].Name)
print("stat number "..i.." has been found")
end
local save_interval = 60 * 2 -- every 2 minutes
wait(save_interval)
while newPlayer.Parent do
local stats = newPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been auto-saved")
end
local data = false
print("DataStoreBackSave1")
newPlayer.CharacterAdded:connect(function(char) -- this will run everytime the Player's Character has been added in workspace.
if not data then
data = datastore:GetAsync(newPlayer.UserId);
end
if data then
--If it does, loop and clone respective tools.
for _,v in next,data do
local tool = tools:FindFirstChild(v);
if tool then
tool:Clone().Parent = newPlayer.Backpack;
end
end
end
end)
end
wait(save_interval)
end)
game.Players.ChildRemoved:connect(function(oldPlayer)
local datastore = game:GetService("DataStoreService"):GetDataStore(oldPlayer.Name.."Stats")
local stats = oldPlayer.leaderstats:GetChildren()
for i = 1, #stats do
datastore:SetAsync(stats[i].Name, stats[i].Value)
print("stat number "..i.." has been saved")
--Make a table to hold all the data
local toolList = {};
--Iterate through the backpack and fill the table in
for _,v in next,oldPlayer.Backpack:GetChildren() do
--Make sure it's actually a tool
if v:IsA("Tool") or v:IsA("HopperBin") then
toolList[#toolList+1] = v.Name;
end
end
--Save the table
datastore:SetAsync(oldPlayer.UserId,toolList);
end
print("DataStoreBackSave2")
end)
|
|
|
|
|