Character Slots Help

I’ve been stumped on this for a while, I’m not sure what I could do to achieve multiple slot data on a single data store. Here’s what I have so far:

local storage = game.ServerStorage.Data
local Service = game:GetService("DataStoreService")
local Datastore = Service:GetDataStore("PlayerDataTest39")
local RaceData = require(game.ServerScriptService.Data.RaceData)
local RaceRarities = require(game.ServerScriptService.Data.RaceRarities)
local VarientRarities = require(game.ServerScriptService.Data.VarientRarities)

function AddSlotData(Parent)
	local Race = Instance.new("StringValue")
	Race.Name = "Race"
	Race.Parent = Parent

	local RaceVarient = Instance.new("StringValue")
	RaceVarient.Name = "RaceVarient"
	RaceVarient.Parent = Parent

	local Armor = Instance.new("StringValue")
	Armor.Name = "Armor"
	Armor.Parent = Parent

	local Merit = Instance.new("IntValue")
	Merit.Name = "Merit"
	Merit.Parent = Parent

	-- Stats --

	local Vigor = Instance.new("IntValue")
	Vigor.Name = "Vigor"
	Vigor.Parent = Parent

	local Agility = Instance.new("IntValue")
	Agility.Name = "Agility"
	Agility.Parent = Parent
end

function AddFolders(player)
	local CharFolder = Instance.new("Folder")
	CharFolder.Name = (player.Name)
	CharFolder.Parent = storage

	local SlotA  = Instance.new("Folder")
	SlotA.Name = "SlotA"
	SlotA.Parent = CharFolder

	local SlotB  = Instance.new("Folder")
	SlotB.Name = "SlotB"
	SlotB.Parent = CharFolder

	local SlotC  = Instance.new("Folder")
	SlotC.Name = "SlotC"
	SlotC.Parent = CharFolder

	AddSlotData(SlotA)
	AddSlotData(SlotB)
	AddSlotData(SlotC)

	local SlotChoice = Instance.new("StringValue")
	SlotChoice.Name = "SlotChoice"
	SlotChoice.Value = "A"
	SlotChoice.Parent = CharFolder
end

function NewData(player, PlayerData)
	-- No Data -- 

	local function Rarity(Table)
		local RNG = Random.new(); 
		local Counter = 0;
		for i, v in pairs(Table) do
			Counter += Table[i][2]
		end
		local Chosen = RNG:NextNumber(0, Counter);
		for i, v in pairs(Table) do
			Counter -= Table[i][2]
			if Chosen > Counter then
				return Table[i][1]
			end
		end
	end

	local Race = Rarity(RaceRarities)
	print(Race)
	PlayerData.Race.Value = Race

	local Varient = Rarity(VarientRarities[Race])
	print(Varient)
	PlayerData.RaceVarient.Value = Varient

	PlayerData.Armor.Value = "Default"

	PlayerData.Merit.Value = 0

	PlayerData.Vigor.Value = 0

	PlayerData.Agility.Value = 0
end

function DataLoad(player)
	local PlayerData = game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local slot = PlayerData.SlotChoice.Value
	PlayerData = PlayerData["Slot"..slot]
	local ID = player.UserId
	local data 
	local success, errormessage = pcall(function()
		data = Datastore:GetAsync(ID)
	--[[	data = data["Slot"..slot]
		print(data)]]
	end)
	if success then
		if data == nil then
			NewData(player, PlayerData)
		else
			if PlayerData == data["Slot"..slot].Slot then
				-- Has Data --
				PlayerData.Race.Value = data["Slot"..slot].Race
				PlayerData.RaceVarient.Value = data["Slot"..slot].RaceVarient
				PlayerData.Armor.Value = data["Slot"..slot].Armor
				PlayerData.Merit.Value = data["Slot"..slot].Merit
			else
				print("New Slot")
				NewData(player, PlayerData)
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	AddFolders(player)

	DataLoad(player)

	repeat wait(0.1) until game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local StatsLoaded = Instance.new("Folder")
	StatsLoaded.Name = "StatsLoaded"
	StatsLoaded.Parent = game.ServerStorage["Data"]:FindFirstChild(player.Name)

	player.CharacterAdded:Connect(function(char)

	end)
end)

function save(player)
	local PlayerData = game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local slot = PlayerData.SlotChoice.Value
	PlayerData = PlayerData["Slot"..slot]
	local ID = player.UserId
	local data = {
		SlotA = {
			Slot = "SlotA";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
		SlotB = {
			Slot = "SlotB";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
		SlotC = {
			Slot = "SlotC";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
	}
	print(data)
	local success, errormessage = pcall(function()
		Datastore:SetAsync(ID, data)
	end)

	if success then
		print("Saved "..player.Name.."s Data")
	else
		print("error")
	end
end

game.Players.PlayerRemoving:Connect(function(player)
	save(player)
end)

I’m completely lost. Could anyone bless me with some assistance!
(I’m trying to follow this: Help on creating Data Character Slots)

2 Likes

Try doing this? I’m not sure if this will solve your problem

local storage = game.ServerStorage.Data
local Service = game:GetService("DataStoreService")
local Datastore = Service:GetDataStore("PlayerDataTest39")
local RaceData = require(game.ServerScriptService.Data.RaceData)
local RaceRarities = require(game.ServerScriptService.Data.RaceRarities)
local VarientRarities = require(game.ServerScriptService.Data.VarientRarities)

function AddSlotData(Parent)
	local Race = Instance.new("StringValue")
	Race.Name = "Race"
	Race.Parent = Parent

	local RaceVarient = Instance.new("StringValue")
	RaceVarient.Name = "RaceVarient"
	RaceVarient.Parent = Parent

	local Armor = Instance.new("StringValue")
	Armor.Name = "Armor"
	Armor.Parent = Parent

	local Merit = Instance.new("IntValue")
	Merit.Name = "Merit"
	Merit.Parent = Parent

	-- Stats --

	local Vigor = Instance.new("IntValue")
	Vigor.Name = "Vigor"
	Vigor.Parent = Parent

	local Agility = Instance.new("IntValue")
	Agility.Name = "Agility"
	Agility.Parent = Parent
end

function AddFolders(player)
	local CharFolder = Instance.new("Folder")
	CharFolder.Name = (player.Name)
	CharFolder.Parent = storage

	local SlotA  = Instance.new("Folder")
	SlotA.Name = "SlotA"
	SlotA.Parent = CharFolder

	local SlotB  = Instance.new("Folder")
	SlotB.Name = "SlotB"
	SlotB.Parent = CharFolder

	local SlotC  = Instance.new("Folder")
	SlotC.Name = "SlotC"
	SlotC.Parent = CharFolder

	AddSlotData(SlotA)
	AddSlotData(SlotB)
	AddSlotData(SlotC)

	local SlotChoice = Instance.new("StringValue")
	SlotChoice.Name = "SlotChoice"
	SlotChoice.Value = "A"
	SlotChoice.Parent = CharFolder
end

function NewData(player, PlayerData)
	-- No Data -- 

	local function Rarity(Table)
		local RNG = Random.new(); 
		local Counter = 0;
		for i, v in pairs(Table) do
			Counter += Table[i][2]
		end
		local Chosen = RNG:NextNumber(0, Counter);
		for i, v in pairs(Table) do
			Counter -= Table[i][2]
			if Chosen > Counter then
				return Table[i][1]
			end
		end
	end

	local Race = Rarity(RaceRarities)
	print(Race)
	PlayerData.Race.Value = Race

	local Varient = Rarity(VarientRarities[Race])
	print(Varient)
	PlayerData.RaceVarient.Value = Varient

	PlayerData.Armor.Value = "Default"

	PlayerData.Merit.Value = 0

	PlayerData.Vigor.Value = 0

	PlayerData.Agility.Value = 0
end

function DataLoad(player)
	local PlayerData = game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local slot = PlayerData.SlotChoice.Value
	PlayerData = PlayerData["Slot"..slot]
	local ID = player.UserId
	local data 
	local success, errormessage = pcall(function()
		data = game:GetService("HttpService"):JSONDecode(Datastore:GetAsync(ID))
	--[[	data = data["Slot"..slot]
		print(data)]]
	end)
	if success then
		if data == nil then
			NewData(player, PlayerData)
		else
			if PlayerData == data["Slot"..slot].Slot then
				-- Has Data --
				PlayerData.Race.Value = data["Slot"..slot].Race
				PlayerData.RaceVarient.Value = data["Slot"..slot].RaceVarient
				PlayerData.Armor.Value = data["Slot"..slot].Armor
				PlayerData.Merit.Value = data["Slot"..slot].Merit
			else
				print("New Slot")
				NewData(player, PlayerData)
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	AddFolders(player)

	DataLoad(player)

	repeat wait(0.1) until game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local StatsLoaded = Instance.new("Folder")
	StatsLoaded.Name = "StatsLoaded"
	StatsLoaded.Parent = game.ServerStorage["Data"]:FindFirstChild(player.Name)

	player.CharacterAdded:Connect(function(char)

	end)
end)

function save(player)
	local PlayerData = game.ServerStorage["Data"]:FindFirstChild(player.Name)
	local slot = PlayerData.SlotChoice.Value
	PlayerData = PlayerData["Slot"..slot]
	local ID = player.UserId
	local data = {
		SlotA = {
			Slot = "SlotA";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
		SlotB = {
			Slot = "SlotB";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
		SlotC = {
			Slot = "SlotC";
			Race = PlayerData.Race.Value;
			Armor = PlayerData.Armor.Value;
			RaceVarient = PlayerData.RaceVarient.Value;
			Merit = PlayerData.Merit.Value;
		};
	}
	print(data)
	local success, errormessage = pcall(function()
		Datastore:SetAsync(ID, game:GetService("HttpService"):JSONEncode(data))
	end)

	if success then
		print("Saved "..player.Name.."s Data")
	else
		print("error")
	end
end

game.Players.PlayerRemoving:Connect(function(player)
	save(player)
end)

(from How to save a Dictionary to a DataStore? - #2 by SSSpencer413)

I dont have a problem with implementing dictionaries into a datastore, checking which slot the player is playing on, and saving that data into the dictionary while not overwriting other slots data.

When player leaves the game, use GetAsync to get the player’s data. Then detect which slot the player is currently playing on using SlotChoice and use SetAsync with the taken data and the chosen slot with the current player data.

You can also store player’s data in a table so you don’t need to use GetAsync for PlayerRemoving