GreedyDataService || The simplest datastore solution that is session-locked and automated

I can agree with this part, I am planning to recreate some modules but with less features and is easier to set up

3 Likes

It strongly depends on where the “simplicity” lies. In this case, it seems as though “simplicity” refers to a non-extensive developer-facing API, which doesn’t really say much. ProfileService is an equally simple library in my opinion, it’s just loaded with a lot of developer-facing API for you to take advantage of. Certainly, not in all cases, but in most cases, this word can be a huge noob trap and lose out on benefits offered by other resources in more robust fashion. That’s part of where I say that personally, the selling points aren’t convincing.

I generally understand what you want to achieve with this library though - automate most of the things that you would otherwise be expected to write yourself with ProfileService (which already automates, so that’s to say it offers a higher level of abstraction) and leave developers to spend less time writing and more time deploying their data tools. The main thing I wanted to convey is that not having some of these things abstracted gives back control to developers and lets them reason about how most of the processes of their data systems are conducted, which is a valuable skill to have.

For pure example: ProfileService lets me decide how to handle the case of a locked session or profile that failed to load so I could either retry in a bit (assuming it’s not an outage) or send them away temporarily to a place that doesn’t require their save data. GreedyDataService immediately assumes that the player should get kicked. You can’t sidestep this without

  1. Setting loadingTimeout to math.huge which will cause an infinite yield.
  2. Modifying the source code, which another library would better serve by allowing you to hook into the loading process or handle state.

It’s reasonable to consider that not many features may be used and may be particularly niche therefore excluding them, but serving a wide variety of use cases - especially of part of your target audience is production-level deployment - really helps future proof the library for those power users. The fact that they’re also battle-tested also helps give me confidence in using them over a novel new library.

As a strong advocate for and user of ProfileService, I use most of its features. There’s a lot of things I like that it offers. While you and your consumers may not use most of the features there and that’s why they aren’t here, the wealth of features helps empower data tooling workflows that are cornerstone to providing developers and players with an appropriate save data experience.

  • Consistency. Player data is not the only thing I use data stores for: I also use them for global configurations, specifically world events. GreedyDataStore only supports player data. While that is not a negative, its inflexibility can lead to inconsistency with data management.

    • GreedyDataService only allows data storage under the GreedyDataStorage namespace. It does not offer support for names, scopes or key structures.

    • This is similar to the limitation that puts me away from DataStore2. A data library purely focused on players is not bad at all, but if another library allows me to use the same library and have the same guarantees for players and non-player entities, I will always preference the latter.

  • Reconciliation is at my discretion. I often reconcile immediately but for trickier requirements like data structure migration, I want to wait until I’ve gone through all migrations first before reconciling since reconcile assumes attaching the latest keys to the current data.

  • Versioning. Player data is incredibly tricky to get down well and it’s incredibly easy to make mistakes. Having support for version rollbacks helps developers gain the confidence they need to rectify data corruptions and other issues. The raw DataStoreService API for versioning and rollbacks requires boilerplate and is a particularly ugly process compared to being given an API that’s human readable and easy to use (e.g. Roblox enforces a UNIX timestamp; ProfileService allows nil, a DateTime object or a UNIX timestamp).

  • Mocking for testing data stores in Studio or test environments without data saving. My two cents is that every DataStore library should include the ability to mock so you can stage code that relies on save data. ProfileService offers this as the Mock member of a ProfileStore. Lapis offers this as a configuration that accepts either DataStoreService for live data or a mock library (e.g. buildthomas’ MockDataStoreService library) for local testing.

  • Clear design for GDPR compliance. Why is this coming soon? This should launch with it. As long as there’s even just a temporary solution before it’s officially supported by the library’s API, that will work well. As you are using an external library for data management, the structure of DataStores is not entirely clear and requires a deeper dive to figure this out.

  • No early-release APIs. GreedyDataService is greedy about how sessions are handled and the contract here is that sessions are active between join and leave, no questions asked. You as the developer cannot defer opening a session or close one early and determine what happens to a player when a session ends (e.g. should they teleport, be kicked, open a different session, etc).

  • Can’t force data to save. I’m cautious: I force saves at critical moments such as Robux purchases. ProfileService will take a force-saved profile out of the current cycle’s auto save queue for me and reset its timer.

    • There are times when you just don’t want to wait for an auto save cycle, especially with high cloud services pressure now. Peak times for your experience, larger experiences updating and crashing cloud services and holidays are all key points when force saving starts becoming a palatable idea so progress isn’t rolled back.

    • Shortening auto save intervals beyond 30 is a bold move depending on your data sizes given the existing throughput limits.

Fair sell? Sure, I speak for myself when I say it’s not convincing. A lot of developers, whether to their own benefit or not, are attracted to the idea of “simple”. It’s like a magic word that sets off all the happiness sensors. You don’t have the company of the APIs you’re not going to be using… though that’s irrelevant, you could just ignore them. Feature-rich libraries aren’t always used in full by their consumers, and you just need to pick out what you need. The more robust a library, the more cases it covers. Primarily why I’m an advocate for wrappers and tutorials moreso than “alternatives”.

5 Likes

Thanks for the feedback, I’ll make adjustments accordingly. While I will keep the simple approach, I’ll add flexibility and functionality for what you’re looking for (so that developers such as yourself can override the default and use niche stuff). Appreciate it, keep an eye peeled for these updates soon :+1:

5 Likes

Hey guys! I’m currently working on a bunch of changes that will be rolled out incrementally in the very-near future.

Check out my todo list here: https://github.com/MiaGobble/GreedyDataService/blob/main/todo.md

Now is the time to give feedback for these upcoming changes!

1 Like

Although I do respect your feedback I do not think that this module was ever supposed to replace / rival ProfileService in terms of features/extensibility. I think that this module is to support the needs of most developers which is a reliable and well-made Datastore Wrapper and I think it does a good job serving that purpose. In general I would consider that most people will not have a problem with the features of this module and as @iGottic stated simple Is sometimes better. In general good job @iGottic and for those that cannot benefit from the simplicity of this module and need a more advanced module then use the battle tested profile service.

2 Likes

When a resource includes any variant of the phrase “why should you use X over Y”, the implication is that it’s intended to be an alternative solution and the following section explains why… well, it’s in the title itself, why it is preferrable for use over other solutions out there.

GreedyDataService’s target audience may not be to serve the same extent as ProfileService or other data libraries and that is okay and respected, much like how you wouldn’t use DataStore2 for anything beyond player data. I do not mean to pressure GreedyDataService to expand its scope beyond its intended use, and that is likely a fault on the way I phrased my replies. I primarily wanted to talk about the positives of other libraries and prod the justification for this as an alternative a bit.

1 Like


Really looking forward to this!

2 Likes

does it use profile service? if so im def gonna use it

1 Like

No, it is an alternative to it.

1 Like