What’s wrong with my code and why can’t I just save folders?
local Players = game:GetService("Players")
local cachedProfiles = {}
local ProfileService = require(script.ProfileService)
local MarketplaceService = game:GetService("MarketplaceService")
local SETTINGS = {
ProfileTemplate = {
Cash = 0,
Level = 0,
Morphs = 0,
Exp = 0,
Inventory = {},
},
Products = { -- developer_product_id = function(profile)
[1334632353] = function(profile)
profile.Data.Cash += 100
end,
[1334633003] = function(profile)
profile.Data.Cash += 250
end,
[1334633004] = function(profile)
profile.Data.Cash += 550
end,
[1334633000] = function(profile)
profile.Data.Cash += 1750
end,
[1334632999] = function(profile)
profile.Data.Cash += 2500
end,
[1334633002] = function(profile)
profile.Data.Cash += 6500
end,
[1334633001] = function(profile)
profile.Data.Cash += 12750
end,
},
PurchaseIdLog = 50, -- Store this amount of purchase id's in MetaTags;
-- This value must be reasonably big enough so the player would not be able
-- to purchase products faster than individual purchases can be confirmed.
-- Anything beyond 30 should be good enough.
}
local PlayerProfileStore = ProfileService.GetProfileStore("PlayerData", SETTINGS.ProfileTemplate)
----- Private Functions -----
local function PlayerDataLoaded(player)
local profile = cachedProfiles[player]
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
folder.Parent = player
local cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Value = profile.Data.Cash
cash.Parent = folder
local level = Instance.new("IntValue")
level.Name = "Level"
level.Value = profile.Data.Level
level.Parent = folder
spawn(function()
while true do
local profile = cachedProfiles[player]
if profile ~= nil then
cash.Value = profile.Data.Cash
level.Value = profile.Data.Level
else
break
end
wait(0.1)
end
end)
print(player.Name .. "'s data is loaded")
end
function cachedProfiles.GiveCash(profile, amount)
-- If "Cash" was not defined in the ProfileTemplate at game launch,
-- you will have to perform the following:
if profile.Data.Cash == nil then
profile.Data.Cash = 0
end
-- Increment the "Cash" value:
profile.Data.Cash = profile.Data.Cash + amount
end
function cachedProfiles.AddMorphValue(profile, amount)
if profile.Data.Morphs == nil then
profile.Data.Morphs = 0
end
profile.Data.Morphs = profile.Data.Morphs + amount
end
--[[local function DoSomethingWithALoadedProfile(player, profile)
profile.Data.LogInTimes = profile.Data.LogInTimes + 1
print(player.Name .. " has logged in " .. tostring(profile.Data.LogInTimes)
.. " time" .. ((profile.Data.LogInTimes > 1) and "s" or ""))
GiveCash(profile, 100)
print(player.Name .. " owns " .. tostring(profile.Data.Cash) .. " now!")
end ]]
local function folderToDictionary(folder, dictionaryi)
local dictionary = dictionaryi
for _, object in ipairs(folder:GetChildren()) do
if object:IsA("Folder") then
dictionary[object.Name] = folderToDictionary(object)
elseif object:IsA("ValueBase") or object.ClassName:match("Value") then
dictionary[object.Name] = object.Value
end
end
return dictionary
end
local function dictionaryToFolder(folder, dictionaryi)
local dictionary = dictionaryi
for i, v in pairs(dictionary) do
if folder:FindFirstChild(v) == nil then
dictionary[v]:Clone().Parent = folder
end
end
--[[ for _, object in ipairs(folder:GetChildren()) do
if object:IsA("Folder") then
dictionary[object.Name] = folderToDictionary(object)
elseif object:IsA("ValueBase") or object.ClassName:match("Value") then
dictionary[object.Name] = object.Value
end
end ]]
return dictionary
end
local function PlayerAdded(player)
local profile = PlayerProfileStore:LoadProfileAsync("Player_" .. player.UserId, "ForceLoad")
if profile ~= nil then
profile:ListenToRelease(function()
cachedProfiles[player] = nil
player:Kick("Your profile has been loaded remotely. Please rejoin.")
end)
if player:IsDescendantOf(Players) then
cachedProfiles[player] = profile
PlayerDataLoaded(player)
else
profile:Release()
end
else
player:Kick("Unable to load saved data. Please rejoin.")
end
local CharacterFolder = Instance.new("Folder")
CharacterFolder.Name = "Inventory"
CharacterFolder.Parent = player
-- dictionaryToFolder(player.Inventory, profile.Data.Inventory)
--[[
for i,v in ipairs(profile.Data.Inventory) do
-- local nv = Instance.new("ObjectValue")
-- nv.Name = i
-- nv.Parent = CharacterFolder
print(v.Name) --->> bla, bla2, bla3
end]]
if profile.Data.Inventory ~= nil then
for i,v in pairs(profile.Data.Inventory) do
if player.Inventory:FindFirstChild(v) == nil then
game.ServerStorage._LeaderstatsInventoryValues[v]:Clone().Parent = player.Inventory
end
end
end
while true do
wait(0.02)
player.PlayerGui:WaitForChild("MainGui")._CashFrame.Title.Text = profile.Data.Cash
-- contents.Cashig = profile.Data.Cash
-- print(contents.Cashig)
end
end
----- DevProduct Functions -----
function PurchaseIdCheckAsync(profile, purchase_id, grant_product_callback) --> Enum.ProductPurchaseDecision
-- Yields until the purchase_id is confirmed to be saved to the profile or the profile is released
if profile:IsActive() ~= true then
return Enum.ProductPurchaseDecision.NotProcessedYet
else
local meta_data = profile.MetaData
local local_purchase_ids = meta_data.MetaTags.ProfilePurchaseIds
if local_purchase_ids == nil then
local_purchase_ids = {}
meta_data.MetaTags.ProfilePurchaseIds = local_purchase_ids
end
-- Granting product if not received:
if table.find(local_purchase_ids, purchase_id) == nil then
while #local_purchase_ids >= SETTINGS.PurchaseIdLog do
table.remove(local_purchase_ids, 1)
end
table.insert(local_purchase_ids, purchase_id)
task.spawn(grant_product_callback)
end
-- Waiting until the purchase is confirmed to be saved:
local result = nil
local function check_latest_meta_tags()
local saved_purchase_ids = meta_data.MetaTagsLatest.ProfilePurchaseIds
if saved_purchase_ids ~= nil and table.find(saved_purchase_ids, purchase_id) ~= nil then
result = Enum.ProductPurchaseDecision.PurchaseGranted
end
end
check_latest_meta_tags()
local meta_tags_connection = profile.MetaTagsUpdated:Connect(function()
check_latest_meta_tags()
-- When MetaTagsUpdated fires after profile release:
if profile:IsActive() == false and result == nil then
result = Enum.ProductPurchaseDecision.NotProcessedYet
end
end)
while result == nil do
task.wait()
end
meta_tags_connection:Disconnect()
return result
end
end
local function GetPlayerProfileAsync(player) --> [Profile] / nil
-- Yields until a Profile linked to a player is loaded or the player leaves
local profile = cachedProfiles[player]
while profile == nil and player:IsDescendantOf(Players) == true do
task.wait()
profile = cachedProfiles[player]
end
return profile
end
local function GrantProduct(player, product_id)
-- We shouldn't yield during the product granting process!
local profile = cachedProfiles[player]
local product_function = SETTINGS.Products[product_id]
if product_function ~= nil then
product_function(profile)
else
warn("ProductId " .. tostring(product_id) .. " has not been defined in Products table")
end
end
local function ProcessReceipt(receipt_info)
local player = Players:GetPlayerByUserId(receipt_info.PlayerId)
if player == nil then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local profile = GetPlayerProfileAsync(player)
if profile ~= nil then
return PurchaseIdCheckAsync(
profile,
receipt_info.PurchaseId,
function()
GrantProduct(player, receipt_info.ProductId)
end
)
else
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
----- Initialize -----
for _, player in ipairs(Players:GetPlayers()) do
spawn(function()
PlayerAdded(player)
end)
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(player)
local profile = cachedProfiles[player]
if profile ~= nil then
for i, v in pairs(player.Inventory:GetChildren()) do
table.insert(profile.Data.Inventory, v.Name)
end
profile:Release()
end
end)
return cachedProfiles
I’ve tried LITERALLY everything on the internet from normal datastore folder saving tutorials to tool saving tutorials and nothing works! I can’t find any tutorials related to ProfileService to do this stuff. The error now says that the script can’t find “Cash” inside of the folder provided in line 216, but cash isn’t really being stored in that table OR folder so what does “Cash” even have anything to do with the dang script?!