Issue with reassigning unique Pet ID after evolving pets

In my game, players can purchase pets, delete pets, and evolve pets. It takes 5 of the same type of pet to get a single pet with a higher evolution.

For example, 5 Bears Evolution 0 = 1 Bear Evolution 1

The Problem:
When a player evolves a pet, or deletes a pet, and then buys a new pet sometimes a pet is given an ID that is already taken (I’ve run some print statements to confirm this). So, if a pet is deleted, another with the same ID also gets deleted. Well, that’s what I think is happening.

When a pet gets evolved, 4 are deleted and 1 is kept (with the same ID as previously).

For each pet a player owns, a folder named after the pet is created under Players[LocalPlayer].Pets
Each pet folder has a Number value called Pet_ID

When the player starts out, each new pet gets a unique ID:

    -- In ServerScriptService
    local function totalPets(Player)
    	local Childen = Player:WaitForChild("Pets"):GetChildren()
    	local TotalPets = 0
    	for i = 1,#Childen do
    		TotalPets = TotalPets + 1
    	end
    	return TotalPets
    end

    -- when the event is fired to give a newly purchased, this is how the pet ID is assigned
        Pet_ID.Value = TotalPets + 1

Here is the script when a pet gets deleted (or a pet gets evolved which requires the deletion of 4 pets):

RepStorage.RemoteEvents.PetDelete.OnServerEvent:Connect(function(Player, Pet_ID, IsEvolve, GetEvolve)
	local PetFolder = getFolder(Pet_ID, Player)
	local PlayerStats = Player:WaitForChild("PlayerStats")
	local PetModel = PetFolder       
	if PetFolder.Equipped.Value == true then 
		PetFolder.Equipped.Value = false
		local Pets = Player.Pets
		local Children = Pets:GetChildren()
		local PetsEquipped = {}
		for i = 1,#Children do
			if Children[i].Equipped.Value == true then
				PetsEquipped[#PetsEquipped+1] = Children[i].Pet_ID.Value
			end
		end
		
		--// Code to give some multipliers
		local Level = PetFolder.Level.Value
	
		unequipPet(Pet_ID,PetsEquipped,Player)
	end
	if not GetEvolve then
		PetFolder:Destroy()
	end
	local Children = Player.Pets:GetChildren()
	if not IsEvolve then
		for i = 1,#Children do
			local prevPet_ID = Children[i].Pet_ID.Value
			Children[i].Pet_ID.Value = i
			if Children[i].Equipped.Value == true then
				local Model = getPet(prevPet_ID, Children[i].Name, Player)
				Model.Pet_ID.Value = Children[i].Pet_ID.Value
			end
		end
	end
	if GetEvolve then
		PetFolder.Level.Value = PetFolder.Level.Value + 1
	end
	RepStorage.RemoteEvents.ChangePetsValue:FireClient(Player, "TotalEquipped")
	RepStorage.RemoteEvents.ChangePetsValue:FireClient(Player, "TotalPets")
end)

I am not sure how I can fix this issue and if the problem lies in how the pets are deleted/evolved or if it’s how the Pet_ID is given for new pets. Any pointers in the right direction would be immensely appreciated.

2 Likes

I’m really not that good at scripting, but a way that MAYBE could solve this is to set up a loop which assigns a random Pet_Id, and the loop checks if the Pet_Id is taken and if it is then you generate a new Pet_Id and if it isnt you keep the same Pet_Id.

I’ll look into that. Thanks for the idea.

Look into GUIDs, these are uniquely generated numbers that will never generate again, it is very useful for creating unique IDs and prevent duplicates, they can be generated by using
HttpService:GenerateGUID()

Thank you! I just looked it up and it looks super helpful. I think that’s the way to go in the future. But I think it’s using a string value and that might interfere with the data already saved for players that own pets in my game.