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

Any better way of datastoring folders??

Asked by 3 years ago
Edited 3 years ago

So, what I am trying to do is store data for the folder. Whenever a player is exiting the game, the script will save his/her Data Folder. This script is a Server script and is the Child of ServerScriptService. The script I have written is:

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")

game.Players.PlayerRemoving:Connect(function(player)
    local Owned_Amians = player.PlayerGui.Owned_Amian

    for tries = 1, 10, 1 do
        local success, errormessage = pcall(function()
            PlayerAmianData:UpdateAsync(player.UserID, Owned_Amians)
        end)
        if success then
            break
        else
            PlayerAmianData:SetAsync(player.Name.."_"..player.UserID, Owned_Amians)
            break
        end
    end
end)

But my script doesn't seem to work properly for datastoring a folder and it's descendants. Is there any better way of doing it?? Thanks in advance!!

2 answers

Log in to vote
1
Answered by
Elyzzia 1294 Moderation Voter
3 years ago

for one, DataStores can only store strings, numbers, booleans, and tables which contain elements of the aforementioned types

to save instances, or any roblox datatype, really, you have to serialize them, which means to convert them to a more basic format

two, UpdateAsync expects a callback which returns the data you want it to save, not just the data

if it did it'd literally just be SetAsync 2

-- inconsistent casing is kind of bleh but it's not a massive deal

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")

game.Players.PlayerRemoving:Connect(function(player)
    local Owned_Amians = player.PlayerGui.Owned_Amian

    local dataToSave = {}
    for _, child in pairs(Owned_Amians) do
        -- do something idk how you're saving your data
    end

    local success, errormessage
    for tries = 1, 10, 1 do
        success, errormessage = pcall(function()
          PlayerAmianData:SetAsync(player.UserID, Owned_Amians) -- no reason to use UpdateAsync when the old data doesn't matter in the slightest
        end)
        if success then
            break
        else -- what's the point of making a system that tries to save your data several times if it's just going to break on the first iteration, no matter what
            warn("Data failed to save: \n" .. errormessage .. "\nRetrying...") -- \n is a new line, it just makes it a bit nicer to read
        end
    end
    if not success then
        warn("Data failed to save!")
    else
        warn("Data saved successfully.")
    end
end)

idk how your amians thingy is organized but. please please please for the love of god don't just do table.insert(dataToSave, child) and expect it to work, you actually have to convert the data into tables, strings, numbers, and booleans

you can put nested tables in a datastore btw, nested tables are just tables in other tables

so you could save something like this and it would work fine

{ {"hi", "hello"}, {"i love big chungus"} }

0
I understand now. Thx!! Shounak123 461 — 3y
0
Thanks again Shounak123 461 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

Thanks to Elyzzia!! Now I made a fully functional script:

wait(1)

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")


function update(plr)
    local Owned_Amians = plr.PlayerGUI.Owned_Amians

    local DataToSave = {}

    for Serial, Amian in pairs(Owned_Amians:GetChildren()) do
        local CurrentAmianData = {}

        table.insert(CurrentAmianData, 1, Amian.AmianName.Value)
        table.insert(CurrentAmianData, 2, Amian.Level.Value)
        table.insert(CurrentAmianData, 3, Amian.Data.Battle.CurrentEnergy.Value)
        table.insert(CurrentAmianData, 4, Amian.Data.Battle.CurrentHealth.Value)
        table.insert(CurrentAmianData, 5, Amian.Data.Battle.MaxEnergy.Value)
        table.insert(CurrentAmianData, 6, Amian.Data.Battle.MaxHealth.Value)
        table.insert(CurrentAmianData, 7, Amian.Data.Other.XP_needed.Value)
        table.insert(CurrentAmianData, 8, Amian.Data.Other.XP_current.Value)

        table.insert(CurrentAmianData, 9 , Amian.Moves.Move1.Value)
        table.insert(CurrentAmianData, 10, Amian.Moves.Move2.Value)
        table.insert(CurrentAmianData, 11, Amian.Moves.Move3.Value)
        table.insert(CurrentAmianData, 12, Amian.Moves.Move4.Value)

        table.insert(DataToSave, Serial, CurrentAmianData)
    end

    PlayerAmianData:SetAsync("Player_"..plr.UserID, DataToSave)
end

game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Wait()
    local Owned_Amians = player:WaitForChild("PlayerGui",10):WaitForChild("Owned_Amians",10)
    wait(1)
    local SavedData

    for tries = 1, 10, 1 do
        print("Getting Data".."["..tries.."]")
        wait(1)
        local success, errormessage = pcall(function()
            SavedData = PlayerAmianData:GetAsync("Player_"..player.UserID)
        end)
        if success then
            break
        else
            warn([[Could not fetch the data
            Retrying...
            ]])
        end
    end

    if SavedData ~= nil then
        for Serial, Amian in pairs(SavedData) do
            local CurrentAmian = game.ReplicatedStorage:WaitForChild("Amians",10):FindFirstChild(Amian[1])
            local CurrentTemplate = game.ReplicatedStorage.Mechanism.Templates.Amian_Template:Clone()

            CurrentTemplate.Name = CurrentAmian.Name
            CurrentTemplate.Data.Description.Value = CurrentAmian.Data.Description.Value
            CurrentTemplate.Data.Description.Value = CurrentAmian.Data.Description.Value
            CurrentTemplate.Body.Image = CurrentAmian.Body.Image

            CurrentTemplate.Data.AmianName.Value = Amian[1]
            CurrentTemplate.Data.Level.Value = Amian[2]
            CurrentTemplate.Data.Battle.CurrentEnergy.Value = Amian[3]
            CurrentTemplate.Data.Battle.CurrentHealth.Value = Amian[4]
            CurrentTemplate.Data.Battle.MaxEnergy.Value = Amian[5]
            CurrentTemplate.Data.Battle.MaxHealth.Value = Amian[6]
            CurrentTemplate.Data.Other.XP_needed.Value = Amian[7]
            CurrentTemplate.Data.Other.XP_current.Value = Amian[8]

            CurrentTemplate.Data.Moves.Move1.Value = Amian[ 9]
            CurrentTemplate.Data.Moves.Move2.Value = Amian[10]
            CurrentTemplate.Data.Moves.Move3.Value = Amian[11]
            CurrentTemplate.Data.Moves.Move4.Value = Amian[12]

            for i, v in pairs(CurrentAmian.Data.Types:GetChildren()) do
                if i == 2 then
                    local Type2 = CurrentTemplate.Data.Types.Type:Clone()
                    Type2.Value = v.Value
                    Type2.Parent = CurrentTemplate.Data.Types
                else
                    CurrentTemplate.Data.Types.Type.Value = v.Value
                end
            end

            CurrentTemplate.Parent = Owned_Amians --Executing it at last

        end
    else
        error("Error fetching the data")
    end

    player.PlayerGui.Intro.Start:FireClient()

    Owned_Amians.Changed:Connect(update(player))
end)

Answer this question