Oh okay thanks for telling me. Edit - It works now!
Today, i just got a error
21:50:54.441 - ServerScriptService.Leaderboard.ProfileData.ProfileService:1052: Argument 2 missing or nil
21:51:24.353 - Not running script because past shutdown deadline (x18)
I don’t know if this is caused by my scripts.
Send me a screenshot of line 1052 in your ProfileService as it might be an outdated version - just send me the line anyways so I could tell where it is in the new code.
@loleris
Do you know how I would create a system to merge for profileservice:
local saveStructure = {
Coins = 0;
Gems = 0; -- what if I added gems in an update
}
local PlayerProfileStore = ProfileService.GetProfileStore("PlayerSaveData", saveStructure)
Also how would you go about saving a table with ProfileService?
Profile.Data
is already a table. You can store nested tables within tables - see Lua documentation.
If your data structure is not complex, you can do a first branch merge (will not merge keys inside nested tables) as soon as you :LoadProfileAsync()
:
local function DeepCopy(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
v = DeepCopy(v)
end
copy[k] = v
end
return copy
end
for key, value in pairs(saveStructure) do
if profile.Data[key] == nil then
if type(value) == "table" then
profile.Data[key] = DeepCopy(value)
else
profile.Data[key] = value
end
end
end
Just use this:
local SaveStructure = {
Coins = 0,
Experience = 0,
Items = {
Owned = {},
Renting = {},
}
}
local function DeepCopy(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
v = DeepCopy(v)
end
copy[k] = v
end
return copy
end
local function MergeDataWithTemplate(data, template)
for k, v in pairs(template) do
if type(k) == "string" then -- Only string keys will be merged
if data[k] == nil then
if type(v) == "table" then
data[k] = DeepCopy(v)
else
data[k] = v
end
elseif type(data[k]) == "table" and type(v) == "table" then
MergeDataWithTemplate(data[k], v)
end
end
end
end
MergeDataWithTemplate(profile.Data, SaveStructure)
Thanks I figured out what to do. Do you think I should create a community tutorial about ProfileService to help people?
Your knowledge might be limited for making a completely correct tutorial, but you can still make one and share with your fellow developers!
Also about the saving folders. You would do Example: (table.insert(profile.Data.Inventory,item.Name). Correct? @loleris
That can be however you like it to be set up.
Do you have an example in the github?? Nevermind I’m trying it out. Done now it works.
coroutine.wrap(SaveProfileAsync)(self, true) – Call save function in a new thread with release_from_session = true
does :LoadProfileAsync()
support only strings for the profile_key, or can I use numbers too?
You’ll have to use tostring()
on your number keys before passing to :LoadProfileAsync()
.
If you’ve been using numbers as keys, they were being casted to strings, based on the official API:
Would the code break if I were to automatically tostring it in your ProfileStore:LoadProfileAsync
function (line 1064)?
I’ve been using numerical keys for my data store and am about to switch to this module.
I would not break it, though, as minuscule as this issue is, it would probably be more professional to convert the value before passing it in. You would also avoid the risk of forgetting custom changes when switching out to an updated ProfileService version in the future.
I’m currently making a module that pretty much just uses your profileservice, but with some renamed functions to fit my coding habits (e.g
function Network:GetProfileStore(StoreName)
return ProfileService.GetProfileStore(StoreName)
end
), I’d assume it’d work fine if I were to just wrap your profilestore in my module to automatically tostring the profile_key
argument of LoadProfileAsync
?
Something along the lines of:
function Network:GetProfileStore(StoreName)
local ProfileStore = ProfileService.GetProfileStore(StoreName)
return setmetatable({
LoadProfileAsync = function(self, profile_key, not_released_handler)
return ProfileStore:LoadProfileAsync(tostring(profile_key), not_released_handler)
end
}, {__index = ProfileStore})
end
Forgetting to implement custom changes to your module is a good concern, so I’d assume this would be the safest approach?
Sure, that looks like it should work fine.