Datastore 2 tables!

So the game I am making is going to have 30+ players in a lobby. The datastore I currently have is datastore2 and it makes instances and saves armour in a string using JSONEncode. I realised is the best way to do it, as in will this be more for the server to maintain, or is it best to use table?

My current script;

local HttpService = game:GetService("HttpService")
local players = game:GetService("Players")

local Datastore2 = require(1936396537) -- Get datastore2 module
Datastore2.Combine("Inventory", "Gold", "Armour", "Potions", "Weapons","Health","Damage","MagicDamage","Level", "Experience","MaxExperience" )

local function addPlayerData(player)
	
	--// Creates a folder to hold the values and subfolders
	local dataSaveFolder = Instance.new("Folder")
	dataSaveFolder.Name = player.Name.."_Data"
	dataSaveFolder.Parent = workspace.Userdata
	
	--// Inventory System
	local Inventory = Instance.new("Folder", dataSaveFolder); Inventory.Name = "Inventory"
	local playerGold = Instance.new("IntValue", Inventory); playerGold.Name = "Gold"
    local playerArmour = Instance.new("StringValue", Inventory); playerArmour.Name = "Armour"
    local playerPotions = Instance.new("StringValue", Inventory); playerPotions.Name = "Potions"
	local playerWeapons = Instance.new("StringValue", Inventory); playerWeapons.Name = "Weapons"
	
	--// Player Stats
	local playerHealth = Instance.new("IntValue", Inventory); playerHealth.Name = "Health"
	local playerDamage = Instance.new("IntValue", Inventory); playerDamage.Name = "Damage"
	local playerMagicDmg = Instance.new("IntValue", Inventory); playerMagicDmg.Name = "MagicDamage"
	
	--// Players Level
	local LevelSystem = Instance.new("Folder", dataSaveFolder); LevelSystem.Name = "LevelSystem"
	local playerLevel = Instance.new("IntValue", LevelSystem); playerLevel.Name = "Level"
	local playerXp = Instance.new("IntValue", LevelSystem); playerXp.Name = "Experience"
	local playerMaxXp = Instance.new("IntValue", LevelSystem); playerMaxXp.Name = "MaxExperience" 
	
	--// Gets DataStores and initial values
    local goldStore = Datastore2("Gold", player); local goldStoreData = goldStore:Get()
    local armourStore = Datastore2("Armour", player); local armourStoreData = armourStore:Get({ })
    local potionsStore = Datastore2("Potions", player); local potionsStoreData = potionsStore:Get({ })
	local weaponsStore= Datastore2("Weapons", player); local weaponsStoreData = weaponsStore:Get({ })
	local healthStore = Datastore2("Health", player); local healthStoreData = healthStore:Get()
	local damageStore = Datastore2("Damage", player); local damageStoreData = damageStore:Get()
	local magicStore = Datastore2("MagicDamage", player); local magicStoreData = magicStore:Get()
	local levelStore = Datastore2("Level", player); local levelStoreData = levelStore:Get()
	local xpStore = Datastore2("Experience", player); local XpStoreData = xpStore:Get()
	local maxxpStore = Datastore2("MaxExperience",player); local MaxXpStoreData = maxxpStore:Get()
	
	--// Updates player values with JSON encoded tables
    playerArmour.Value = HttpService:JSONEncode(armourStoreData)
    playerPotions.Value = HttpService:JSONEncode(potionsStoreData) 
    playerWeapons.Value = HttpService:JSONEncode(weaponsStoreData) 
	
	--// Updates player values with non-table values
	playerGold.Value = goldStoreData
	playerHealth.Value = healthStoreData
	playerDamage.Value = damageStoreData
	playerMagicDmg.Value = magicStoreData
	playerLevel.Value = levelStoreData
	playerXp.Value = XpStoreData
	playerMaxXp.Value = MaxXpStoreData
	
	--// Checks to see when data changes and syncs it to DS2
	playerGold.Changed:Connect(function(newVal)
		goldStore:Set(newVal)
	end)
	playerArmour.Changed:Connect(function(newVal)
		goldStore:Set(newVal)
	end)
	playerPotions.Changed:Connect(function(newVal)
		goldStore:Set(newVal)
	end)
	playerWeapons.Changed:Connect(function(newVal)
		goldStore:Set(newVal)
	end)
	playerHealth.Changed:Connect(function(newVal)
		healthStore:Set(newVal)
	end)
	playerDamage.Changed:Connect(function(newVal)
		damageStore:Set(newVal)
	end)
	playerMagicDmg.Changed:Connect(function(newVal)
		magicStore:Set(newVal)
	end)
	playerLevel.Changed:Connect(function(newVal)
		levelStore:Set(newVal)
	end)
	playerXp.Changed:Connect(function(newVal)
		xpStore:Set(newVal)
	end)
	playerMaxXp.Changed:Connect(function(newVal)
		maxxpStore:Set(newVal)
	end)
	
	--// Checks to make sure that everyone has a saveDataFolder
	local playerList = game.Players:GetPlayers()
	for i = 1, #playerList do
		if workspace.Userdata:FindFirstChild(playerList[i].Name.."_Data") == nil then
			addPlayerData(playerList[i])
		end
	end
	
end
game.Players.PlayerAdded:Connect(addPlayerData)

local function removePlayerData(player)
	
	--// Destroys the player's dataSaveFolder
	local dataSaveFolder = workspace.Userdata:FindFirstChild(player.Name.."_Data")
	dataSaveFolder:Destroy()
	
		--// Removes any dataSaveFolders that were missed for some reason
	local dataFolderList = workspace.Userdata:GetChildren()
	for i = 1, #dataFolderList do
		if dataFolderList[i]:IsA("Folder") then
			if game.Players:FindFirstChild(string.gsub(dataFolderList[i].Name, "_Data", "")) == nil then
				dataFolderList[i]:Destroy()
			end
		end
	end
		
end
game.Players.PlayerRemoving:Connect(removePlayerData)

local function manualAddPlayerData(player)
	if workspace.Userdata:FindFirstChild(player.Name.."_Data") == nil then
		addPlayerData(player)
	end
end
workspace.Userdata.ManualLoadData.OnServerEvent:Connect(manualAddPlayerData)

Use a table for the stats and you save it right after.

This script is unnecessarily long for what it’s trying to accomplish. Just use tables. They’re already JSON formatted (unless you use Roblox Custom variables like Color3, BrickColor, UDim2, Vector3, etc.) and it would be way easier to manage then this.

I have one question how do I actual save a table, Would just be table_Name:Set()

Tables automatically save… You just have to use the following to update the table.

table.insert(TABLE_NAME, NEW_DATA)
-- or
TABLE_NAME["NEW_DATA"] = NEW_DATA2

image

So if I had something like this and I added to add gold I Would :Increment(amount, Table_Name)

local DataStore = game:GetService("DataStoreService"):GetDataStore("MyDataStore")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
  if DataStore:GetAsync(("%s-data"):format(Player.UserId)) then
    -- Player already has data
  else
    -- First time player played
  end
  -- For example, let's set their data.
  DataStore:SetAsync(("%s_data"):format(Player.UserId), {
    Gold = 10,
    Levels = {
      Level = 1
    }
  })
end)

How would I change the value like gold and level?

Sorry for the questions.

local Table = {
  Gold = 10,
  Inventory = {
    Armour = {},
    Potions = {},
    Weapons = {}
  },
  Stats = {
    Health = 100,
    Damage = 5,
    Defense = 5,
    ["Magic Damage"] = 5
  },
  Levels = {
    Level = 1,
    Experience = 0,
    MaxExperience = 0
  }
}

Table.Gold = 50 -- Changes the amount of Gold to 50
Table.Levels.Level = 2 -- Changes the player's level to 2

-- Save it as a table to DataStore2
2 Likes

So can I create a table in a module script and in the dataStore script can I require the table, would this work?

I’m not responding anymore after this post.
Yes. You can create a table from a ModuleScript (or audit it from a ModuleScript) as long as it’s returning the table back (if required, unless you’re saving with the ModuleScript and don’t require it to be sent back)

Alright, Thanks for your help :heart:

My recommendation is to use a dictionary table for your Stats for example

local dataToSave = {gold = gold.Value, health = playerHealth.Value} and so on
DataStore2(“PlayerData”, self._obj):Set(dataToSave)

and then to retrieve it, just use

local dataTemplate = {gold = 0, health = 100} – Use default values
local data = DataStore2(“PlayerData”, player):Get(dataTemplate);

and then assign values like

playerGold.Value = data.gold – Do this for all the values you’re saving/loading

2 Likes