Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How to save table in the Data Store Service?

Asked by
yoavstr 52
6 years ago
Edited 6 years ago

Please include the code which you are trying to use, so the community will be better-equipped to help you with your problem.

I've made a coin collection system (there are coins around the map and players pick them up and get money). I want to make that when a player joins the game only the coins that he haven't taken yet will be created. I thought of using tables and every time the player takes the coin it adds the coin number to the table, and when it generates the coins it will remove the already taken coins. My question is if it's the right way of doing it and if it is how can I save tables on data store service and then get it from there?

Data store script:

--Save data server script. Parent - Workspace 


--Get services.
local DSService = game:GetService('DataStoreService'):GetDataStore('asdsdafasdgsdfa')
local Workspace = game:GetService('Workspace')
local ReplicatedStorage = game:GetService('ReplicatedStorage')



--Setup remote functions
local startCollectedCoinsFunction = ReplicatedStorage:WaitForChild("StartCollectedCoinsFunction")--Holding the table of not taken coins, called when the player is  
local notTakenCoins = {}                                                                      --joining the game in antoher script


local endCollectedCoinsTable = Instance.new("RemoteFunction") --Holding the table of not taken coins, called when the player is leaving the game.
endCollectedCoinsTable.Parent = ReplicatedStorage
endCollectedCoinsTable.Name = "EndCollectedCoinsFunction"


--Player added
game.Players.PlayerAdded:connect(function(plr)

 local uniquekey = 'id-'..plr.userId

-- Define cash variables
 local leaderstats = Instance.new('IntValue', plr)
 local cash =  Instance.new('IntValue')
 leaderstats.Name = 'leaderstats'
 cash.Parent = leaderstats
 cash.Name = "Cash"
 cash.Value = 50

--Define coin variables
local numberOfCoins = 5 
for i = 1 , numberOfCoins do
    table.insert(notTakenCoins, i) --Inserts the number of coins to the table for a case that it's the first join of the player.
end


-- GetAsync
local GetSaved = DSService:GetAsync(uniquekey)
 if GetSaved then
  cash.Value = GetSaved[1]
  notTakenCoins = GetSaved[2]
 else
  DSService:SetAsync(uniquekey, {
    cash.Value,
    notTakenCoins
})
 end

--Send table
local function SendTable()--Sends the table of the taken coins (from the data store service) to the local script that clones the coin


    return notTakenCoins
end

startCollectedCoinsFunction.OnServerInvoke = SendTable


--Save data on player remove
game.Players.PlayerRemoving:connect(function(plr)
local uniquekey = 'id-'..plr.userId
DSService:SetAsync(uniquekey, {
    plr.leaderstats.Cash.Value,
    endCollectedCoinsTable:InvokeClient(plr) --Sends request to the local script for the current not taken coin 

})



end)
end)

Spawn coins script:

--Spawn coins local script. Parent - StartGui

--Get Services
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Workspace = game:GetService('Workspace')
local Players = game:GetService('Players')

--Setup remote functions
local endCollectedCoinsFunction = ReplicatedStorage:WaitForChild("EndCollectedCoinsFunction")

local startCollectedCoinsFunction = ReplicatedStorage:WaitForChild("StartCollectedCoinsFunction")


--Call for table
--local notTakenCoins = startCollectedCoinsFunction:InvokeServer()--Requests the table of non taken coins fron the server script


--Player Added 
local PlayerAddedEvent = ReplicatedStorage:WaitForChild('PlayerAddedEvent')


--Creates the coins folder
local flr = Instance.new("Folder", game.Workspace)
flr.Name = "Coins"


--Checks if the coinId is in the table
local function CheckCoins(table, coinId)

    for i, value in pairs(table) do

        if  value == coinId then

            return true

        end

    end 

    return false    
end


--Spawn the coins
local function SpawnCoins(pos, num)


    --Call CheckCoins function
    if CheckCoins(startCollectedCoinsFunction:InvokeServer(), num) then --The coin will be spawned only if it is in the table

        --Define variables.
            local coin = game.ReplicatedStorage.Coin:Clone()
            local coinId = Instance.new("IntValue")
            coin.Parent = flr
            coin.Anchored = true
            coin.Name = "Coin"..num
            coinId.Parent = coin
            coinId.Name = "CoinId"
            coinId.Value = num

        --Change the coins position
            coin.Position = pos
    end
end


--Calls the spawn function with the position
PlayerAddedEvent.OnClientEvent:Connect(function(plr)


        SpawnCoins(Vector3.new(-20.192,2.943,1.5),1)
        SpawnCoins(Vector3.new(-20.192,2.943,-5.5),2)
        SpawnCoins(Vector3.new(-20.192,2.943,-11.5),3)
        SpawnCoins(Vector3.new(-20.192,2.943,-17.5),4)
        SpawnCoins(Vector3.new(-20.192,2.943,-23.5),5)


end)



--Make a table of new not taken coins, called when the player is leaving the game.
local newNotTakenCoins = {}
local function AddCoinsToTable()
    for i,v in pairs(flr:GetChildren()) do
    table.insert(newNotTakenCoins, v.CoinId)
    end
    return newNotTakenCoins
end

endCollectedCoinsFunction.OnClientInvoke = AddCoinsToTable --Calls the function above
0
Dont't use table as your parameter. table is a keyword in roblox lua. If the error still persists then it means that on line 49 the first argument does not return a table. User#21908 42 — 6y
0
the function I am refering to is on line 28 User#21908 42 — 6y

1 answer

Log in to vote
0
Answered by 6 years ago

Since you did not include a script I will not write one for you. However there are a few tips I can give you to help you on your way. First: If I were you I would have all the coins in a single folder or model. Then create an IntValue inside of each coin which has the number you choose for labeling it. Whenever the player collects a coin remove it from that model/folder. Then when the time comes to save, loop through the folder/model with a for loop and something like: for i,v in pairs(coins:GetChildren()) do then: table.insert(exampleTable, v.CoinId.Value) or whatever you prefer. After doing all that save the table to the datastore via :SetAsync and then when the player rejoins get the data using :GetAsync. When the data has loaded loop through the table and the loop through the folder/model and check if a number in the datastore table matches the CoinId or whatever you call it. If it does then remove that coin from the folder/model. I hope this helps. If you have any additional questions you can comment below my answer and I will try to help. Have a great day scripting!

0
I tried to do what you advised me but I'm getting an error when I'm running it on local server with 2 players and coins doesn't spawn. the error: Players.Player2.PlayerGui.SpawnCoins:30: bad argument #1 to 'pairs' (table expected, got nil) btw I have added the scripts to the original question yoavstr 52 — 6y
Ad

Answer this question