Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do i make a table or something to store this? Guidance please?

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.

2 answers

✓ Accepted answer

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.

--// 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.

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

--// 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:

--// 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:

--// 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:

--// 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
  • 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.

--// 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:

--// 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:
--//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:

--//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.

8 comments

0

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 :)))

0

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!

0

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

0

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.

0

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:

0

I'll edit my response to give you an example of how to do this.

0

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!

0

Glad you got everything working and happy to help! Data stores were a struggle for me at the start too.

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

This discussion is preserved as it was. New answers, comments, and votes are closed.