I am relitavely new to scripting, ive been doodling with it here and there. I recently made like a "pet decorating" game just for fun and practice where you purchase a pet, buy items for the pet, colorize, different wings and wing colors and many different faces, and naming ability. Everything works accordingly but ive ran into a wall, i cant figure out how to save these changes a player makes to the pet, or load when the player returns. (Color, wings, faces, given names) ive been stuck for weeks, and im almost ready to give up. (I really dont want to).
Do i make a table with 100+ available variations? (lengthy process and was going to be last resort.)
I am absolutely lost and i have no idea how to start. Ive looked everywhere, roblox wiki pages, and even other threads reguarding saving models, parts, and such. Am i missing something? Im aware you cant save objects in datastores, but how else can i do this?
Id love to learn more about scripting but im so very lost on saving items, skins, colors, names etc.
Thanks to anyone in advance.
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.
lua
--// The roblox data service
dataServ = game:GetService("DataStoreService")
--// Creates a data store
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. ```lua 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
```lua
--// Make a new function to save the data
SaveData = function(plr)
pcall(function()
--// Where all the data should be in the player
local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then --// All the stats inside of the 'PetInfo' Folder local petName = petStats:FindFirstChild("PetName") --// If the stats aren't nil save them 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: ```lua --// When a player leaves game.Players.PlayerRemoving:Connect(function(plr) pcall(function() --// Call the saving 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: ```lua --// The roblox data service dataServ = game:GetService("DataStoreService") --// Creates a data store local PetData = dataServ:GetDataStore("PetData_01")
--// Make a new function to save the data SaveData = function(plr) pcall(function() --// Where all the data should be in the player local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then --// All the stats inside of the 'PetInfo' Folder local petName = petStats:FindFirstChild("PetName") --// If the stats aren't nil save them if petName ~= nil then PetData:SetAsync(plr.UserId,{petName.Value}) end end end)
end
--// Give physical holders for data when a player joins 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)
--// When a player leaves game.Players.PlayerRemoving:Connect(function(plr) pcall(function() --// Call the saving 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: ```lua --// Loading stats function LoadData = function(plr, petName) --// We'll need these parameters when we call the function later pcall(function() --// Data from the datastore using the players ID local GetPetData = PetData:GetAsync(plr.UserId)
--// If saved data was found load it if GetPetData then --// Because we saved our data in a table -- we're now pulling that information from -- that table. The first value being petName petName.Value = GetPetData[1] print("Data loaded:", plr) else --// If save data wasn't found load in some default values petName.Value = "Default Name" print("No data to load:", plr) end end)
end ```
-- So in the player added function under setting all the physical tables values we load in this data. ```lua --// Give physical holders for data when a player joins 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" --// The added lines where we load the data wait() pcall(function() LoadData(plr, petName) end)
end) ```
That would complete the data store making our whole script look like: ```lua --// The roblox data service dataServ = game:GetService("DataStoreService") --// Creates a data store local PetData = dataServ:GetDataStore("PetData_01")
--// Loading stats function LoadData = function(plr, petName) --// We'll need these parameters when we call the function later pcall(function() --// Data from the datastore using the players ID local GetPetData = PetData:GetAsync(plr.UserId)
--// If saved data was found load it if GetPetData then --// Because we saved our data in a table -- we're now pulling that information from -- that table. The first value being petName petName.Value = GetPetData[1] print("Data loaded:", plr) else --// If save data wasn't found load in some default values petName.Value = "Default Name" print("No data to load:", plr) end end)
end
--// Make a new function to save the data SaveData = function(plr) pcall(function() --// Where all the data should be in the player local petStats = plr:FindFirstChild("PetInfo")
if petStats ~= nil then --// All the stats inside of the 'PetInfo' Folder local petName = petStats:FindFirstChild("PetName") --// If the stats aren't nil save them if petName ~= nil then PetData:SetAsync(plr.UserId,{petName.Value}) end end end)
end
--// Give physical holders for data when a player joins 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" --// The added lines where we load the data wait() pcall(function() LoadData(plr, petName) end)
end)
--// When a player leaves game.Players.PlayerRemoving:Connect(function(plr) pcall(function() --// Call the saving 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: ```lua --//Local script local Player = game.Players.LocalPlayer local data = Player:WaitForChild("PetInfo") local petName = data:WaitForChild("PetName")
--// Lets say it changes the text on a gui to the name of the pet 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:
```lua
--//Local script
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")
--// Not sure how you're doing the pet creation -- but it would be something like this
--// If the player has a saved value for accessory one if petAcc1.Value ~= "" then local newAcc = accessoryFolder:FindFirstChild(petAcc1.Value) newAcc.Parent = --// Parent it to the pet
--// And then weld it in place here or however you did it
end
--// You'd do the same check for the second accessory if petAcc2.Value ~= "" then local newAcc = accessoryFolder:FindFirstChild(petAcc2.Value) newAcc.Parent = --// Parent it to the pet
--// And then weld it in place here or however you did it
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.
Well its actually quite simple when you get the hang of it
First Learn how to Data store, which i'm guessing you can somewhat do
Second If you don't know already, learn about JSONEncode. Your going to need to convert tables into strings and datastore those
Now What you could do is get the children of the pet and if its not a limb you add it to the table for ex.
local Pet = --The Pet local Decor = {} for i, v in pairs(Pet:GetChildren()) do if not v:IsA"Limb" then -- or you could say if v.Name == "Decoration" or whatever table.inset(Decor, v) end end
Then Fire the Data Store Event with the table in the parameter then Convert with the JSON Encode