Lionstore, a low impact, reliable DataStore library

Lionstore

a low impact, reliable alternative to ProfileService and DataStore2.

Github | Docs | Download | Donate :heart:


Lionstore is meant to be a low impact, reliable alternative to ProfileService and DataStore2.

Lionstore aims to be as minimal as possible yet powerful. Having the capability of ProfileService’s session locking, and using backups like DataStore2, lionstore provides a robust way to save your data.

Lionstore is fault tolerant. If your data becomes corrupted, no problem; enter habitats , a way to catch errors and mark them from saving before it gets deleted. Partitions are a powerful feature of the library. The reason why it’s so lightweight is that it gives you the ability to split the allocation of your data into multiple partitions. No need for ordered data stores anymore. Every time a player’s data gets loaded, a partition gets discarded so there’s a revision history based on how many partitions exist.

Lionstore is low impact. Data is only retrieved once, and periodically sends a lock request every 4 minutes per session.

The API is very minimal. Everything is already implemented for you. You don’t need to store player objects in tables, it does it for you. Session locking means that if a player rejoins while the past server is saving, data won’t be lost.

There’s no set functions, only update. Data automatically get reconciled upon load.

Lionstore automatically keeps profiles alive as long as the player has not left. Saves are brute force and will be retried until the save succeeds.

Usage:

local Lionstore = require(script.Parent.Lionstore)

Lionstore.SetInfo({
    Partitions = 9,
    Default = {Log = 0},
    HandleLocked = function(Player)
        print(Player.Name .. " has data loaded elsewhere")
        local Profile = Lionstore.GetProfile(Player)
        Profile.Release.Event:Wait()
        print("other servers done")
        return true
    end,
    HandleCorruption = function(Player, Data)
        print(Player.Name .. " has bad  data")
        local File2 = Data.Data[2]
        if File2 then
            print('revert')
            Data.Data[1] = File2
            Data.Corrupted = false
            return true
        end
    end,
    BeforeSave = function(Player, Data) 
        print(Player.Name .. " is about to save") 
        return Data
    end,
    BeforeInitialGet = function(Player, Data)
        print(Player.Name .. " has data")
        return Data
    end,
    
})

game.Players.PlayerAdded:Connect(function(Player)
    local Profile = Lionstore.new("key2825122", Player)

    Profile:habitat(function(Data)
        Profile:update(function()
            Data.Log += 1
            return Data
        end)
        print("person logged in; " .. Data.Log)
    end)
end)

12 Likes

why does it have to many functions just to save player’s data and does this use some functions to make a leaderboard

I agree with @FerbZides, its a ton for just saving player data. All you have to do in DS2 is initialize and :Save()… you may want to work on making it better so more people feel the need to actually switch over.

1 Like

Whats so good about this compared to ProfileService? Datastores are almost never corrupted and its only ever roblox’s fault when they do.

That makes the whole corruption protection completely useless and makes this whole thing pointless compared to ProfileService.

1 Like

Kicking players when they won the race over the save from the last session is far from ideal:


Screenshot_3

From what I can see there’s no endpoint for repeating the GetAsync manually either within a custom HandleLocked(), so there’s not much else you could do while using this module in this scenario.

ProfileService allows reliable grabbing of profile locks from remote sessions that haven’t even decided to release the profile yet - this should be the norm for any kind of DataStore session locking.

3 Likes

Just wondering, why not just us Datastore 2 instead?

I didn’t understood are all those functions in .SetInfo optional or required

Datastore2 doesn’t have session locking.

2 Likes

I find the usage still confusing. How do I set data? It seems really complicated.

That’s there for a default. You can write your own HandleLocked which lets you do whatever you want with the player.

That being said, I’ll add this in a next release

v3 is out! I added profile lock grabbing & poll for unlock.
Check op for updated content

This seems pretty good for what it is, sorry for the bump. Just figured out this was the first “hybrid” and stuff.

I would like to know, are these backups OrderedBackups or the weird “backups” DataStore2 has as :SetBackup(), :IsBackup(), (those for me aren’t even backups, they’re just emergencial or something…)

Eh… Using less API requests doesn’t really mean that it’s good, I would go for 60 seconds. It sounds safe to me and yeah.

Not related but useful for anyone building their solutions to datastoring:

Try to wait until the DataStore 1.1 update gets released as it would help future proofing your module if you use it. The more you can integrate into it the better. It’s hard to set up stuff to work later to work with it so I would wait… it’s supposed to release Q4 2021 so it’s supposed to be really soon? I guess we’ll have to wait.