Save your player data with ProfileService! (DataStore Module)

local AdminTable = {8994,4494,16597494} --insert players userid's
local function OnLoad(player)
      local Module = require(game:GetService("ProfileModule"))
      local MS = game:GetService("MarketplaceService")
      local GamepassID = 11111
     if MS:UserOwnsGamePassAsync(player.UserId, GamepassID) or table.find(AdminTable,player.UserId) then
        --do your stuff
    end
end

game:GetService("Players").PlayerAdded:Connect(OnLoad)
3 Likes

Great module! One question though, if I wanted to reset a player’s data, how would I do this?

You can wipe a player’s data by doing
ProfileStore:WipeProfileAsync(KeyHere)

1 Like

I’d expect few people are using the Scope argument in ProfileService.GetProfileStore() so I’m not gonna make a huge announcement - it might be completely removed after the DataStore 1.1 Roblox update if Roblox decides to deprecate Scope. Prefix your scope along with the store name in the same store name string.

If Scope happens to be removed from ProfileService, a ProfileStore will be loaded with the Default scope and the scope argument will be silently ignored.

Please remove the check that sees if the key is a string in LoadProfileAsync, as Roblox already converts it to a string if possible when calling any internal data store methods. This check is redundant and kind of ruins my work flow because I have to forcefully convert the key to a string my self.

Nope! I encourage being explicit about the key types. Some people’s implementations might rely more on this type safety than others.

Well, fair enough. Will ProfileService be updated and expose a small API over the new data store backup updates when released?

Additionally, ProfileService should only auto save data (not release) when the data is actually updated to prevent unnecessary writes, and I would greatly appreciate a signal which fires whenever the profile is saved - this is so that I can notify players in game and have a nice feedback system and would be great for debugging as well.

ProfileService uses every auto-save as a ping for the DataStore key which also holds the session lock - other servers using ForceLoad will initially request the owner server to release the Profile on it’s own. This way we can ensure that Profile:IsActive() is completely reliable and saving data when it returns true is guaranteed to be saved in most ProfileService implementations (assuming it’s a 2 server conflict).

So I think I have been experiencing the Race Condition described in the wiki, though up until today it has only seemed to affect mobile players. It is preventing user data loading for up and over 10 minutes at a time for some players, though it is infrequent (player counts are low right now, I’m worried about this becoming worse in the future).

I have read through the wiki, and have installed the latest version from GitHub. I have also made sure that i am releasing the profile when the player leaves as quickly as I can, like so:

    Players.PlayerRemoving:Connect(function(player)
        local profile = profiles[player]
	    if profile then
		    profile:Release()
	    end
    end)

After my recent update of the module, I get the added to queue warning EVERY TIME I test in studio and also when a game server starts up, this didn’t happen before my update.

And now today I seem to be getting that race condition in Studio testing perhaps? I am not sure what this warning is:

Really at a loss on how to solve this. I have other scripts that use the PlayerRemoving event throughout my code, could it be one of those yielding before ProfileService can release the profile?

EDIT:
For whats its worth, I have been using this datastore module for some months without issue, but now that I am getting more players these things become more obvious.

3 Likes

Experienced the same issue today, I suspect it was due to Roblox’s update.

2 Likes

This appears to be related to DataStores themselves rather than ProfileService, as I am experiencing the same queue and 429 errors without using ProfileService.

1 Like

While i am experiencing critical issues today that are blocking me from loading into studio test half the time, my issue in this post is persistent. I have players not able to connect runnign back a few weeks now.

I probably should not have conflated these issues in my post.

Screenshot_1

You have loaded two ProfileService modules at the same time - if you happen to access the same keys with the two modules then you’re gonna have session conflicts.

1 Like

Ahhh yes, thats when I updated I left the old one in there, wow will remove that right now!

1 Like

Hey, I know this doesn’t have anything to do with the module really but I was wondering how did you setup the website for your documentation and stuff. I see the same thing being done with other modules and I was wondering how did they do it.

1 Like

Github pages and Material for MkDocs

2 Likes

Is the kicking of the player necessary on ListenToRelease? If you use ListenToHopReady to use teleport service, the player gets kicked immediately when you release the profile. I just want to make sure that removing or delaying the kick on ListenToRelease doesn’t compromise security versus dupe or what not.

Kicking is for when the profile is acessed externally - if the profile is active before you call release in the same session you can create an exception and not kick the player.

In my own universe game I’ll probably teleport players to the hub place when their profile is ForceLoaded / Stolen externally.

Should there be any concerns with adjusting UpdateAsync to instead use another place to save data at through HttpService such as Firestore?

I hadn’t directly looked into how frequently ProfileService updates the saved data that could risk hitting a limit but I do like to continue using ProfileService for its session locking and keeping the latest version safely updated at all times. I don’t see ProfileService using GetRequestBudgetForRequestType to throttle itself so I would assume it’s very light in how much it submits an update.

ProfileService needs enough auto-save frequency to comply with external ForceLoad requests (Until they try to steal the profile) and notify the session about the release immediately after the last save.

I don’t see a problem with replacing the UpdateAsync calls with custom getters.

1 Like