Welcome back to another tutorial. Today I'll be showing you how to use RbxWeb, which is a DataStoreService wrapper made by my friend movsb. I'll be using a rewritten version of it, so that it's more similar to the actual DataStoreService.
To get things started, let's require the module in our Main script.
local RbxWeb = require(3254046154)
Now that we have that, we need to initialize the module. You can either use MockDataStoreService made by buildthomas by passing the require function, or use the default DataStoreService by passing game. I'm gonna be using require because it's just easier that way and allows pseudo-DataStores on local files.
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
We should also setup our services and whatnot. The script should look like this afterwards.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
Now, we're gonna get a generic DataStore (which is just another name for GlobalDataStore). To do this, we have to call two functions, AddGeneric and GetGeneric.
The API for these functions are as follows:
RbxWeb::AddGeneric(string Key, string Scope, string Prefix: ""): GlobalDataStore RbxWeb::GetGeneric(GlobalDataStore DataRoot): GenericClass
Here's how I usually do it:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
local VERSION = "V1"
local GameDataStore = RbxWeb:GetGeneric(RbxWeb:AddGeneric(
"GameDataStore" .. (RunService:IsStudio() and "Testing" or "Release") .. VERSION,
"Global",
"PlayerData"
))
This will allow us to have separate DataStores depending on if you're testing the game or not. Now, we're gonna setup our PlayerAdded and PlayerRemoving connections.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
local VERSION = "V1"
local GameDataStore = RbxWeb:GetGeneric(RbxWeb:AddGeneric(
"GameDataStore" .. (RunService:IsStudio() and "Testing" or "Release") .. VERSION,
"Global",
"PlayerData"
))
local function PlayerAdded(Player)
end
local function PlayerRemoving(Player)
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)
I like to avoid calling DataStore methods too often, as I've had issues with that in the past and it results in data loss, and that's just a pain. The most I suggest is calling GetAsync once in PlayerAdded, and SetAsync if their data is null, and calling GetAsync once more in PlayerRemoving, followed by UpdateAsync. We should set that up now, along with a data template table.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
local VERSION = "V1"
local DATA_TEMPLATE = {
DataID = 0;
Points = 0;
}
local GameDataStore = RbxWeb:GetGeneric(RbxWeb:AddGeneric(
"GameDataStore" .. (RunService:IsStudio() and "Testing" or "Release") .. VERSION,
"Global",
"PlayerData"
))
local function PlayerAdded(Player)
local PlayerKey = GameDataStore:GetKey(Player.UserId)
local Success, PlayerData = GameDataStore:GetAsync(PlayerKey)
if Success and not PlayerData then
PlayerData = DATA_TEMPLATE
GameDataStore:SetAsync(PlayerKey, PlayerData)
end
end
local function PlayerRemoving(Player)
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)
Now that we have that done, we should probably create the Leaderstats for the player, so we can finish up PlayerRemoving.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
local VERSION = "V1"
local DATA_TEMPLATE = {
DataID = 0;
Points = 0;
}
local GameDataStore = RbxWeb:GetGeneric(RbxWeb:AddGeneric(
"GameDataStore" .. (RunService:IsStudio() and "Testing" or "Release") .. VERSION,
"Global",
"PlayerData"
))
local function PlayerAdded(Player)
local PlayerKey = GameDataStore:GetKey(Player.UserId)
local Success, PlayerData = GameDataStore:GetAsync(PlayerKey)
if Success and not PlayerData then
PlayerData = DATA_TEMPLATE
GameDataStore:SetAsync(PlayerKey, PlayerData)
end
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
local Points = Instance.new("IntValue")
Points.Name = "Points"
Points.Value = PlayerData.Points
Points.Parent = Leaderstats
end
local function PlayerRemoving(Player)
local Leaderstats = Player:FindFirstChild("leaderstats")
if Leaderstats then
end
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)
Note: I don't suggest using Leaderstats or ValueBase objects, and instead use a table. If requested enough, I'll show how that can be accomplished.
Now that we have that all done, let's finish our PlayerRemoving function. We're gonna call GetAsync once and then finish it up with UpdateAsync.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RbxWeb = require(3254046154)
RbxWeb:Initialize(require)
local VERSION = "V1"
local DATA_TEMPLATE = {
DataID = 0;
Points = 0;
}
local GameDataStore = RbxWeb:GetGeneric(RbxWeb:AddGeneric(
"GameDataStore" .. (RunService:IsStudio() and "Testing" or "Release") .. VERSION,
"Global",
"PlayerData"
))
local function PlayerAdded(Player)
local PlayerKey = GameDataStore:GetKey(Player.UserId)
local Success, PlayerData = GameDataStore:GetAsync(PlayerKey)
if Success and not PlayerData then
PlayerData = DATA_TEMPLATE
GameDataStore:SetAsync(PlayerKey, PlayerData)
end
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
local Points = Instance.new("IntValue")
Points.Name = "Points"
Points.Value = PlayerData.Points
Points.Parent = Leaderstats
end
local function PlayerRemoving(Player)
local Leaderstats = Player:FindFirstChild("leaderstats")
if Leaderstats then
local PlayerKey = GameDataStore:GetKey(Player.UserId)
local Success, PlayerData = GameDataStore:GetAsync(PlayerKey)
if Success and PlayerData then
GameDataStore:UpdateAsync(PlayerKey, function(OldData)
local PreviousData = OldData or DEFAULT_DATA
if PlayerData.DataID == PreviousData.DataID then
PlayerData.DataID = PlayerData.DataID + 1
PlayerData.Points = Leaderstats.Points.Value
return PlayerData
else
-- Don't save and lose data!
return nil
end
end)
end
end
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)
That's basically how to use RbxWeb. It's definitely my favorite module, since it's so much easier to use, and I haven't ever had data loss with it in any of my games.