Suphi's DataStore Module

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:

1 Like

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
1 Like

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
1 Like

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.

1 Like

Owww, thanks I got it now. I’ll stop sending reply after this to avoid spam.

1 Like

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?

  1. 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)
1 Like

the first error says your trying to do a for loop with the value nil i was not able to see any for loops in the code you shared

the second error says your trying to get userid from nil so that shows that player is set to nil

1 Like

Good day sir thanks for reply, btw I wasn’t trying to find a way to fix that error. I want to know why the printed data send a value of nil or 0. What I really mean is the one with “Resources”, “Stats”, and “Leaderstats” at the first line.

1 Like

I don’t see a problem with the code you shared

2 Likes

I think the same too however the.

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

won’t work if the data didn’t have any value in it, however I think that would work because if didn’t have any value or it is their first time then the template would give a value from the template script like

local template = {
Level = 0,
}

I also edited the function to check if there is a value of 0 or nil

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
	if dataStore.Value[key] == 0 or nil then
		dataStore.Value[key] = amount
	else
		dataStore.Value[key] += amount
	end
	dataStore.Resources[key].Value = dataStore.Value[key]
end

But it still didn’t work, what I did to solve that problem from the time being is by using this function first to give a default value before changing any data.

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

Btw what is the use of the value in a template if it didn’t put a default value sir?
also the print from PlayerAdded in template script didn’t print either.

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") --didn't print this
	elseif dataStore:Open(template) == "Success" then print(player.Name, "Datastore was opened") nor this one.
	print(dataStore.State)
end

Could you do

print(dataStore.Value)

And showing me what it prints?

1 Like

I already know what cause the problem and it is indeed the way I change and read data.
I will share it here cause other people might need it.

Old Code

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.leaderstats[key].Value = dataStore.Value[key]
end

Updated and fix

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.leaderstats[key] = value   -- I didn't know that I should have added leaderstats cause I didn't understand what that Value mean at first.
	dataStore.leaderstats[key].Value = dataStore.Value.leaderstats[key]
end
2 Likes

I have never used any sort of data store for my games, but this resource seems to be done by a very skilled and trusted programmer (No like, seriously have any of you checked out his channel, he has tons of good tutorials).

So I will definitely give this over a try, instead of just using DataStore2.

2 Likes

exactly, who would join a discord server just to see the documentation