ProfileStore - Save your player data easy (DataStore Module)

Deep copy your default data template and set Profile.Data to the deep copy all while the session is active. You can find a deep copy function inside the ProfileStore source code.

How can I update a user’s data even if his profile is active on another server?, and also know if the player’s serssion is on or not

It seems like .OnLastSave does not work as expected, specifically the reason being passed. Shutting down servers from the experience page does not trigger a “Shutdown” reason. This is because shutting down servers seems to kick all players first, firing PlayerRemoving events then BindToClose functions are fired. I am not sure how to get around this or if this is intended.

One thing I think Roblox’s DataStoreService is really lacking is the ability to treat a regular DataStore as an OrderedDataStore, with some version of GetSortedAsync for regular DataStores storing dictionaries.

For example, I might be saving a player data dictionary like this one:

local dataTemplate = {
   Coins = 0,
   Wins = 0,
   Pets = {},
}

If I wanted to create a global leaderboard for Coins, I’d need to create a separate OrderedDataStore so that I could use GetSortedAsync. I think it would be really awesome if ProfileStore had a feature handling this. I’d imagine it working sort of like GetSortedAsync, returning a DataStorePages object.

An example of what I think you could implement in ProfileStore:

local pages = profile.Data:GetSortedByStat(statName: "Coins", ascending: true, pageSize: 25, minValue: 5, maxValue: 100)

By the way, amazing module! Using ProfileStore really gets rid of the worry that my DataStore script isn’t secure enough, and I may be subject to data loss. Thank you for creating this amazing resource :woot:

If players are really kicked before BindToClose is called then that’s making things pretty tricky…

A) You could try to manually inform all servers you’re going to shutdown with MessagingService and then treat players leaving differently. You may also create a DataStore flag to let new servers know a shutdown is about to happen. This might be the only way to make a clean leave penalty system in this case.

B) You try to not have any penalties for player leaving. Treat all leaving as if the players didn’t leave on their own.

C) You treat all player leaving as if they left by themselves. If there are any penalties for leaving you warn players that they will be penalized even if the servers shut down.

1 Like

Yes, ideally BindToClose should be fired before kicking players (honestly before ANY other events). Using MessagingService to lock servers and then conducting shutdown logic would work, but I am concerned about possible cases in which MessagingService fails. I am not sure what the behavior is, like if 8/10 servers can successfully receive a message but the last 2 get dropped for whatever reason leading to un-updated servers hanging around.

Probably will just end up going with Option B :smiling_face_with_tear:

Im sorry to ask again, but is it possible to update a user data even if is active or not, because I rlly need to update it in real time, not If the player joins the game, Ik I can use the messageAsync, however If the player on not online I can use the SetAsync to also update it to others players, but idk how to check If the player is online

I am with a problem where if you send a message, th other player will only receive it after rejoining the game, is there any way to the player receive it while is on the game

Use messangingservice for that if the player is in a different server, or handle it logically if they are in the same server.

In case anyone is wondering, I did find a work around for this issue which corrects the behavior of OnLastSave. I am not sure if there are any downsides to this, I can’t really think of any if you structure your logic correctly.

Since PlayerRemoving fires before BindToClose functions, you can yield in the PlayerRemoving event for a small amount of time to wait for BindToClose to fire. Specifically, adding a RunService.Heartbeat:Wait() before calling Profile:EndSession() will causes BindToClose to run before Profile:EndSession().

Of course, you need to add logic such as Profile:IsActive() == true before calling Profile:EndSession() since BindToClose will also close the profile.

This seems to be working 100% of the time. I also tested this in situations where you are the last player in a server (when leaving causes BindToClose to fire) and it works as expected.

If player kicking and BindToClose run on the same game tick then yielding for one frame would be a reliable solution! It would be useful if this behaviour could be backed up by official Roblox sources, but if it works then it works!

Agreed. I have no knowledge on underlying engine behavior but it seems to be working. I initially tried using task.defer, but this still led to BindToClose firing after PlayerRemoving which I found interesting.

I use ProfileService greatly. My new game isn’t released yet and I’ve built it using ProfileService mostly. Is this ProfileService stable enough for a game release yet? I don’t want to use it if players will have problems, but I absolutely love the new API that comes with this.

You can check through some of the people’s replies on this forum thread - so far I haven’t received any reports that would lead to a critical bug since this module’s release. ProfileService has also maintained a clean track record since release!

Hello, I have a question, I am using SetAsync in order to make the data go fast troughout the servers, however SetAsync ends the sessions, how could I update the player data, instand of only updating every 300 seconds.

What’s your intended goal with this? Don’t understand make the data go fast troughout the servers exactly.

Im making a game where you can follow people like on Instagram, and its importante to get the followers list, to be like live if some One follows you, you know instantly on your data