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

How do you store a collection of objects in a data store dictionary?

Asked by
Bisoph 5
6 years ago

I'm currently attempting to make an adventure game in Roblox; a one like Roblox Adventure 3: Rise of Nobeesi. I'm not really having problems (except trying to make a level fun) except for the DataStore. Previously, it was totally broken, because the thing didn't save/load-- but I fixed it. Unfortunately, there's still a glitch in saving. Loading works; but saving doesn't (i tested it by setting the data manually in the command bar). I found out that saving doesn't work because it can't store dictionaries inside the data store dictionary. How did Polyhex did it? Maybe he had to write like a billion items to check whether a certain Token was collected, but I don't want to do that; it's too complicated and long. How do I store a collection of objects in a DataStore dictionary, then?

For extra proof and comprehension, here is my DataStoreService module script:

local DataModule = {}

local DataStoreService = game:GetService('DataStoreService')
local playerData = DataStoreService:GetDataStore('PlayerData')
local sessionData = {}

local function retry(func)
    local s, data, tries = true, nil, 0
    repeat
        tries = tries + 1
        s, msg = pcall(function()
            data = func()
        end)

        if not s then wait(1) end
    until tries == 3 or s

    if not s then
        warn('Datastore failure: ' .. msg)
    end

    return s, data
end

local function setStats(player)
    local data = sessionData[player]
    local PlayerData = game.ReplicatedStorage.PlayerData[player.Name]
    data.stars = PlayerData.Stars.Value
    data.coins = PlayerData.Coins.Value
    data.weapons = PlayerData.Weapons:GetChildren()
    data.collectedStars = PlayerData.CollectedStars:GetChildren()
end

local function save(player)
    return retry(function()
        return playerData:SetAsync(player.UserId, sessionData[player])
    end)
end

local function load(player)
    return retry(function()
        return playerData:GetAsync(player.UserId)
    end)
end

local function autosave()
    while wait(30) do
        for player, data in pairs(sessionData) do
            setStats(player)
            save(player)
        end
    end
end

local function loadToGame(player)
    local data = sessionData[player]
    local PlayerData = game.ReplicatedStorage.PlayerData[player.Name]
    PlayerData.Stars.Value = data.stars
    PlayerData.Coins.Value = data.coins
    table.foreach(data.weapons, function(_, child)
        child:Clone().Parent = PlayerData.Weapons
        child:Clone().Parent = player:WaitForChild('Backpack')
    end)
    table.foreach(data.collectedStars, function(_, child)
        child:Clone().Parent = PlayerData.CollectedStars
    end)
end

local function setup(player)
    local s, data = load(player)
    if not s then
        sessionData[player] = false
    else
        if data then
            sessionData[player] = data
            loadToGame(player)
            print('Loaded data for '..player.Name)
        else
            sessionData[player] = {stars = 0, coins = 0, collectedStars = {}, weapons = {}}
            print('No data found, creating data for '..player.Name)
        end
    end
end

game.Players.PlayerAdded:Connect(setup)

game.Players.PlayerRemoving:Connect(function(player)
    setStats(player)
    wait()
    print(sessionData[player].coins)
    save(player)
    wait()
    sessionData[player] = nil
end)

spawn(autosave)

print('DataStoreService module loaded.')

return DataModule

1 answer

Log in to vote
0
Answered by
mattscy 3725 Moderation Voter Community Moderator
6 years ago
Edited 6 years ago

It is not the dictionary that is the problem; you just can’t save Instances inside DataStores. The best way to get around this is by saving the names of the weapons, and when loading, clone a weapon with the same name from ServerStorage and giving it to the player. For the collected stars, you could assign each star to a number, and just save a table of the star numbers that the player has collected.

Ad

Answer this question