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

I want to switch from SetAsync to UpdateAsync (or better save system) please help?

Asked by 4 years ago
Edited 4 years ago

I want to switch to UpdateAsync so players dont keep losing their data, but im not sure how to edit my code for it please help.

local Data = game:GetService('DataStoreService'):GetDataStore('rdata2')
local module = require(game.ServerScriptService.module)
local prefix = 'user_' -- example prefix
local rep = game:GetService("ReplicatedStorage")
local e = rep.events.save

game.Players.PlayerAdded:connect(function(player)

    local data = Instance.new('Configuration')
        data.Name = "Data"
        data.Parent = player

local strength = Instance.new('NumberValue')
        strength.Name = "strength"
       strength.Parent = data

local strengthxp = Instance.new('NumberValue')
        strengthxp.Name = "strengthxp"
       strengthxp.Parent = data

local ability = Instance.new('StringValue')
        ability.Name = "ability"
       ability.Parent = data

local style = Instance.new('StringValue')
        style.Name = "style"
       style.Parent = data

local stamina = Instance.new('NumberValue')
        stamina.Name = "stamina"
       stamina.Parent = data

local staminaxp = Instance.new('NumberValue')
        staminaxp.Name = "staminaxp"
       staminaxp.Parent = data

local defense = Instance.new('NumberValue')
        defense.Name = "defense"
        defense.Parent = data

local defensexp = Instance.new('NumberValue')
        defensexp.Name = "defensexp"
        defensexp.Parent = data

local cash = Instance.new('NumberValue')
        cash.Name = "cash"
        cash.Parent = data


 local race = Instance.new('StringValue')
        race.Name = "race"
        race.Parent = data

local nowstamina = Instance.new('NumberValue')
        nowstamina.Name = "nowstamina"
        nowstamina.Parent = data

local doingquest = Instance.new('BoolValue')
        doingquest.Name = "doingquest"
        doingquest.Parent = data

local CanRun = Instance.new('BoolValue')
        CanRun.Name = "CanRun"
        CanRun.Parent = data
        CanRun.Value = true

local CanUseSkill = Instance.new('BoolValue')
        CanUseSkill.Name = "CanUseSkill"
        CanUseSkill.Parent = data
        CanUseSkill.Value = true

local ate = Instance.new('NumberValue')
        ate.Name = "ate"
        ate.Parent = data

local killed = Instance.new('NumberValue')
        killed.Name = "killed"
        killed.Parent = data


    local pData = Data:GetAsync(prefix  .. tostring(player.UserId))

    if pData then
        strength.Value = pData[1] or 1
        strengthxp.Value = pData[2] or 0
        race.Value = pData[3] or "human"
        defense.Value = pData[4]or 1
        defensexp.Value = pData[5]or 0
        ability.Value = pData[6]or ""
        style.Value = pData[7]or ""
        stamina.Value = pData[8]or 1
        staminaxp.Value = pData[9]or 0
        ate.Value = pData[10]or 0
        cash.Value = pData[11]or 0
        killed.Value = pData[12]or 0
   else
    strength.Value = 1
    strengthxp.Value = 0
        race.Value = "human"
        defense.Value = 1
        defensexp.Value = 0
        ability.Value = ""
        style.Value = ""
        stamina.Value = 1
        staminaxp.Value = 0
        ate.Value = 0
        cash.Value = 0
        killed.Value = 0

   end


coroutine.resume(coroutine.create(function()
    while wait(120) do
    Data:SetAsync(prefix  .. tostring(player.UserId), {
strength.Value,
strengthxp.Value,
race.Value,
defense.Value,
defensexp.Value,
ability.Value,
style.Value,
stamina.Value,
staminaxp.Value,
ate.Value,
killed.Value,
        })



end
end))

e.OnServerInvoke = function(Player)
    local d = Player.Data
    local strength = d.strength
    local strengthxp = d.strengthxp
    local defense = d.defense
    local defensexp = d.defensexp
    local ability = d.ability
    local style = d.style
    local race = d.race
    local ate = d.ate
local killed = d.killed
    Data:SetAsync(prefix  .. tostring(Player.UserId), {
strength.Value,
strengthxp.Value,
race.Value,
defense.Value,
defensexp.Value,
ability.Value,
style.Value,
stamina.Value,
staminaxp.Value,
ate.Value,
killed.Value,
        })

    return "saved"
    end

game.Players.PlayerRemoving:connect(function(Player)
    local d = Player.Data
    local strength = d.strength
    local strengthxp = d.strengthxp
    local defense = d.defense
    local defensexp = d.defensexp
    local ability = d.ability
    local style = d.style
    local race = d.race
    local ate = d.ate
local killed = d.killed
    Data:SetAsync(prefix  .. tostring(Player.UserId), {
strength.Value,
strengthxp.Value,
race.Value,
defense.Value,
defensexp.Value, 
ability.Value,
style.Value,
stamina.Value,
staminaxp.Value,
ate.Value,
killed.Value,
    })
end)


---------------------------------------------------------------------------------------------------------------------------------


end)

1 answer

Log in to vote
6
Answered by
royaltoe 5144 Moderation Voter Community Moderator
4 years ago
Edited 4 years ago

What you can do to prevent data loss is keep track of your data version history.

Have a variable in your playerData table called Version. Every time you update the player's data, add one to the version. This way you'll know what version you're saving over so you don't overwrite a newer version.

First, make sure you have a table that contains the default data - data you want to save for the player when they're new to the game. Notice how there's a variable named version. This is the version of the data you're saving. Since this is new data, the defaultData`s version variable is 0.

defaultData = {
    --TODO: Insert default player data items such as strength, killed, etc. 
    Version = 0
}

Next, let's write a function called updateData() Right now all it has are three variables:

  • saveKey which is the player's datastore key.
  • d which is where the player's in data is in game.
  • playerData`, which is the player's data in a table.
function updateData()
    local saveKey = prefix  .. tostring(Player.UserId)
    local d = Player.Data

    --put the player's in game data in a table to save to the datatstore
    local playerData = {
        d.strength.Value,
        d.strengthxp.Value,
        d.defense.Value,
        d.defensexp.Value,
        d.ability.Value,
        d.style.Value,
        d.race.Value,
        d.ate.Value,
        d.killed.Value
        d.Version.Value
    }

    --TODO: UpdateAsync() will go here, we'll talk about that in the next step
end

Now let's update the playerData to the datastore with UpdateAsync.

The code below will go where the TODO: comment in the previous step is, but I'm just writing it here because it's easier to read.

What the code is doing is checking if the data is valid (if the old data's version is the current version - 1), if it is, we'll update the data, if it's not, then the data isn't valid so we return nil and don't update

    Data:UpdateAsync(saveKey, function(oldData)
        --if the previous data doesn't exist, use the defaultData this is our first time saving the player's data, otherwise use the old data
        local previousData = oldData or defaultData

        --check to see if the data is valid
        if playerData.Version == previousData.Version then
            playerData.Version= playerData.Version+ 1
            return playerData
        else
            return nil
        end
    end)

Tell me if you have any more questions

Ad

Answer this question