I am trying to add multiple save slots to my game using ProfileService. This in itself is easy enough given that you can load different keys for different slots.
The issue is that I have data that I want to be synced across all different keys.
Does anyone know if this is possible, and if so, how I would go about doing it?
ProfileStore:LoadProfileAsync("Player_"..player.UserId) -- Loads different key but changes all data
1 Like
You should have only one profile per player, that’s how ProfileService is intended to be used. Rather than saving multiple slots across profiles, you should only use one profile and structure it in a way that is friendly towards such behavior.
That is good to know. But as a solution, I did find out I can load two different profile stores for the same user, which (outside of GlobalUpdates) seems to be the only way I could pull off what I’m trying to achieve with the way my profiles are structured.
If this is a bad practice though and may have negative consequences overall, please let me know.
I wouldn’t necessarily label it as “bad practice”, but it is definitely unconventional and may cause unintended behavior overall, which is why I personally would not recommend it. Besides, I’m not sure what you mean by “it is only possible this way” as all you’re doing is just maintaining multiple data templates, which is entirely possible to contain in a single profile.
Come to think of it, I didn’t actually consider loading multiple templates on one profile.
I’m going to try that instead and see what happens.
For this case, trying to add another template with the data to sync throws an error, mainly since the data script is not receiving that new template from the sole profile store.
I’m not exactly sure what this means, could you show me the “error” or the issue you’re encountering?

Due to the fact that ProfileStore only provides the one template, the data from the other template can’t be added as well. Unless you can add multiple templates to one profileStore?
That’s not really what I mean. What you could do is “simulate” multiple templates being in one profile. The structure could look something like this:
local slotTemplate = {
money = 100,
...
}
-- Pass this into `ProfileService.New`
local template = {
currentSlot = 1, -- Default slot
slots = {
[1] = slotTemplate,
[2] = slotTemplate,
...
}
}
Now this might be a bit hard to implement into a new project as its semantics are quite different from a generic profile, but I would consider it the best way to achieve what you want by far.
Yes, it’s possible to usa that, just use a separate ProfileStore "SharedData_"..player.UserId
(example) for data you want synced across all slots, and keep per slot data in individual stores then simply just load both profiles when the player joins and that should be it
I see.
so slotTemplate would be all the regular data that would go into the different slots.
Then from there, I would choose what slot to call on the data loading script from the template?
1 Like
Yes
Example if player clicks button 2 (Slot 2 index) then load everything with slot 2.
Edit: I do believe having multiple data stores will cause an issue with roblox, i think they limit how many total data stores you have per game, so its best to minimize this amount (Someone can correct me if i am wrong)
Makes sense.
This would likely also mean that code like the manager would work just fine since the slot being loaded is still one profile.
Correct! All you have to do is maybe modify your Manager to determine which slot to load
like you could add PlayerManager.GetLoadedSlot()
and return the currentSlot
the player has selected like what @CE0_OfTrolling said above in their code
That checks out.
However, this brings me back to my original issue, where I want to have some data that is synced between every slot. Unless this was already solved and I somehow missed it.
Well in that case you could just put the data in the root template rather than each slot, and just adjust your “manager code” to retrieve it in a different way.
1 Like
You can determine what data you want synced by placing it outside of the slot table
local slotTemplate = {
money = 100,
...
}
-- Pass this into `ProfileService.New`
local template = {
currentSlot = 1, -- Default slot
LEVEL = 1 -- this will be a global shared data
slots = {
[1] = slotTemplate,
[2] = slotTemplate,
...
}
}
1 Like
This sounds right.
However, I assume I would still have to return “template” since it’s a moduleScript.
In which case, the slotTemplate should still be part of it?
Also: In the data loading script, how would I tell it what slot to recieve?
Yes all you are doing is just adding a new table its like this
local slotTemplate = {
money = 100, -- This is per slot
...
}
-- Pass this into `ProfileService.New`
local template = {
CurrentSlot = 1, -- Default slot for when player joins ?
Level = 1 -- this will be a global shared data
Slots = {
[1] = slotTemplate, -- Slot 1
[2] = slotTemplate, -- Slot 2
...
},
Settings = {
MUSIC = false,
PerformanceMode = true,
}
}
All of this will be returned under the Template you just need to reference it by using profile.Data.Settings.MUSIC → Returns false or profile.Data.Slots[1] → returns slot one.
In the data loading script you would tell what slot to receive by letting the user input their choice but for now you can hard code it
function Manager.SetCurrentSlot(Player: Player, Value: number)
local profile = Manager.Profiles[player]
if not profile then return end
profile.Data.CurrentSlot = value
end
function Manager.GetCurrentSlot(Player: Player)
local profile = Manager.Profiles[player]
if not profile then return end
return profile.Data.CurrentSlot
end
Manager.SetCurrentSlot(game.Players.MoawesomeI8, 1) -- Sets as slot one.
-- Manager.LoadSlot(game.Players.MoawesomeI8)...? If this function exists it would load everything in that slot.
This is just a bare bones example but you can modify it to your needs
As of now I currently have a function that adds folders & whatnot to the player after the single profile is loaded. Would I just have to move this code to the manager and then do:
Manager.LoadSlot(plr, CurrentSlot) as an example
?
If it’d help I can provide an example of what I mean.