I tried doing this:
game.Players.PlayerAdded:Connect(function(plr)
local toolsOwned = {}
local titlesOwned = {}
local style = ""
local title = plr.Character.Head.Nametag.Title.Text
But it breaks the entire script.
I tried doing this:
game.Players.PlayerAdded:Connect(function(plr)
local toolsOwned = {}
local titlesOwned = {}
local style = ""
local title = plr.Character.Head.Nametag.Title.Text
But it breaks the entire script.
Try printing what packed data is after you call GetAsync(). Also, put a print statement after your conditional where youâre checking to make sure packedData is a table. My guess is the script is evaluating that if statement to be false and itâs not changing âtitleâ, so it just appears to be ââ every time someone plays.
Also, Lua tables already JsonEncode and Decode themselves, so you donât need to do that.
All of the other values (Skips, Wins, Coins) are loading but the previoustitle is not. I think the problem is that there is nothing set in previoustitle so there is nothing so save/load. Can you help me with that?
Have you tried printing out what âtitleâ is equal to in your saveData function? If itâs equal to ââ then itâs not getting the text inside the pcall function.
Yeah, I think thats the issue. I donât know what to set it to though without the whole program breaking. I tried this:
local toolsOwned = {}
local titlesOwned = {}
local style = ""
local title = plr.Character.Head.Nametag.Title.Text
But it didnât work.
A playerâs character is instantly removed once a player leaves. The playerâs client is around a little bit longer, but the character isnât. You have three options here I think:
You could try running the Player.CharacterRemoving event to grab the leaving playerâs character right before they leave and store the text in the title variable through that.
Store the NameTagâs text inside a StringValue located in the player somewhere
Store the entire NameTag inside the player, and just set the adornee to the playerâs characterâs head.
My guess is that the character is being deleted instantly, and so because that line of code is inside a pcall, no error ever gets thrown, so title is just equal to nil since the script could find the character.
I understood until you said this. What does it mean?
Instead of parenting the nametag to the character in your playerAdded event, parent it to the player instead.
--Main Text
newtext.Parent = head -- Get rid of this line in your character added event, and parent the nametag to the player instead.
newtext.Adornee = head
uppertext.Text = plr.Name
So this is my current script:
function saveData(plrLeaving)
if not plrLeaving:GetAttribute('DataSuccess') then
return
end
local ownedTools = {}
for i, tool in pairs(plrLeaving.OwnedTools:GetChildren()) do
table.insert(ownedTools, tool.Name)
end
local ownedTitles = {}
for i, title in pairs(plrLeaving.OwnedTitles:GetChildren()) do
table.insert(ownedTitles, title.Name)
end
local title;
pcall(function()
title = plrLeaving.Character.Head.NameTag.Title.Text
end)
local output = {
Titles = ownedTitles,
Tools = ownedTools,
Coins = plrLeaving.leaderstats.Coins.Value,
Wins = plrLeaving.leaderstats.Wins.Value,
Skips = plrLeaving.leaderstats.Skips.Value,
Style = "", -- BE SURE TO SAVE THE STYLE!
Title = title,
}
local success, err = pcall(function()
ds:SetAsync(plrLeaving.UserId, game.HttpService:JSONEncode(output))
end)
end
game.Players.PlayerAdded:Connect(function(plr)
local toolsOwned = {}
local titlesOwned = {}
local style = ""
local title = ""
local coins = 0
local wins = 0
local skips = 0
local packedData;
local s, err = pcall(function()
packedData = ds:GetAsync(plr.UserId)
end)
if s then
plr:SetAttribute('DataSuccess', true)
else
print(tostring(err))
end
if packedData then
local s = pcall(function()
packedData = game.HttpService:JSONDecode(packedData)
end)
if typeof(packedData) == 'table' then
titlesOwned = packedData.Titles or titlesOwned
toolsOwned = packedData.Tools or toolsOwned
coins = packedData.Coins or coins
wins = packedData.Wins or wins
skips = packedData.Skips or skips
title = packedData.Title or title
else
plr:SetAttribute('DataSuccess', false)
end
end
print(3)
if not plr:GetAttribute('DataSuccess') then
-- notify the player that their data did not load successfully.
local msg = Instance.new('Message')
msg.Name = '__ALEXSMESSAGE'
msg.Text = 'Failed to load your data. Please rejoin.'
msg.Parent = plr:WaitForChild('PlayerGui')
game.Debris:AddItem(msg, 5)
end
print(4)
local ls = Instance.new("Folder", plr)
ls.Name = "leaderstats"
local coinsValue = Instance.new("IntValue", ls)
coinsValue.Name = "Coins"
coinsValue.Value = coins
local winsValue = Instance.new("IntValue", ls)
winsValue.Name = "Wins"
winsValue.Value = wins
local skipsValue = Instance.new("IntValue", ls)
skipsValue.Name = "Skips"
skipsValue.Value = skips
local previoustitle = Instance.new("StringValue", plr)
previoustitle.Name = "previoustitle"
previoustitle.Value = title
local previousstyle = Instance.new("StringValue", plr)
previousstyle.Name = "previousstyle"
previousstyle.Value = style
print(5)
plr.CharacterAdded:Connect(function(char)
--Varibles
local head = char.Head
local newtext = nametag:Clone()
local uppertext = newtext:WaitForChild("Name")
local lowertext = newtext.Title
local humanoid = char.Humanoid
print(6)
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None -- use enum instead of a string
--Main Text
newtext.Parent = head
newtext.Adornee = head
uppertext.Text = plr.Name
if plr.previoustitle.Value ~= "" then
lowertext.Text = plr.previoustitle.Value
end
--"If" Statements
--You can add as many of these as you wish, just change it to the player's name.
end)
print(7)
plr.CharacterRemoving:Connect(function()
title = plr.Character.Head.Nametag.Title.Text
end)
local ownedFolder2 = Instance.new("Folder", plr)
ownedFolder2.Name = "OwnedTools"
local ownedFolder3 = Instance.new("Folder", plr)
ownedFolder3.Name = "OwnedTitles"
for i, owned in pairs(toolsOwned) do
if tools:FindFirstChild(owned) then
tools[owned]:Clone().Parent = ownedFolder2
end
end
for i, owned in pairs(titlesOwned) do
if titles:FindFirstChild(owned) then
titles[owned]:Clone().Parent = ownedFolder3
end
end
end)
game.Players.PlayerRemoving:Connect(saveData)
When the player leaves, it uses this event and saves title to the top of the characterâs head.
plr.CharacterRemoving:Connect(function()
title = plr.Character.Head.Nametag.Title.Text
end)
And then it saves it:
local title;
pcall(function()
title = plrLeaving.Character.Head.NameTag.Title.Text
end)
When the player joins back it loads it:
if packedData then
local s = pcall(function()
packedData = game.HttpService:JSONDecode(packedData)
end)
if typeof(packedData) == 'table' then
titlesOwned = packedData.Titles or titlesOwned
toolsOwned = packedData.Tools or toolsOwned
coins = packedData.Coins or coins
wins = packedData.Wins or wins
skips = packedData.Skips or skips
title = packedData.Title or title
else
plr:SetAttribute('DataSuccess', false)
end
end
print(3)
But its still not working.
One of my issues is this part
local title;
pcall(function()
title = plrLeaving.Character.Head.NameTag.Title.Text
end)
What do I need to change title to here?
The three things that I listed above were three separate things I told said you could do, thatâs why I called them options. They arenât supposed to be used together. If you are going the route of parenting the entire nametag to the player instead of the character, then
local title;
pcall(function()
title = plrLeaving.NameTag.Title.Text
end)
That should be your new pcall function to assign title. You can remove the plrLeaving.CharacterRemoving() event since you are just parenting the nametag to the player anyways.
This is what your completed should look like I think.
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local tools = game.ReplicatedStorage:WaitForChild("Tools")
local titles = game.ReplicatedStorage:WaitForChild("Titles")
function saveData(plrLeaving)
if not plrLeaving:GetAttribute('DataSuccess') then
return
end
local ownedTools = {}
for i, tool in pairs(plrLeaving.OwnedTools:GetChildren()) do
table.insert(ownedTools, tool.Name)
end
local ownedTitles = {}
for i, title in pairs(plrLeaving.OwnedTitles:GetChildren()) do
table.insert(ownedTitles, title.Name)
end
local title;
pcall(function()
title = plrLeaving.NameTag.Title.Text
end)
local output = {
Titles = ownedTitles,
Tools = ownedTools,
Coins = plrLeaving.leaderstats.Coins.Value,
Wins = plrLeaving.leaderstats.Wins.Value,
Skips = plrLeaving.leaderstats.Skips.Value,
Style = "", -- BE SURE TO SAVE THE STYLE!
Title = title,
}
local success, err = pcall(function()
ds:SetAsync(plrLeaving.UserId, game.HttpService:JSONEncode(output))
end)
end
game.Players.PlayerAdded:Connect(function(plr)
local toolsOwned = {}
local titlesOwned = {}
local style = ""
local title = ""
local coins = 0
local wins = 0
local skips = 0
local packedData;
local s, err = pcall(function()
packedData = ds:GetAsync(plr.UserId)
end)
if s then
plr:SetAttribute('DataSuccess', true)
else
print(tostring(err))
end
if packedData then
local s = pcall(function()
packedData = game.HttpService:JSONDecode(packedData)
end)
if typeof(packedData) == 'table' then
titlesOwned = packedData.Titles or titlesOwned
toolsOwned = packedData.Tools or toolsOwned
coins = packedData.Coins or coins
wins = packedData.Wins or wins
skips = packedData.Skips or skips
title = packedData.Titled or title
else
plr:SetAttribute('DataSuccess', false)
end
end
if not plr:GetAttribute('DataSuccess') then
-- notify the player that their data did not load successfully.
local msg = Instance.new('Message')
msg.Name = '__ALEXSMESSAGE'
msg.Text = 'Failed to load your data. Please rejoin.'
msg.Parent = plr:WaitForChild('PlayerGui')
game.Debris:AddItem(msg, 5)
end
local ls = Instance.new("Folder", plr)
ls.Name = "leaderstats"
local coinsValue = Instance.new("IntValue", ls)
coinsValue.Name = "Coins"
coinsValue.Value = coins
local winsValue = Instance.new("IntValue", ls)
winsValue.Name = "Wins"
winsValue.Value = wins
local skipsValue = Instance.new("IntValue", plr)
skipsValue.Name = "Skips"
skipsValue.Value = skips
local previoustitle = Instance.new("StringValue", plr)
previoustitle.Name = "previoustitle"
previoustitle.Value = title
local previousstyle = Instance.new("StringValue", plr)
previousstyle.Name = "previousstyle"
previousstyle.Value = style
plr.CharacterAdded:Connect(function(char)
--Varibles
local head = char.Head
local newtext = nametag:Clone()
local uppertext = newtext:WaitForChild("Name")
local lowertext = newtext.Title
local humanoid = char.Humanoid
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None -- use enum instead of a string
--Main Text
newtext.Parent = plr
newtext.Adornee = head
uppertext.Text = plr.Name
if plr.previoustitle.Value ~= "" then
lowertext.Text = plr.previoustitle.Value
end
--"If" Statements
--You can add as many of these as you wish, just change it to the player's name.
end)
local ownedFolder2 = Instance.new("Folder", plr)
ownedFolder2.Name = "OwnedTools"
local ownedFolder3 = Instance.new("Folder", plr)
ownedFolder3.Name = "OwnedTitles"
for i, owned in pairs(toolsOwned) do
if tools:FindFirstChild(owned) then
tools[owned]:Clone().Parent = ownedFolder2
end
end
for i, owned in pairs(titlesOwned) do
if titles:FindFirstChild(owned) then
titles[owned]:Clone().Parent = ownedFolder3
end
end
end)
game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for i, plrLeaving in pairs(game.Players:GetPlayers()) do
coroutine.wrap(function()
saveData(plrLeaving)
end)()
end
-- stall the server
if not game:GetService('RunService'):IsStudio() then
while wait() do
if math.floor(os.clock()%5)== 0 then
print('OMG WE ALL FINNA DIE')
end
end
end
end)
spawn(function()
while wait(60) do
for i, plrLeaving in pairs(game.Players:GetPlayers()) do
coroutine.wrap(function()
saveData(plrLeaving)
end)()
end
end
end)
Didnât seem to work, thank you for helping though!