ProfileStore - Save your player data easy (DataStore Module)

How do I migrate from profile service to this? I’ve been using profile service for a minute and needs to transfer all my players data.

I see that it’s backward compatible that means if I use the same keys and things the data structure should still work the same?

Just go through your code and replace all variables and functions to use the new APIs. You might also have to reorder some parts of it. Use the tutorial as a template.

2 Likes

For dummies like me:

  1. Replace your Data script with the example script.
  2. Inside the PROFILE_TEMPLATE, replace the cash & items with the Template variables.
  3. Delete the Template module script, since we now use that in the Data script.
  4. If you have any other scripts that reference the old ProfileService, change it to ProfileStore.

I did this and it seems to be working perfectly

2 Likes

Do we not need :ListenToRelease anymore? I noticed it wasn’t here anymore

Would it be possible for you to make a .Changed signal for profiles whenever the data is changed?

Does this also apply for gamepasses?

Roblox’s Datastores just so happened to go down as I set this up, so I thought I was doing everything wrong… :cry:

Anyways. Could I suggest two global settings for ProfileStore?

SILENCED

This setting would mute all of the prints coming from ProfileStore. Warnings and errors will stay as they are important.

{6939F88A-BEEE-4A57-B217-3A5633FF3260}

It could be implemented like this:

{F7FD462E-8F1B-4747-AB0F-76999B522166}

SAVE_ENABLED

This setting will control whether saving is enabled. When true, data may be loaded, but no changes are saved. I’ve needed to implement this myself in ProfileService, because I don’t want my code to ruin my data when I’m experimenting with something, or if I’m working on a new system.

It could be implemented like this:


Having both of these settings built-in would make migrating to newer versions a lot easier. Thanks!

1 Like

Gamepass purchase state can always be checked, so it is not data that must be saved on the DataStore.

You can attain non-saving behaviour without forking ProfileStore by using ProfileStore:GetAsync(), ProfileStore.Mock and RunService:IsStudio().

2 Likes

Ah, so the way im handling gamepasses with profilestore should work fine? No need :Save()?

Ok! I’m using that now, and it seems to work. What about silencing the prints? This was something I had to change in ProfileService as well. I like my output clean (when I’m not testing datastores)!

with ProfileService, I’d do this when the profile had loaded for the player (so listen for messages + check for updates

Do I just do this instead, and it’ll get updates they received while offline as well as any they got during in-game sessions?

Yes, the ProfileStore messaging system is for sending messages that are stored permanently in the DataStore regardless of whether a session is active for the recipient profile.

1 Like

I’ve had an issue with the old profile service not updating the template given, example:
I got this table in a template Table = {BB = true, DD = {}} new players who joined got their data as the template is set, but when i updated the template, the data for players that already have a record or the data set before i updated the table in the template to for example Table = {BB = true, DD = {}, CD = 0} they still only had {BB = true, DD = {}} with “CD” missing, is there some function for that in the newer one or even the old one?

is GetAsync the equivelant to ViewProfileAsync from ProfileService, for viewing a player’s data (whether they online or not, not session locked)

and is there any recommendation for “creating” data whether a player has joined or not?

local ProfileKey = "Player_" .. userId
local RecipientProfile = DataService.ProfileStore:ViewProfileAsync(ProfileKey)
if not RecipientProfile then
	return false, "Failed to get profile. Make sure they have played before"
end

I used to do this, which if a player had never played the game, it’d return an error, but ideally I don’t want that to occur, and just forcibly create data for the player, whether they ever play the game or not

cause atm, if data exists (they’ve played before) I do this

DataService.ProfileStore:MessageAsync(
	ProfileKey,
	{ Type = "SetClan", Tag = "ABCD" }
)

but can I just do

local RecipientProfile = DataService.ProfileStore:GetAsync(ProfileKey)

RecipientProfile.Data.Clan.Tag = "ABCD"
RecipientProfile:SetAync()

and that means when you play for the very first time, it’d load from that data?

Data in the returned Profile can be edited to create a payload which can be saved via Profile:SetAsync()

I believe I have found a bug where querying a VersionAsync whilst in Studio at runtime results in ProfileStore assuming that I am in Mock mode.

This is due to the DataStoreState not being set to “Access”, which happens in a task.spawn when I am in studio. Since this check is asynchronous, it means that it finishes after my query attempt, resulting in it believing I can’t make the query.


1 Like

when you load the profile you need to reconcile it, to have the new parts of the template table appear in the old sets of data

1 Like

I’m considering switching, but question: Does it support the old method names? specifically loadprofileasync and getprofilestore? what would their equivalents be, if the names have been changed, and do they fully serve the same purpose?

Nice catch :+1:

I have now fixed this and published the changes.

The VersionQuery code was carried over from ProfileService without many changes, but the DataStore access check was new and it went over the automatic testing since the testing code waited for ProfileStore’s DataStore access check before testing VersionQuery.

1 Like