Saving model name & colour

Hi, I’m trying to use datastores to save a player’s model name and its colours, then load this in when the player joins. However, an error is showing up in the output as:
attempt to index nil with 'FindFirstChild'

Serverscript Code:

-- Save Function
local function SaveData(Player, Character)
	local data = {}
	local DroidModel
	local key = Player.UserId
	
	for i,v in pairs(DroidModule) do
		if Character:FindFirstChild(v.Title) then
			DroidModel = v.Title
		end
	end
	
	local DroidBody = Character:FindFirstChild(DroidModel)
	
	for i,v in (DroidBody:GetChilden()) do
		table.insert(data, {
			DroidModel,
			
			v.Primary.Head.Color.R,
			v.Primay.Head.Color.G,
			v.Primary.Head.Color.B,
			
			v.Secondary.Head.Color.R,
			v.Secondary.Head.Color.G,
			v.Secondary.Head.Color.B,
			
			v.Tertiary.Head.Color.R,
			v.Tertiary.Head.Color.G,
			v.Tertiary.Head.Color.B,
		})
	end
	
	local success, err
	
	repeat
		success, err = pcall(function()
			DataStore:SetAsync(key, function()
				return data
			end)
		end)
		
		task.wait(1)
	until success
	
	if not success then
		warn("Failed to save data: " .. tostring(err))
	end
end
1 Like

Have you waited for the players character to load?

Player.CharacterAdded:Wait()

which line is the error on???

if Character:FindFirstChild(v.Title) then

1 Like

no need for an if statement, just do:

local Character = player.Character or player.CharacterAdded:Wait()
1 Like

Hi, this fixed the errors but generally the model doesn’t seem to be saving/loading correctly. Do you mind taking a look at the code?

-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")

-- Droid Module
local DroidModule = require(ReplicatedStorage:FindFirstChild("Droids").DroidModule)

-- RemoteEvent
local DroidEvent = ReplicatedStorage:FindFirstChild("Droids").DroidEvent

-- Datastore
local DataStore = DataStoreService:GetDataStore("Development1")

-- Save Function
local function SaveData(Player, Character)
	local data = {}
	local DroidModel
	local key = Player.UserId
	
	for i,v in pairs(DroidModule) do
		if Player.Character:FindFirstChild(v.Title) then
			DroidModel = v.Title
		end
	end
	
	local DroidBody = Character:FindFirstChild(DroidModel)
	
	for i,v in (DroidBody:GetChilden()) do
		table.insert(data, {
			DroidModel,
			
			v.Primary.Head.Color.R,
			v.Primay.Head.Color.G,
			v.Primary.Head.Color.B,
			
			v.Secondary.Head.Color.R,
			v.Secondary.Head.Color.G,
			v.Secondary.Head.Color.B,
			
			v.Tertiary.Head.Color.R,
			v.Tertiary.Head.Color.G,
			v.Tertiary.Head.Color.B,
		})
	end
	
	local success, err
	
	repeat
		success, err = pcall(function()
			DataStore:SetAsync(key, function()
				return data
			end)
		end)
		
		task.wait(1)
	until success
	
	if not success then
		warn("Failed to save data: " .. tostring(err))
	end
end

-- Load Function
function LoadData(Player, Character)
	
	local key = Player.UserId
	local success, err
	local data
	
	repeat
		success, err = pcall(function()
			data = DataStore:GetAsync(key)
		end)

	until success
	
	if not data then return end
	
	if success then
		for i,v in ipairs(data) do
			local NewDroid = ReplicatedStorage.Droids:FindFirstChild(v[1]):Clone()
			
			for i,primary in (NewDroid.Body.Primary) do
				primary.Color = Color3.fromRGB(data[2], data[3], data[4])
			end
			
			for i,secondary in (NewDroid.Body.Secondary) do
				secondary.Color = Color3.fromRGB(data[5], data[6], data[7])
			end
			
			for i,tertiary in (NewDroid.Body.Tertiary) do
				tertiary.Color = Color3.fromRGB(data[8], data[9], data[10])
			end
			NewDroid.Parent = Player.Character
		end
	else
		warn("Failed to load data: " .. tostring(err))
	end
end

-- Player
game.Players.PlayerAdded:Connect(function(Player)
	local Character = Players:GetPlayerFromCharacter(Player) or Player.CharacterAdded:Wait()
	
	if Player:WaitForChild("Droids").Owned.Value == true then
		LoadData(Player, Character)
	end
	
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Character = Players:GetPlayerFromCharacter(Player) or Player.CharacterAdded:Wait()
	
	SaveData(Player, Character)
end)

When they load in for the first time they won’t have data so this would always be true leading the code below to not run. You need to auto assign some data. Also repeatedly getting / saving data might lead to your server getting rate limited

Edit: Can you add some print the data right after you retrieve the data and before you save?

Hi, the printing doesn’t seem to work. Might need to rewrite the code.