Save your player data with ProfileService! (DataStore Module)

I have no idea how I overlooked game.Players:GetPlayerFromUserId. Thank you so much for the reply and your input :open_hands:

1 Like

need help. dm me

ㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤ

ㅤㅤ

I’m having issues with Profile Service, after setting up the data template and everything it works fine… but once the game is played by players and etc, if i added any new value to the data template it returns “nil” and errors until i totally wipe Data, How Can i Solve this issue? Since i can’t really wipe data again to just add a few values…

Look at and use profile:Reconcile() :wink:

2 Likes

Alright Let me read about it, then i will tell you if it worked ;c

Hello, I have a question. When using LoadProfileAsync if the profile isn’t found / there is no saved profile with the key, will it simply just write to the datastore / cache with the key and essentially prevent it returning a non existent profile.

If so how could I circumvent this as i want specific behaviour for when data in that certain key hasn’t been saved before.

You may use the return value of ProfileStore:ViewProfileAsync(). It will return nil if no profile is linked to the provided key.

1 Like

I’m new to ProfileService and am having an issue with some of my profile data. I have the following template:

local ProfileTemplate = {
	BestRaceTimes = {}, -- [courseNumber] = elapsedTime
	RaceCounts = {}, -- [courseNumber] = raceCount
	LogInTimes = 0,
}

This data is being updated in two ways. The first way works fine:

local function UpdateProfileLogInTimes(player, profile)
	profile.Data.LogInTimes += 1
	print(player.Name .. " has logged in " .. tostring(profile.Data.LogInTimes)
		.. " time" .. ((profile.Data.LogInTimes > 1) and "s" or ""))
end

The second way updates profile.Data but the changes aren’t getting saved to the Datastore:

local function updateRaceData(player, courseNumber, elapsedTime)
	print("PlayerProfile updateRaceData", player.UserId, courseNumber, elapsedTime)
	local profile = PlayerProfiles[player].Profile
	local bestTime = profile.Data.BestRaceTimes[courseNumber]
	if bestTime == nil or elapsedTime < bestTime then
		profile.Data.BestRaceTimes[courseNumber] = elapsedTime
	end
	if profile.Data.RaceCounts[courseNumber] == nil then
		profile.Data.RaceCounts[courseNumber] = 0
	end
	profile.Data.RaceCounts[courseNumber] += 1
end

SavepointRemoteEvent.OnServerEvent:Connect(updateRaceData)

Any idea what I am missing or doing wrong?

Hello. I have a quick question.

Is there anyway I am able to read / extract data from a profile in profile service without having to load it normally. I am also wondering how I would be able to access ALL profile entries in my profile data store.

Any help would be appreciated.

On the 3rd line, local profile = PlayerProfiles[player].Profile
I don’t think the .Profile is necessary. So you should just be able to access the data by PlayerProfiles[player].Data instead of PlayerProfiles[player].Profile.Data

Wow! A person from a discord server recommended me this, and I am very thankful because this helped a lot! Thanks, @breadbutcooler !

3 Likes

Actually, I need .Profile because I’m also using ReplicaService so my PlayerProfiles looks like this:

local PlayerProfiles = {} -- [player] = {Profile = profile, Replica = replica}

Learning this module was worth my time, thanks for providing this loleris :slight_smile:

1 Like

Anybody struggling with using :Reconcile()?

Been using this module for over a year and haven’t had any issues. Now however I’m finding it impossible to remove old data values. Using :Reconcile() on the profile usually fixed this, however now it seems to do nothing. Anybody having similar experiences with possible solutions?

:Reconcile() doesn’t remove existing data from a player’s profile; it only fills in variables from the current ProfileTemplate that the player doesn’t have in their profile already.

If there are any existing variables in a player’s profile that you want to remove, that would need to be done separately.

1 Like

How trust worthy is whats preventing multiple server editing? In my case, players can like a players creation from other servers meaning there could be a lot of data trying to overlap.

ProfileService session-locking is more for avoiding players from having two servers with ‘active’ session data by attaching a job-id to the session when the player is in a server. If you try to load another profile with this session data active, the player will have to wait a bit for the data to become available, as the new server requests to take over by appending a force request, wait a bit, if the session was released, the new server takes it back, if the session didn’t release, it’ll assume the session died and take over.
ProfileService forces only one server to have an active attachment of a profile if you have Loaded their profile.

TL;DR. It’s best to use ProfileService for making sure only one session has access to an ID at a time.

As for wanting to add a like to another players creation, you could instead use DataStore directly and use UpdateAsync which makes all other servers get into a ‘queue’ to update the data if multiple servers are wanting to add a like.

UpdateAsync(“key”,function(current key)
current key[ likes ] = current key[ likes ] + 1
return current key
end) )

Roblox does the work to make sure other servers who also want to add an update, yeild, until the previous one has returned data.

https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/UpdateAsync

GlobalDataStore:UpdateAsync is safer for handling multi-server attempts because it reads the current key value (from whatever server last updated it) before making any changes. However, it’s somewhat slower because it reads before it writes, and it also counts against both the read and write limit.

1 Like

I never knew default datastore did this, thank you!

How often does profile service check to see if a player’s session is still locked?

How does profile service handle when a session is locked on a live server and someone is trying to login from a second?

For the second question, it will depend on what you put for the second variable.

  • ForceLoad - Will repeatedly request the server that has it locked to release it or will steal it after a certain amount of attempts.

  • Steal - Ignores session lock

Refer to the not_released_handler for the ones below.

  • Repeat - Will continuously attempt to load the profile (Profile locks automatically timeout after 30 minutes if server holding it has crashed)

  • Cancel - Cancels the load attempt and returns nil for the profile

https://madstudioroblox.github.io/ProfileService/api/#profilestoreloadprofileasync