How would I go about making a pet system?

Hello, I am trying to make a system to buy (and save) pets and have them follow you, let me explain.

The pets are all (free) models found in ServerStorage in a folder called “Pets”.

This is what the DataStore for the pets looks like

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("UserData2121")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Data = {
	Strength = 0;
	Rebirths = 0;
	Cash = 1111110;
	Speed = 116;
	Damage = 5;
	Health = 110;
	Weight = 1;
	Alien = false;
	Bear = false;
	Bee = false;
	Bunny = false;
	Burger = false;
	Cat = false;
	Cow = false;
	Dog = false;
	Donut = false;
	Forgotton = false;
	Fox = false;
	Jellyfish = false;
	Mouse = false;
	Demon = false;
	Spook = false;
	TV = false
	}



local playersavetable = {};

local function loadStarterData(Player)
		local Stats = Instance.new("Folder")
		Stats.Name = "Stats"
		Stats.Parent = Player
		local Inventory = Instance.new("Folder")
		Inventory.Name = "Inventory"
		Inventory.Parent = Stats
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == 'number' then
			local intvalue = Instance.new("IntValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = Stats
			else if type(statvalue) == 'boolean' then
			local intvalue = Instance.new("BoolValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = Inventory
		end
	end
		end
		end

local function loadData(player, Stats)
	local Data = {}
	local Stats = Stats or player.Stats
	local s, e = pcall(function()
	Data = DataStore:GetAsync('UserId'..player.UserId)
	end)
	
	if s then 
		print (player.Name.."Data loaded")
	else
		print(player.Name.."Data failed to load")
	end
	
	if Data then
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == "number" then
			player.Stats[statname].Value = statvalue
			else if type(statvalue) == "boolean" then
			player.Stats.Inventory[statname].Value = statvalue
			end
			end
		end
		print(player.Name.."Data has been loaded")
	else
		print(player.Name.."No data found! generating..")
		end
	end

local function saveData(player)
	--if RunService:IsStudio() then return end
	local Data = {}
	for _, stat in ipairs(player.Stats:GetChildren()) do
   if not stat:IsA("Folder") then
       Data[stat.Name] = stat.Value
   end
end
	local s, e = pcall(function()
		DataStore:SetAsync('UserId'..player.UserId, Data)
	end)
		if s then 
	print(player.Name.."Data has been saved")
		else
	warn (player.Name.."Data failed to save"..e)
	end
end

ReplicatedStorage.SaveEvent.OnServerEvent:Connect(function(player)
 saveData(player)	
end)

Players.PlayerAdded:Connect(function(player)
	playersavetable[player] = tick()
	loadStarterData(player)
	loadData(player)
   
   local Stats = player:WaitForChild("Stats")
   
  local RemoveEvent
   RemoveEvent = Players.PlayerRemoving:Connect(function(vplayer)
      if vplayer == player then
         saveData(vplayer, Stats)
         RemoveEvent:Disconnect()
      end
   end)
end)

my script generates all values on player join and this may not be the most efficient method.

The main thing I am trying to figure out though is how I would go about making a buying script for the pets, do I have to make a separate RemoteEvent for all of them? I am very lost here and I have been looking on the DevForum for awhile now and while I have found some stuff none of it was really helpful for this circumstance.


This is my GUI I made for the shop.

If anyone has any questions feel free to ask!

2 Likes

The general rule in my case is beauty on client, security on server.

As a side note, I recommend storing pets in their own sub table

So Data[Pets] could be looped through if needed.

The smartest solution is to pass information to the remote event.

So remoteEvent:FireServer({UpdateType = “BuyPet”, Pet = “PetNameHere”})

The way I do it is make it so when a frame has the pets name.

So if you named your pet frames correctly you could do a for loop of them, and add the same event, which uses the frames name.

I don’t understand, do I need to make a separate remote to buy each pet? If not can you please provide an example of it being done otherwise?