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

My DataStore will not save?

Asked by 5 years ago

I want it so Pebbles and Value both save and load, but when I join the game the output says 20:40:40.729 - ServerScriptService.leaderstats:21: attempt to index local 'SavedData' (a number value)

local DataStore = game:GetService("DataStoreService"):GetDataStore('RockData12')

game.Players.PlayerAdded:Connect(function(player)
    local key = player.UserId
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = 'leaderstats'
    leaderstats.Parent = player

    local Pebbles = Instance.new("IntValue")
    Pebbles.Name = 'Pebbles'
    Pebbles.Value = 0
    Pebbles.Parent = leaderstats

    local level = Instance.new("IntValue")
    level.Name = 'Level'
    level.Value = 0
    level.Parent = leaderstats

    local SavedData = DataStore:GetAsync(key)
    if SavedData then
        player.leaderstats.Pebbles.Value = SavedData[1]
        player.leaderstats.Level.Value = SavedData[2]
    else
        local StartValues = {Pebbles.Value, level.Value}
        DataStore:SetAsync(key, StartValues)
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local key = player.UserId
    local CurrentValue = {player.leaderstats.Pebbles.Value}
    local LevelValue = {player.leaderstats.Level.Value}
    DataStore:SetAsync(key, CurrentValue[1], LevelValue[2])
end)

game:BindToClose(function()
    for i,v in pairs(game.Players:GetPlayers()) do
        if v then
        v:Kick()
    end
    end
    wait(3)
end)
0
Do not forget to accept my answer if it helps out. User#24403 69 — 5y

2 answers

Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

The reason for your error is because SavedData is not a table, rather a number. You are attempting to index that number. Lua does not support indexing numbers. In your PlayerRemoving event listener you attempt to save more than one value. The third argument and so on will be discarded; only the second argument is saved. You should instead save a table. Instead of saving two individual tables, just store one table, specifically an array, like so:

DataStore:SetAsync(key, {
    player.leaderstats.Pebbles.Value,
    player.leaderstats.Level.Value
})

Think of arrays as mappings from 1...#array to arbitrary values. You can get the first element of the array with array[1], second element with array[2], and so on.

Example:

local arr = {"hello", "world"}
print(arr[1], arr[2]) --> hello    world

Index 1 in your case will be the pebbles value and index 2 is the level.

Now, your game:BindToClose() logic is not very great. You should read this tutorial on how to properly save your player's data.

Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

I'm going to supplement incapaxx's answer with the following code:

local DataStore = game:GetService("DataStoreService"):GetDataStore('RockData12')

game.Players.PlayerAdded:Connect(function(player)
    local key = player.UserId
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = 'leaderstats'
    leaderstats.Parent = player

    local Pebbles = Instance.new("IntValue")
    Pebbles.Name = 'Pebbles'
    Pebbles.Value = 0
    Pebbles.Parent = leaderstats

    local level = Instance.new("IntValue")
    level.Name = 'Level'
    level.Value = 0
    level.Parent = leaderstats

    local SavedData = DataStore:GetAsync(key) or 0
    if SavedData then
        player.leaderstats.Pebbles.Value = SavedData[1]
        player.leaderstats.Level.Value = SavedData[2]
    else
        local StartValues = {Pebbles.Value, level.Value}
        DataStore:SetAsync(key, StartValues)
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local key = player.UserId
    local CurrentValue = player.leaderstats.Pebbles.Value
    local LevelValue = player.leaderstats.Level.Value
    local SaveArray = {CurrentValue, LevelValue}
    DataStore:SetAsync(key, SaveArray)
end)
-- You can edit the BindToClose Function as needed from incapaxx's link
game:BindToClose(function()
    for i,v in pairs(game.Players:GetPlayers()) do
        if v then
            v:Kick()
        end
    end
    wait(3)
end)

I'm also just going to point out that when you wrote:

local LevelValue = {player.leaderstats.Level.Value}
DataStore:SetAsync(key, CurrentValue[1], LevelValue[2])

within the LevelValue Table, the placement of "player.leaderstats.Level.Value" is in the first position (thus it would be LevelValue[1] instead) However, since the arrays you provided are both only 1 variable long, they would cause an error when attempting to use setasync.

Answer this question