Save your player data with ProfileService! (DataStore Module)

It’s a safe Method - calling it too many times won’t risk anything! But, it’s also… Redundant since very early updates to ProfileService - It might only speed up the saving a little bit and is not necessary for protecting state - Why would ProfileService need some explicit method to save when it can just reliably do this all the time :sweat_smile:? It was a method created in early development stages and later had it’s behaviour changed to only request a faster save. To make secure dev product sales you need to cache receipt id’s - there’s an example on how to do this here: Developer Products - ProfileService

3 Likes
  1. I keep getting kicked in studio (PlayerAdded function is responsible)
  2. I already use regular datastore and assigned many values already. How would I be able to switch quickly?

My apologies, I was just misdirected because I thought I remembered seeing something about calling :Save() whenever something is bought, but thank you for clarifying!

So is there no real use case for this given the most updated version of profile service? Since you mentioned it being used during early development. I understand that its to request faster saving, but is there really any situation where you would need to do this?

Also, sorry to ask so many questions, but the documentation regarding developer products, what potential issues would there be if you didn’t handle developer products as shown in the documentation?

Can you possibly guide in a direction on how to create multiple save slots?

1 Like

I’ve noticed, when viewing multiple profiles at once

ProfileStore:ViewProfileAsync(`Player_{UserId}`)

It kinda like “overloads” profileservice, if multiple calls to viewprofile is happening
loadprofile doesnt work anymore…?

After all the ViewProfiles have finished data loads again like normal?

you mentioned a “remote server.” What do you mean by this?

You also specified that it waits an entire minute which is quite a long time for a user to get their data.

Why not just kick the player if a session already exists or if you have this magical “remote server”, kick all the players on the previous servers and load the new one?

ProfileService waits a minute for the other server to release the session lock on the players data so that two servers can’t edit the players data at the same time. If the server that has a session lock on the players data does not respond in time, ProfileService forceloads the data.

The remote server is the server that has a session lock on the players data I assume.

1 Like

why not wait like 10 seconds instead? A full minute is quite excessive considering the situation is likely a player either crashed or the getter beat the race condition from the setter. 5-10 seconds would be a more manageable timeframe to retrieve data rather than a full minute. Also having to do frequent checks within this minute could be a of requests.

@loleris

Well, I am clearly not loleris so I can not answer that question on his behalf. I’m just explaining what I know about ProfileService.

its possible the reason it waits a full minute is because the “remote server” is really just the autosave script.

For example, every time it autosave, it retrieves the current information about the session lock. When a different server changes the current session lock, the autosave loop will catch onto it and cancel its current session, allowing the new session to be the most recent.

Is there a way to have saveable and temporary data in the same table? I saw a response by loloris and have attempted to implement it but my understanding of profile service is limited so I am unsure if this is the correct way to achieve this.

if player:IsDescendantOf(Players) == true then
			local player_data = {Save = profile.Data, Session = {}}
			
			Profiles[player] = player_data
			
			-- func

Ideally anything under " Session " would not save, while everything under profile.data would.

Any proof to support that claim?

Its a claim on subjective basis not objective facts. While I could pull up studies of “9-10 surveyers voted that they would rather wait 10 seconds for data to load than a full minute” but I dont think such studies exist. It is simply a matter of logically reasoning the probable desires of players

I use profile service it is so nice, is there anything wrong with it? I never ran into any issues.

Its well made and tested but has a bit of a learning curve and over complicated the data saving process. A lot of the stuff you have to set up manually and manage (such as having to disconnect and connect players when they join/leave) should be automatixally done to make using the module easier.

This was the main reason I created EasyDatastore, which is like profile service however you dont have to setup any kind of profiles or configurations since its done for you. It has only 2 functions: get() and set(), which is all you need to manipulate and save data.

Now the reason I am on this post is not because I am here to talk about EasyDatastore, but because I want to talk about profileservice. To my understandint, profileservice forces the player to wair a full minute when a session is locked for this “remote sever” (presumably the autosave function.) i think this time is quite excessive (although I just kick the player)

connecting and disconnecting players are literally just a couple of lines

Oh thats okay, its recommended by so many people and has well over 100 guides on how to setup and configure a few things. I also follow your EasyDatastore, and it is nice and I recommend it for new developers, I think I even posted on that. PS is very much for a certain set of people. I don’t think EasyDS can achieve the same things PS can though. I remember talking about tables inside tables and other more complex things, but you might have added support for that IDK.

To clarify I am talkkng about EasyDatastore V2, not EasyDatastore V1. EasyDatastore V2 is just as reliable and supportive as profile service, being designed for even large scale games and projects. It supports all datatypes and is setup by creating a data template withon the EasyDatastore module script.

Its still redundant to do so. Even if its “just a few lines” it adds complexity to the module and is overall extra. It makes the learning curve more difficult for no reason too.

If ProfileService does something, it does so for a good reason. Also ProfileService waiting for over a minute until another server releases the profile is a case, not the regular behaviour of ProfileService where any profile will usually load as fast as a single DataStore call would take - you need to mess your implementation of ProfileService up to run into that case. Even so, thanks to how ProfileService handles cross-server conflicts, it can still retain a reliable :IsActive() state that guarantees “atomicy” between two loaded profiles on the same server even if you mess a lot of things up.

During a session lock conflict where ProfileService would need to wait for over a minute it lets the server that currently has the profile loaded that it has to release the profile and switch off the :IsActive() state. If the new server grabbing the profile would take ownership more hastily then this guarantee would no longer exist.

If your game doesn’t have trading or item storage between multiple data store keys - you probably won’t run into any problems with any method for storing into the DataStore. However if you have these features in your game - not using ProfileService or some kind of other trick to prevent a server hop server state mismatch you’ll be in for some surprises down the line.

5 Likes