The state only changes when the datastore opens closes or is destroys
Okay, got it. Thanks for such a quick response. Iāve fixed it by adding dataStore:Open() to the script where I update dataSore. Should I use this approach to update the folders under player or should I use another event such as Saving?
You should open when the player enters the game and destroy when they leave
I cover this in my basics video
Yes Iāve watched it. But Iām using your datastore to keep track of quest progression, inventory, skills etc. So, gui needs to update quickly when new item is added or a quest is progressed. Like in your video (You used leaderstats folder to demonstrate), Iām getting the data from datastore and storing inside dedicated folders in Player. When data changes in datastore, I copy the new data in corresponding folders. Like this:
Iām confused why quest progression doesnāt update, even tough stats, skills do update. (If I relog quest progress updates, but does not update untill that)
I donāt see you updating the attributes when the humanoid dies
In such of factions/groups (non-player related data), how would this be able to function for leaderboards and such for factions?
Iām updating it with this line: datastore.Value.ActiveQuests[1].Progression += 1
Nevertheless, Iāve fixed this issue by changing my code to this:
Thank you for your replies. Youāve lead me to right direction.
You would save the value in a separate ordered datastore
OrderedDataStore:SetAsync(dataStore.Value.Coins)
Doesnāt really answer the question on how this can handle non-player data such as factions.
Depends on how your factions work but It might be better to do a no cache approach and just use UpdateAsync every time you want to write data to the factions datastore
For faction/crew I wouldnāt use any datastore module that use Session-Locking,so you have to make your own and use UpdateAsync
I am using your datastore but Iām new to coding, I just wanna know how do I save an object in the datastore? I have this Template which look really bad.
my first question is how do I use an array or maybe it is a table.
I mean like this
STATUS= {"STR","AGI","INT","STR"},
this the the current template code. cause I donāt know how to get the data from STATUS
local DataStoreModule = require(game.ServerScriptService.DataStore)
local template = {
-------CURRENCY-------
Level = 0,
Coins = 0,
-------STATUS-------
STR = 0,
AGI = 0,
INT = 0,
Wood = 0,
-------BIRTH-------
StartingPoints = "Unknown",
-------ARMOR-------
Head = "NONE",
Torso = "NONE",
Gloves = "NONE",
Legs = "NONE",
Shoes = "NONE",
--ARMOR INVENTORY
Inventory = {},
-------RESOURCES-------
Batteries = 0,
Copper = 0,
Gold = 0,
Glass = 0,
Grapes = 0,
Paper = 0,
Metal = 0,
Plastic = 0,
Rubber = 0,
-------RESOURCES-------
DeveloperProducts = {},
}
game.Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
if dataStore:Open(template) ~= "Success" then print(player.Name, "failed to open")
elseif dataStore:Open(template) == "Success" then print(player.Name, "Datastore was opened")
print(dataStore.State)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
dataStore:Destroy()
print(dataStore.State)
end)
WARNING: lot of grammatical Error
I also have this second problem, I tried using the crafting script made by HowToRoblox and tried to put the data which is an object.
AS you can see, I tried putting the item in the plr.ArmorInventory then scan the items inside of it then send the data to dataStore.ArmorInventory.Inventory
local rs = game:GetService("ReplicatedStorage"):WaitForChild("Crafting")
local Remotes = game.ReplicatedStorage:WaitForChild("REvents"):WaitForChild("RE_CRAFTING")
local items = rs:WaitForChild("CraftableItems")
local recipes = require(rs:WaitForChild("Recipes"))
local DataStoreModule = require(game.ServerScriptService.DataStore)
Remotes.OnServerEvent:Connect(function(plr:Player, itemToCraft:string)
itemToCraft = items:FindFirstChild(itemToCraft)
if itemToCraft then
local recipeForItem = recipes[itemToCraft]
if recipeForItem then
for resource, amount in pairs(recipeForItem) do
local plrAmount = plr.Resources[resource].Value
if plrAmount < amount then
return
end
end
for resource, amount in pairs(recipeForItem) do
local resourceValue = plr.Resources[resource]
resourceValue.Value -= amount
end
if plr.Character then
local dataStore = DataStoreModule.find("Player", plr.UserId)
itemToCraft:Clone().Parent = plr.ArmorInventory
local InventoryItems = plr.ArmorInventory
if InventoryItems then
for index, item in pairs(InventoryItems:GetChildren()) do
dataStore.ArmorInventory.Inventory = item --I tried to access the Inventory from template
print(item)
end
end
print("Armor Save")
end
Remotes:FireClient(plr, "CRAFT SUCCESS")
end
end
end)
If you want to save instances/objects you will have to serialize it and de-serialize it. Here is how you can do it:
maybe you want something like this?
local template = {
Level = 0,
StartingPoint = "Unknown",
Stats = {
Strength = 0,
Agility = 0,
Intelligence = 0,
},
Armor = {
Head = "NONE",
Torso = "NONE",
Gloves = "NONE",
Legs = "NONE",
Shoes = "NONE",
},
Resources = {
Coins = 0,
Batteries = 0,
Copper = 0,
Gold = 0,
Glass = 0,
Grapes = 0,
Paper = 0,
Metal = 0,
Plastic = 0,
Rubber = 0,
Wood = 0,
},
Inventory = {},
}
then to get the data from Stats
you simply do
print(datastore.Value.Stats.Strength)
or if you want to loop all stats you do
for index, value in datastore.Value.Stats do
print(index, value)
end
to add a item to the inventory you can do
table.insert(dataStore.Value.Inventory, item.Name)
then you can use the name to find the item inside a items folder in server storage
-- get the first item name from the inventory table
local itemName = dataStore.Value.Inventory[1]
-- use the name to clone the item from the items folder
local item = game.ServerStorage.Items[itemName]:Clone()
-- parent the item into workspace
item.Parent = workspace
I got it and I found out that I donāt really understand what Does Value
Really stand for in ādatastore.Value.Stats.Strengthā or in the Datastore module. Can you explain it for me?
.Value
is used to access all the data in the datastore.
Owww, thanks I got it now. Iāll stop sending reply after this to avoid spam.
Note: the edited reply is all about saying thanks.
Sorry to ask again but I have been wondering about what is wrong within my code (Iām new to coding btw).
----This is the template
local DataStoreModule = require(game.ServerScriptService.DataStore)
local template = {
leaderstats = {
Level = 0,
Coins = 0,
},
StartingPoint = {
FirstTime = "Unknown",
BirthStarting = "Unknown",
},
FirstTime = {},
Stats = {
STR = 0,
AGI = 0,
INT = 0,
},
Armors = {
HeadGear = "NONE",
Top = "NONE",
Gloves = "NONE",
Bottom = "NONE",
Shoes = "NONE",
},
Resources = {
Batteries = 1,
Copper = 0,
Gold = 0,
Glass = 0,
Grapes = 0,
Paper = 0,
Metal = 0,
Plastic = 0,
Rubber = 0,
Wood = 0,
},
Inventory = {},
ArmorInventory = {
HeadGearInventory =
{
Hotcake = 0,
Spag = 0,
},
TopInventory = {
Basic_Top = 0,
},
GlovesInventory = {
Basic_Gloves = 0,
},
BottomInventory = {
Basic_Pants = 0,
},
ShoesInventory = {
Basic_Shoes = 0,
},
},
DeveloperProducts = {},
}
game.Players.PlayerAdded:Connect(function(player)
local dataStore = DataStoreModule.new("Player", player.UserId)
if dataStore:Open(template) ~= "Success" then print(player.Name, "failed to open")
elseif dataStore:Open(template) == "Success" then print(player.Name, "Datastore was opened")
print(dataStore.State)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
dataStore:Destroy()
print(dataStore.State)
end)
I also have this code which is responsible in changing the data from dataStore.Resources, it indeed change the value and save it however when printing the data from it whenever the player joined it printed 0 just like the other value or nil. which I believed to be the default value.
PROBLEM or Not?
- The data always send 0 or nil even do it does have a higher value.
This is an example of functions I have been using to add or set a value.
local module = {}
local DataStoreModule = require(game.ServerScriptService.DataStore)
-------------------------------RESOURCES-------------------------------
function module.Add (player, key, amount)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
if dataStore.State ~= true then return end
dataStore.Value[key] += amount
dataStore.Resources[key].Value = dataStore.Value[key]
end
function module.Divide (player, key, amount)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
if dataStore.State ~= true then return end
dataStore.Value[key] /= amount
dataStore.Resources[key].Value = dataStore.Value[key]
end
function module.Multiply (player, key, amount)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
if dataStore.State ~= true then return end
dataStore.Value[key] *= amount
dataStore.Resources[key].Value = dataStore.Value[key]
end
function module.Subtract (player, key, amount)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
if dataStore.State ~= true then return end
dataStore.Value[key] -= amount
dataStore.Resources[key].Value = dataStore.Value[key]
end
function module.Set (player, key, value)
local dataStore = DataStoreModule.find("Player", player.UserId)
if dataStore == nil then return end
if dataStore.State ~= true then return end
dataStore.Value[key] = value
dataStore.Resources[key].Value = value
end
return module
This is how I call the function and it indeed change and save the data.
Remotes.RE_RESOURCES.OnServerEvent:Connect(function(player: Player)
ManagerLeaderstats.Add(player, "Level", 1)
ManagerLeaderstats.Add(player, "Coins", 1)
ManagerResources.Add(player, "Batteries", 1)
end)