How do I use datastore?

Hello there,

I am Mastermahmoudpip and I would like to know how to use datastore, maybe this question has been aleardy answered but I don’t understand from others because they explain it on the advanced way. Can someone answer it in the easy way and put it in detail what does it do and how do I use it?

Note: (I even can’t understand from roblox developer hub, I need help please, anyone and any help is appreciated.)

4 Likes

Ah yes, DataStores!
To put it simply? A DataStore is basically something that stores every player’s individual data

You can use DataStores in a lot of different ways, but let’s say you wanna make a simple basic save/load system

Step 1: Setting up our Variables & Events

The first thing when making a script, is that we should go ahead & create our Variables & Events so that we can easily access them! First, we’ll define our variables then we’ll need to use the PlayerAdded & PlayerRemoving Events in this Instance:

local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")

local function LoadData()

end

local function SaveData()

end

game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)

LoadData is just simply whatever we wanna call it when we use the GetDataStore function (Heck you can even call it a meme string and it’ll still work, just make sure not to name it too long)

The next thing we’ll insert in our script is creating our local Values for each player when they first join:

local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")

local function LoadData(Player)
    local stats = Instance.new("Folder")
    stats.Name = "leaderstats"
    stats.Parent = Player

    local RandomValue = Instance.new("IntValue")
    RandomValue.Name = "Value1"
    RandomValue.Parent = Player
end

local function SaveData(Player)

end

game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)

Naming our folder leaderstats & parenting it to the player will create ROBLOX’s leaderstat system!

Step 2: Getting/Saving the Data

Now here’s where things get a bit tricky, saving & loading the Data

Whenever we want to function something relevant to player data, we’d always wanna encase it in a pcall (Which is in simple terms, a protective call so that we have a much better chance for our data to save/load)

Referring back to our code, once a Player joins the game we’d wanna attempt to load their data if they have any

We also want to include a certain key for every player so that each one has different individual data, so we can go & get the Player’s ID:

local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")

local function LoadData(Player)
    local stats = Instance.new("Folder")
    stats.Name = "leaderstats"
    stats.Parent = Player

    local RandomValue = Instance.new("IntValue")
    RandomValue.Name = "Value1"
    RandomValue.Parent = Player
    
    local PlayerID = Player.UserId
    local Data
    
    local Success, Whoops = pcall(function()
        Data = LocalData:GetAsync(PlayerID)
    end)
    
    if Success then
        print("Loaded data to: "..Player.Name.."!")
        RandomValue.Value = Data.RandomValue
    else
        warn("Something else happened!")
    end
end

local function SaveData(Player)
    local PlayerID = Player.UserId

    local Data = {
        RandomValue = Player.leaderstats.RandomValue.Value
    }

    local Success, Whoops = pcall(function()
        LocalData:SetAsync(PlayerID, Data)
    end)

    if Success then
        print("Saved data to: "..Player.Name.."!")
    else
        warn("An error has occurred saving the data! Please check the Dev Console!")
        warn(Whoops)
    end
end

game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)

The pcall will check if we have any sort of Data that’s already been saved for the player, if there is then we can save/load that! We also wanna include our Data variable inside our SaveData function in a table, in case if we want to include more data values to save!

Step 3: Last Case Scenario

If for some reason your game suddenly has an update or PlayerRemoving isn’t working, chances are your Data has not saved properly

Well, how could you fix that? We use a function called: BindToClose() which fires when the game unexpectedly shuts down

We can connect that with our SaveData event by getting all the players in this Instance:

local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")

local function LoadData(Player)
    local stats = Instance.new("Folder")
    stats.Name = "leaderstats"
    stats.Parent = Player

    local RandomValue = Instance.new("IntValue")
    RandomValue.Name = "Value1"
    RandomValue.Parent = Player
    
    local PlayerID = Player.UserId
    local Data
    
    local Success, Whoops = pcall(function()
        Data = LocalData:GetAsync(PlayerID)
    end)
    
    if Success then
        print("Loaded data to: "..Player.Name.."!")
        RandomValue.Value = Data.RandomValue
    else
        warn("Something else happened!")
    end
end

local function SaveData(Player)
    local PlayerID = Player.UserId

    local Data = {
        RandomValue = Player.leaderstats.RandomValue.Value
    }

    local Success, Whoops = pcall(function()
        LocalData:SetAsync(PlayerID, Data)
    end)

    if Success then
        print("Saved data to: "..Player.Name.."!")
    else
        warn("An error has occurred saving the data! Please check the Dev Console!")
        warn(Whoops)
    end
end

game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)

game.BindToClose(function()
    for _, Player in pairs(game.Players:GetPlayers()) do
        SaveData(Player)
    end
end)

We can get all the players using a loop, and saving everyone’s individual data this way!

If you hopefully followed all the steps, you should get something like this!

local DataService = game:GetService("DataStoreService")
local LocalData = DataService:GetDataStore("Test")

local function LoadData(Player)
    local stats = Instance.new("Folder")
    stats.Name = "leaderstats"
    stats.Parent = Player

    local RandomValue = Instance.new("IntValue")
    RandomValue.Name = "Value1"
    RandomValue.Parent = Player
    
    local PlayerID = Player.UserId
    local Data
    
    local Success, Whoops = pcall(function()
        Data = LocalData:GetAsync(PlayerID)
    end)
    
    if Success and Data ~= nil then
        print("Loaded data to: "..Player.Name.."!")
        RandomValue.Value = Data.RandomValue
    else
        warn("Something else happened!")
    end
end

local function SaveData(Player)
    local PlayerID = Player.UserId

    local Data = {
        RandomValue = Player.leaderstats.RandomValue.Value
    }

    local Success, Whoops = pcall(function()
        LocalData:SetAsync(PlayerID, Data)
    end)

    if Success then
        print("Saved data to: "..Player.Name.."!")
    else
        warn("An error has occurred saving the data! Please check the Dev Console!")
        warn(Whoops)
    end
end

game.Players.PlayerAdded:Connect(LoadData)
game.Player.PlayerRemoving:Connect(SaveData)

game.BindToClose(function()
    for _, Player in pairs(game.Players:GetPlayers()) do
        SaveData(Player)
    end
end)
3 Likes

i love how you typed 45 minutes for this <3

Technically 30 minutes but thanks

I might have a couple things wrong so do correct me if you see any

1 Like

In the GetAsync portion, you should include a part that checks if the data exists as to not cause any errors to occur if it’s nil.


Yes

2 Likes

Would it be something relevant like this?

    if Success and Data ~= nil then
        print("Loaded data to: "..Player.Name.."!")
        RandomValue.Value = Data.RandomValue
    else
        warn("Something else happened!")
    end
1 Like

Thank you so much, I DMED you too lol.

1 Like