Module Script Only Working for 1 Player at a Time

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to have a module script run for multiple people at the same time

  2. What is the issue? Include screenshots / videos if possible!
    At the end of the script when the pets are cloned, they are all given to a single player

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried putting each player in a table and looping through them, but it still didn’t work
    Basically the egg animation plays for each player but at the end of the animation, one player gets all the pets instead of each player getting their own pet
    Here’s some of the code:

--Server script
local eggHatchingModule = require(game.ServerScriptService.EggHatchingModule)

game.ReplicatedStorage.Events.Egg.hatchEgg.OnServerEvent:Connect(function(player, mode, eggNumber)
	if mode == "auto" then 
		eggHatchingModule.auto(player, eggNumber)
	elseif mode == "triple" then
		eggHatchingModule.triple(player, eggNumber)
	elseif mode == "single" then
		eggHatchingModule.single(player, eggNumber)
	end
end)
--EggHatchingModule, when the hatch ends, this event is fired by the client
	local debounce = false
	game.ReplicatedStorage.Events.Egg.hatchEnd.OnServerEvent:Connect(function(player)
		if debounce == false then
			debounce = true
			petInventoryModule.ClonePets(player, pet, petModule.baseMultipliers[pet.Name], rarity, false)
			petInventoryModule.petHatched(player, pet.Name)
		end
	end)

This all works for one player but when multiple players open an egg at the same time, one player gets all the pets. I’ve been stuck on this for a while now. Any help would be appreciated.

2 Likes

its because you use a debounce for all the players. Heres how to fix:

local debounce = {}
	game.ReplicatedStorage.Events.Egg.hatchEnd.OnServerEvent:Connect(function(player)
	if not debounce[player.UserId] then
		debounce[player.UserId] = true
		petInventoryModule.ClonePets(player, pet, petModule.baseMultipliers[pet.Name], rarity, false)
		petInventoryModule.petHatched(player, pet.Name)
	end
end)

Just another little thing I noticed, and its not really a problem, but there is a way better way of doing it: In the first script you show, you can change it to this and save a lot of space:

local eggHatchingModule = require(game.ServerScriptService.EggHatchingModule)

game.ReplicatedStorage.Events.Egg.hatchEgg.OnServerEvent:Connect(function(player, mode, eggNumber)
	eggHatchingModule[mode](player, eggNumber)
end)
2 Likes

Thanks for your reply! It works for every player now, but instead it gives all the players each pet (so if each player hatched 1 egg, they all get 4 pets)

Here’s the ClonePets function:

PetInventoryModule.ClonePets = function(player, pet, multiplier, rarity, isShiny)
	
	if isShiny then
		PetInventoryModule.makeShinyPet(player, pet, multiplier, rarity)
		return
	end
	
	--Gives the pet a Unique ID
	local id = pet.Name.." ID: ".. tostring(math.random(1,10000000))  --will change this to use generateguid later
	
	--Puts the pet in the savedInventory folder in the player
	for _, v in pairs(game.ServerStorage.PetsToSave:GetDescendants()) do
		if pet.Name == v.Name then
			local savedPet = v:Clone()
			savedPet.Name = v.Name
			savedPet.Id.Value = id
			savedPet.Level.Value = 0
			savedPet.Exp.Value = 0
			savedPet.totalExp.Value = 0
			savedPet.bobaMultiplier.Value = tostring(multiplier) 
			savedPet.cashMultiplier.Value = tostring(multiplier)
			savedPet.Parent = player.Inventory
		end
	end
	
	--Puts pet in inventory from the egg (default pet stats)
	local petTemplate = game.ServerStorage.petTemplate
	local PlayerGui = player:WaitForChild("PlayerGui")
	local inventory = PlayerGui:WaitForChild("inventoryGui").inventoryFrame.inventoryGridFrame
	
	local selectedPet = petTemplate:Clone()
	selectedPet.Exp.Value = 0
	selectedPet.petTemplateId.Value = id
	selectedPet.Level.Value = 0
	selectedPet.Visible = true
	selectedPet.Parent = inventory
	selectedPet.petName.Text = pet.Name
	selectedPet.petNameShadow.Text = pet.Name
	selectedPet.Rarity.Value = rarity
	selectedPet.bobaMultiplier.Value = tostring(multiplier)
	selectedPet.cashMultiplier.Value = tostring(multiplier)
	selectedPet.totalExp.Value = PetInventoryModule.BaseTotalPetExp[rarity][pet.Name] --For total exp (if it's at this point the pet already is not shiny)
	
	--[[PET COLOR CUSTOMIZATION]]
	selectedPet.petName.TextColor3 = PetInventoryModule.rarityColors[rarity].petNameTextColor
	selectedPet.petName.BackgroundColor3 = PetInventoryModule.rarityColors[rarity].petNameBackgroundColor
	selectedPet.BackgroundColor3 = PetInventoryModule.rarityColors[rarity].petNameBackgroundColor
	selectedPet.Rounded.ImageColor3 = PetInventoryModule.rarityColors[rarity].roundedImageColor
	selectedPet.RoundedOutsideButton.ImageColor3 = PetInventoryModule.rarityColors[rarity].roundedOutsideButtonColor	

	selectedPet.petImage.Image = pet.petIcon.Image		
end

Bump, still having this problem, haven’t found a solution yet

If you don’t use the eggHatchingModule variable anywhere else besides in that event (server script from OP), try requiring the event inside the event that way each time the event fires, a new instance of the module is required (at least try it because idk if that’s how it would actually work).

Tried it, still gives both players both pets though. I’m not really sure what else I could do, but I think the problem is with the ClonePets function

Bump again, still haven’t found a solution

Why are you firing an event from the Client when the hatching is complete (hatchEnd event)?

Good question…I wanted to wait until the animation was over before giving the pet but now that I look at it that isn’t really necessary

…That was actually the problem…thank you so much I’ve been stuck on this for like a day

You could still keep it, but instead use a RemoteFunction. You would be able to tell the Client when to start the animation and once it is complete just do return true. You would be able to do something similar to:

repeat wait(1) until RemoteFunction:InvokeClient(player)
-- would wait 1 second until the client function returns true

Edit: The code could be wrong but it is that concept.

Your question from before led me to the solution, thanks for your help