How can I simplify this?

So, I looked at your new code and noticed somethings you can do to make it cleaner. I recommend separating things into functions, and trying to attempt to get from datastores a few times before backing off.

So, I took some of my ideas and @GameMaster4268 to create this feel free to change it up for your project:

-- services
local DSS = game:GetService("DataStoreService"):GetDataStore("PlayerData")
local Players = game:GetService("Players")
local RS = game:GetService("RunService")

-- settings

local SAVE_INTERVAL = 300
local dataPrefix = "id_"

-- pcall trys
local maxTries = 5

-- define

local dataCache = {}

local TemplateData = {
	["leaderstats"] = {
		["Bounty"] = 0,
		["Kills"] = 0,
	},
	["playertats"] = {
		["Cash"] = 0,
		["Bank"] = 0
	},
	["playersettings"] = {
		["FirstPlay"] = false,
		["DataLoaded"] = false
	}
}

-- functions

local function LoadData(plr:Player, Data)
	
	if Data then
		
		-- Load Data
		
		for folderName, folderData in pairs(Data) do
			local folder = plr:FindFirstChild(folderName)
			if folder then
				for childName, Value in pairs(folderData) do
					local child = folder:FindFirstChild(childName)
					if child then
						child.Value = Value
					end
				end
			end
		end
		dataCache[plr.UserId] = Data
		
		print("Loaded "..plr.UserId.." Data!")
	else
		-- New player no need to load any data
		
		dataCache[plr.UserId] = TemplateData
		
		plr.playersettings.FirstPlay.Value = true
		
		print("Created New Data For "..plr.UserId.."!")
	end
	
	-- Set DataLoaded true
	plr.playersettings.DataLoaded.Value = true
end

local function SaveData(plr:Player)
	
	-- Check if data loaded
	
	local DataLoaded = plr:FindFirstChild("playersettings").DataLoaded
	
	if DataLoaded and DataLoaded.Value == false then
		warn("Player data not loaded! Trying to save!")
		return
	end
	
	local key = dataPrefix..plr.UserId
	
	local Data = {}
	
	-- Loop through the folders 
	
	for folderName, children in TemplateData do 
		local folder = plr:FindFirstChild(folderName)
		
		local folderData = {}
		
		if folder then
			for childName, _ in children do
				local child = folder:FindFirstChild(childName)
				if child then
					folderData[childName] = child.Value
				end
			end
		end
		Data[folderName] = folderData -- Add data to a dictionary
	end
	
	-- Save Data
	
	local success, err = pcall(function()
		DSS:SetAsync(key, Data)
	end)
	
	if not success then
		warn("Could not save "..plr.UserId.." data! Error:"..err)
	else
		print("Saved "..plr.UserId.." data!")
	end
end


-- on player added
Players.PlayerAdded:Connect(function(plr:Player)
	-- create instances
	for folderName, children in TemplateData do 
		
		local folderObject = Instance.new("Folder")
		folderObject.Name = folderName
		for childName, value in children do
			
			local typeOfValue = typeof(value) -- Type of value
			local childObject 
				
			if typeOfValue == "number" then
				childObject = Instance.new("NumberValue")
			elseif typeOfValue == "boolean"  then
				childObject = Instance.new("BoolValue")
			elseif typeOfValue == "string" then
				childObject = Instance.new("StringValue")
			end
			
			childObject.Name = childName
			childObject.Value = value
			childObject.Parent = folderObject
		end
		
		folderObject.Parent = plr
	end

	-- get playerdata
	local key, data = dataPrefix..plr.UserId, nil
	local success, err
	
	local trys = 0
	
	-- Atempt to get save data
	repeat
		success, err = pcall(function()
			data = DSS:GetAsync(key)
		end)
		trys += 1
	until success or trys == maxTries -- if success or reached max trys stop attempting to get data

	if success then
		LoadData(plr, data)
	elseif not success then
		plr:Kick("DataStoreService may be suffering connection difficulties at this moment, please try playing again later to avoid data loss.") -- replace with ui thing later
	end

	-- saves player data every 5 mins to prevent data loss
	task.spawn(function()
		while task.wait(SAVE_INTERVAL) do
			pcall(function()
				SaveData(plr)
			end)
		end
	end)

	-- on character added
	plr.CharacterAdded:Connect(function(char)
		char:WaitForChild("Humanoid").Died:Connect(function()
			local tag = char.Humanoid:FindFirstChild("creator")
			if tag and tag.Value then
				local ls = tag.Value:FindFirstChild("leaderstats")
				if ls then ls.Kills.Value += 1 end
			end
		end)
	end)
end)

-- on player removing
Players.PlayerRemoving:Connect(function(plr)
	SaveData(plr)
	dataCache[plr] = nil
end)

-- saves every player's data on server shutdown
if not RS:IsStudio() then
	game:BindToClose(function()
		for _, plr in (Players:GetPlayers()) do
			task.spawn(function()
				SaveData(plr)
				dataCache[plr] = nil
			end)
		end
	end)
end

By the way I tested it, and it works!