Save your player data with ProfileService! (DataStore Module)

A bit confused on how to access the data store player-key. Trying to read someone’s store with the DataStore Editor 3.0 made by @sleitnick. How should I go about this?

The name of the DataStore is the ProfileStore’s name, and the key is the Profile’s key.

Alright, so people seem to be confused on whether this is really worth switching to or not, so I’ve decided to write a little ‘review’ of sorts:

  1. How efficient is this?
    Obviously, this module was made with low footprint in mind. It doesn’t alter your Profile.Data whatsoever, and it’s as efficient as it gets. Is it perfect? no, there’s always room for improvement and little stuff to nitpick, but those barely got any impact. As it is, this module is as good as it gets.
  2. Why should I use this?
    This module was made with issues like item duplication loopholes in mind. It prevents a lot of issues such as item-duplication through session locking (which is arguably the most important use of this module), and handles a lot of other issues for you. It has signals, which allows you add logs for when your data gets corrupted, datastore completely fails, etc, Which I’ve found very useful.
  3. But does it actually work?
    Well, you can’t really say much about that, because I didn’t really have any item-duplication issues previously, and I still don’t with this. But after discussing with loleris in DMs, I can guarantee that it does it’s job as efficiently as possible. We talked about detecting whether a player has joined from a “corrupted” (crashed) server, since there could be an issue when a player joins another server, and yet their profile wasn’t released from an old one due to that server crashing and thus being unable to release a profile. We eventually came to a solution where you can detect if a player’s profile has been locked in just >80 seconds, which is really efficient if you ask me. Obviously you could use stuff like MessagingService to perform a ping operation on a server and checking if it’s “alive” or not that way, but as Roblox states, Delivery is best effort and not guaranteed. Make sure to architect your game so delivery failures are not critical., it’s not a guaranteed and trustworthy method to use. But hey, even if you can’t get instant server-crash detection, 80 seconds is still more than enough!
  4. Is this easy to setup for my game?
    Short answer: Yes.
    Long answer: It depends.
    If you’re making a game from scratch and are going to use this from the getgo, then you don’t have to worry about anything. The API page is well-documented and has great examples, allowing for an easy setup and usage of this module.
    But for some people like me, who’ve rewritten their module from scratch to support this, here’s my take on it:
    This module is based off of what it calls profiles, so if your data-handling module isn’t set up properly, it could take you some time to switch from default data to profiles. Either way, it’s really easy to just make a wrapper of this module, allowing you to for instance imitate DataStore as much as possible.
    My data-handling module looks like this:
    image
    , where in the script it’s just local DataStoreService = require(script.Wrapper).
    Easy to setup, right?

The only thing you need to get used to is the methods a profile has, such as Profile:ListenToRelease, Profile:Release etc, but those are really easy to understand and get used to, especially with the examples provided and the API page.

Hopefully I went through everything most people are interested about, but if you feel like I missed something out, feel free to ask!

12 Likes

I really appreciate this module. After using it for a bit, I think it’s easily the best method of managing player data that is publicly available. I looked a bit at your other work and was wondering if the character anti-cheat or other aspects of your Madwork system will eventually be made publicly available? There is a lack of good movement anti-cheats out there and yours seems great so far.

1 Like

Thanks!

Madwork is a commercial project, so you can only expect gradual open sourcing of few of it’s modules over the course of next few months.

2 Likes

In my opinion, this is a great module, minus the fact of possibly waiting 80 seconds for data to load. If I were in the user’s shoes, someone who wouldn’t know about how the code works behind the scenes, I sure would find it massively inconvenient to wait 80 seconds to load into the game. This takes away from user experience and in my opinion, will make players not want to join your game if they know they could just join another fun game they like that takes seconds to load. Sure that other server might not have the features that ProfileService provides, but if the player knows they can get into the action faster in another game I am sure they would choose that over a game that takes over a minute to load your data.

You should really think of a way on how to avoid this 80 second wait altogether.

The 80 second wait is hypothetical and HIGHLY unlikely in normal conditions - some people have been highlighting it too much without explaining the actual slim odds of even encountering it.

When you actually get the 80 second wait, then we can have constructive discussions about it.

5 Likes

Wouldn’t MessagingService only really fail when either, it’s hit its limits, or all the other Roblox services are failing as well due to an outage? Whifh would include DataStoreService.

Probably, but wiki says as it shouldn’t be relied upon when it comes to important stuff.

“ Delivery is best effort and not guaranteed. Make sure to architect your game so delivery failures are not critical.”

I think you are misinterpreting this line, because this way of doing things is true for other things. I see no issue of using MessagingService as a first attempt and if that fails, fall back to the methods already in place.

I’ve already talked to loleris about it, don’t remember the reply because the whole convo was pretty long, so you’d have to ask him about it. Either way 80 (theoretical) seconds isn’t bad, adding substantially more footprint just to reduce some seconds isn’t the best choice.

1 Like

80 seconds is really bad. Imagine if you were a non-developer user as I mentioned previously. You would most likely not want to play anymore when you know other games can load faster. But I mentioned all that before. Even though this 80 second thing is hypothetical, it could still happen. It lowers user experience in my opinion.

I also disagree with where you state 80 seconds is “really efficient” because that’s completely false.

Other modules dont even offer anything. Also, take this case into consideration:

  • Player joins
  • Player’s data is session locked
  • You ping the server from where their data was session locked from
  • MessagingService fails and you are unable to validate whether that ping request didn’t work because the server crashed, or because MessagingService failed.

If you have ideas to implement something <80 seconds that is also reliable, then be my guest. If not, then this is the best you’re going to get.

2 Likes

That’s exactly my point, if MessagingService fails you fall back to other methods, but there is no harm in implementing it if it will increase the user experience of your game. I have already created a session locking system with a method using MessagingService alongside DataStores which in theory should prevent this supposed 80 second long wait.

In that bulleted list you make it as if I’m only wanting to use MessagingService which just isn’t the case.

But you can’t find out whether it has failed or not.

The “critical” part of that line is exactly what category data saving falls under. A player not being able to load their data is considered “critical” in most applications on the internet.

That’s why you implement a system that waits a max amount of time and the querys the datastore again to check if the session owner became nil. You could argue this method might take a long time too but after 1 or 2 attempts if the session owner still isnt nil, then you could just steal ownership. Time between UpdateAsync calls is under 10 seconds, so this process can be done a lot quicker than 80 seconds.

This module is made with my highest expertise - I wouldn’t be able to make any valuable changes to the dead session lock mechanics of ProfileService.

Stop talking about the 80 second wait like it’s going to happen every 10 minutes. No. If you’re not doing witchcraft in your server and Roblox is in healthy shape you’ll never get the 80 second wait.

Also dead session locks are passively cleared after 30 minutes - if the player profile receives a dead session lock and joins later in the day or next day, ProfileService will automatically clear the dead session lock based on the os.time() tag. I can’t go less than 30 minutes due to how wonky os.time() can be.

If you know of a perfect way to improve this you’ll have to make a pull request on the github repo - as I said, this is no longer something I can script based on my Roblox API knowledge and it’s trust limits. MessagingService can’t add speed to ProfileService for clearing dead session locks because the server that locked the profile is DEAD - MessagingService should not be used for checking if a server is dead because there might be other causes preventing a LIVE server from responding.

13 Likes

Is it bad? Yes, it’s terrible but we can’t physically do anything about it can we?

MessagingService will not be able to solve this issue, it’s not reliable, half broken and useless.

@JonByte as requested link1, link2, Data size limit and Budget limit is also limiting.

Solution: inform the player to wait a little longer because we are experiencing data issues, that’s all we can do, it’s pretty simple.

2 Likes

Can you explain how you know MessagingService is “not reliable, half broken and useless” ?