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

Datastore is throwing an error that doesn't make sense to me?

Asked by
R_alatch 394 Moderation Voter
6 years ago

I have a datastore where it's supposed to save a StringValue inside the player named "CurrentPet". The problem is, it's giving the error "ServerScriptService.Leaderboard:11: bad argument #3 to 'Value' (string expected, got nil)" and I don't know why. Any help is appreciated, thanks!

local dss = game:GetService("DataStoreService"):GetDataStore("PetData")

game:GetService("Players").PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        local currentpet = Instance.new("StringValue", player)
        currentpet.Name = "CurrentPet"

        local stats = dss:GetAsync(player.UserId)

        if stats then
            currentpet.Value = stats[1]
        else
            local savestat = currentpet.Value
            dss:SetAsync(player.UserId, savestat)
        end
    end)
end)

game:GetService("Players").PlayerRemoving:Connect(function(player)
    local savestat = player.CurrentPet.Value
    dss:SetAsync(player.UserId, savestat)
end)

2 answers

Log in to vote
0
Answered by 6 years ago

This is because when a datastore key is blank, it returns NO VALUE. Not a nil or false value, it is like doing this

function blank()
    return
end

To make an easy check, we can use typeof. It returns if the value is a string, a number, an instance, etc. Here is how you could do this.

local dss = game:GetService("DataStoreService"):GetDataStore("PetData")

game:GetService("Players").PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        local currentpet = Instance.new("StringValue", player)
        currentpet.Name = "CurrentPet"

        local stats = dss:GetAsync(player.UserId)

        if typeof(stats) == typeof({}) --[[to get a value of what it would return if it was a table]] then

            currentpet.Value = stats[1]
        else
            local savestat = currentpet.Value
            dss:SetAsync(player.UserId, savestat)
        end
    end)
end)

game:GetService("Players").PlayerRemoving:Connect(function(player)
    local savestat = player.CurrentPet.Value
    dss:SetAsync(player.UserId, savestat)
end)

Also, you should use BindToClose to stop the server from shutting down for some time. The max is 30 seconds. So what I'd do is this

function wait30sec()
    local waited = wait(10)
    warn('Warning:'..30 - waited..' more seconds until the server will close.')
    local waited = wait(10) + waited
    warn('Warning:'..30 - waited..' more seconds until the server will close.')
    local waited = wait(5) + waited
    warn('Warning:'..30 - waited..'more seconds until the server will close!')
    wait(30 - waited - .1)
    error('Server cannot handle extending server lifetime. Closing server...')
end
game:BindToClose(wait30sec)

so your script can do all the data store stuff and have the events and stuff fire if you were the last person in the game. BindToClose just allows you to do action before the server shuts down, and the server politely gives us time (max:30 seconds) to do whatever actions we need to do before it shuts down.

Hope this helps!

Ad
Log in to vote
0
Answered by 6 years ago

The error meant that on line 11 the .Value was expected to be a string, instead, you gave it something else.

Here is a simple example:

local string = Instance.new('StringValue')
string.Parent = plr -- imagine we have plr already
string.Value = hello

this would error because on line 3 hello is just hello. You need "Hello" instead. here is the proper way;

local string = Instance.new('StringValue')
string.Parent = plr -- imagine we have plr already
string.Value = "hello"

Right now stats is a variable, but this variable isn't something like local stats = "Hi"

So right now you are giving the string value a game service. PlayerId in this case. So you should change it to something you want.

Simply your pets should have names, and it should have another string value in the player called CurrentPet.

The new CurrentPet value should be equal to the current pet inside the player.

Answer this question