Ah yes, I remember quitting many projects back and the day due to the difficulties of saving data so let me help you out.
-- First we have to set up the data we're saving, so you want to add a script into ServerScriptService and inside we have to first set up our data store.
dataServ = game:GetService("DataStoreService")
local PetData = dataServ:GetDataStore("PetData_01")
- I use the
_01 after the name for different data versions. By changed this name you reset the data store and create a new one.
-- Now we want to add a folder containing all the pet data into the player when they join the game.
game.Players.PlayerAdded:Connect(function(plr)
local petStats = Instance.new("Folder")
petStats.Parent = plr
petStats.Name = "PetInfo"
local petName = Instance.new("StringValue")
petName.Parent = petStats
petName.Name = "PetName"
end)
-- So now we need to go back and use the data store we made earlier to save all the data in PetInfo
SaveData = function(plr)
pcall(function()
local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then
local petName = petStats:FindFirstChild("PetName")
if petName ~= nil then
PetData:SetAsync(plr.UserId,{petName.Value})
end
end
end)
end
- Now this is just a function made to save data now we have to actually put it to use when a player leaves the game
-- At the very bottom of this script we'd put:
game.Players.PlayerRemoving:Connect(function(plr)
pcall(function()
SaveData(plr)
end)
end)
-- So far we've created a data store, made a folder to hold all of our data and made a way to save data when a player leaves. Our whole script looks like this:
dataServ = game:GetService("DataStoreService")
local PetData = dataServ:GetDataStore("PetData_01")
SaveData = function(plr)
pcall(function()
local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then
local petName = petStats:FindFirstChild("PetName")
if petName ~= nil then
PetData:SetAsync(plr.UserId,{petName.Value})
end
end
end)
end
game.Players.PlayerAdded:Connect(function(plr)
local petStats = Instance.new("Folder")
petStats.Parent = plr
petStats.Name = "PetInfo"
local petName = Instance.new("StringValue")
petName.Parent = petStats
petName.Name = "PetName"
end)
game.Players.PlayerRemoving:Connect(function(plr)
pcall(function()
SaveData(plr)
end)
end)
- But we're still not done because now we have to load all that data we've just saved.
-- So just like with the saving lets make a function for loading data:
LoadData = function(plr, petName)
pcall(function()
local GetPetData = PetData:GetAsync(plr.UserId)
if GetPetData then
petName.Value = GetPetData[1]
print("Data loaded:", plr)
else
petName.Value = "Default Name"
print("No data to load:", plr)
end
end)
end
- Now you might be asking where this function goes and the answer is in the same place we're tracking a player joining the game.
-- So in the player added function under setting all the physical tables values we load in this data.
game.Players.PlayerAdded:Connect(function(plr)
local petStats = Instance.new("Folder")
petStats.Parent = plr
petStats.Name = "PetInfo"
local petName = Instance.new("StringValue")
petName.Parent = petStats
petName.Name = "PetName"
wait()
pcall(function()
LoadData(plr, petName)
end)
end)
That would complete the data store making our whole script look like:
dataServ = game:GetService("DataStoreService")
local PetData = dataServ:GetDataStore("PetData_01")
LoadData = function(plr, petName)
pcall(function()
local GetPetData = PetData:GetAsync(plr.UserId)
if GetPetData then
petName.Value = GetPetData[1]
print("Data loaded:", plr)
else
petName.Value = "Default Name"
print("No data to load:", plr)
end
end)
end
SaveData = function(plr)
pcall(function()
local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then
local petName = petStats:FindFirstChild("PetName")
if petName ~= nil then
PetData:SetAsync(plr.UserId,{petName.Value})
end
end
end)
end
game.Players.PlayerAdded:Connect(function(plr)
local petStats = Instance.new("Folder")
petStats.Parent = plr
petStats.Name = "PetInfo"
local petName = Instance.new("StringValue")
petName.Parent = petStats
petName.Name = "PetName"
wait()
pcall(function()
LoadData(plr, petName)
end)
end)
game.Players.PlayerRemoving:Connect(function(plr)
pcall(function()
SaveData(plr)
end)
end)
Things to note:
- In the LoadData function keep your parameters in the same order in both places
- To make new data just create a new StringValue, add it to the folder we're holding all the data in, add it to the save and loading functions just like I did with the pet name
- To get this data in another script say to set the saved pet name:
local Player = game.Players.LocalPlayer
local data = Player:WaitForChild("PetInfo")
local petName = data:WaitForChild("PetName")
script.Parent.Text = petName.Value
Well, that was lengthy so if you didn't understand anything or need help please let me know.
EDIT:
To save the appearance I would make a folder in ReplicatedStorage called Accessories and put everything the player can use to customize a pet in there.
I'd assume you'd want a limit on the amount of things a player can put on a pet so lets say that limit is two.
I'd make two new StringValues in the data script to save the first accessory and the second one. The values you would be saving are the names of the accessory.
So to load these back in wherever you pet creation script is I'd make a check to see if the player has any saved data for pets already and load it like so:
local Player = game.Players.LocalPlayer
local data = Player:WaitForChild("PetInfo")
local petAcc1 = data:WaitForChild("Accessory1")
local petAcc2 = data:WaitForChild("Accessory2")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local accessoryFolder = ReplicatedStorage:WaitForChild("Accessories")
if petAcc1.Value ~= "" then
local newAcc = accessoryFolder:FindFirstChild(petAcc1.Value)
newAcc.Parent =
end
if petAcc2.Value ~= "" then
local newAcc = accessoryFolder:FindFirstChild(petAcc2.Value)
newAcc.Parent =
end
If the number of customization's you can put on a pet is unlimited I'd actually save a table and use in pairs to loop through that saved tabled and weld every accessory back on the pet.
And of course saving a new accessory value through a GUI you would just use a RemoteEvent and fire that new value to the server to update the pets accessory data.
8 comments
wow! very descriptive, i appreciate the detailed response! my 2 questions are: should i make a string value to hold the colors too, is that how it works? also: do i put the pet in "petinfo" it too? again, thank you SO much :)))
Yeah I'd use string values for everything that isn't a number you're trying to save. So you can make one called petType or something and save the what kind of pet they have. And when they join again check petType to load their pet same for colors too. Glad this helped!
i'm having one issue with loading, i cant seem to get the pet itself to load, the items save perfectly, but i cant figure out how to save the pet to the player to apply the saved appearance ..lol
Oh okay. Depending on how you made the customization might change the way you load the data. Can you link me to the game so I can check it out? Then I can form a good answer on how to load it.
I have 3 different games, the main game is where i put all my tested data, its not all together so it is scrambled right now trying to put the save together, i just have a gui that spawns a base pet. Then, the player can open another gui to color and decorate the wings, and faces etc, but i just dont understand how i am to get the pet to load onto the player to apply the saved appearance o:
I'll edit my response to give you an example of how to do this.
oh yeah, i also fixed it, it took an entire day to get the code to cooperate with my setup xD but it works, i appreciate it so much, you taught me a lot! it was a little difficult to catch on..lol thanks again!
Glad you got everything working and happy to help! Data stores were a struggle for me at the start too.