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
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.