local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")

local fartEvent = ReplicatedStorage:WaitForChild("FartEvent")
local fartStore = DataStoreService:GetDataStore("FartSim_Data")
local fartSoundId = "rbxassetid://8551016315"

local playingSoundForPlayer = {}

Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player

	local farts = Instance.new("IntValue")
	farts.Name = "Farts"
	farts.Parent = stats

	local success, savedCount = pcall(function()
		return fartStore:GetAsync(player.UserId)
	end)
	if success and savedCount then
		farts.Value = savedCount
	end

	player.CharacterAdded:Connect(function(character)
		local hrp = character:WaitForChild("HumanoidRootPart")

		local billboard = Instance.new("BillboardGui")
		billboard.Name = "FartNameTag"
		billboard.Adornee = hrp
		billboard.Size = UDim2.new(0, 300, 0, 70)
		billboard.StudsOffset = Vector3.new(0, 6, 0)
		billboard.AlwaysOnTop = true
		billboard.Parent = character

		local textLabel = Instance.new("TextLabel")
		textLabel.Size = UDim2.new(1, 0, 1, 0)
		textLabel.BackgroundTransparency = 1
		textLabel.TextColor3 = Color3.new(1, 1, 1)
		textLabel.TextStrokeTransparency = 0.5
		textLabel.Font = Enum.Font.GothamBold
		textLabel.TextScaled = true
		textLabel.TextWrapped = true
		textLabel.Parent = billboard

		spawn(function()
			while character.Parent do
				local fartsValue = player:FindFirstChild("leaderstats") and player.leaderstats:FindFirstChild("Farts")
				if fartsValue then
					textLabel.Text = player.Name .. "\nFarts: " .. fartsValue.Value
				else
					textLabel.Text = player.Name .. "\nFarts: 0"
				end
				wait(0.5)
			end
		end)
	end)
end)

Players.PlayerRemoving:Connect(function(player)
	local farts = player:FindFirstChild("leaderstats") and player.leaderstats:FindFirstChild("Farts")
	if farts then
		pcall(function()
			fartStore:SetAsync(player.UserId, farts.Value)
		end)
	end
end)

fartEvent.OnServerEvent:Connect(function(player)
	local character = player.Character
	if not character then return end

	local hrp = character:FindFirstChild("HumanoidRootPart")
	if not hrp then return end

	local stats = player:FindFirstChild("leaderstats")
	if not stats then return end
	local farts = stats:FindFirstChild("Farts")
	if not farts then return end

	farts.Value += 1

	local template = ReplicatedStorage:FindFirstChild("fart particle")
	if not template then
		warn("fart particle not found in ReplicatedStorage")
		return
	end

	local fartClone = template:Clone()
	fartClone.Anchored = true
	fartClone.CanCollide = false
	fartClone.Parent = workspace
	fartClone.Transparency = 0

	local fadeTime = 3
	local steps = 30
	local waitTime = fadeTime / steps

	spawn(function()
		for i = 1, steps do
			local alpha = i / steps
			fartClone.Transparency = alpha

			for _, child in ipairs(fartClone:GetChildren()) do
				if child:IsA("ParticleEmitter") then
					child.Rate = math.floor((1 - alpha) * 50)
					child.Transparency = NumberSequence.new(alpha)
				elseif child:IsA("Smoke") then
					child.Opacity = 1 - alpha
				end
			end

			if hrp.Parent then
				fartClone.CFrame = hrp.CFrame * CFrame.new(0, -1, -2)
			end

			wait(waitTime)
		end
		fartClone:Destroy()
	end)

	if farts.Value % 20 == 0 then
		if not playingSoundForPlayer[player.UserId] then
			playingSoundForPlayer[player.UserId] = true

			local sound = Instance.new("Sound")
			sound.SoundId = fartSoundId
			sound.Volume = 1
			sound.Parent = hrp

			sound.Loaded:Wait()
			sound:Play()

			local soundEndedConnection
			local function cleanup()
				playingSoundForPlayer[player.UserId] = false
				if soundEndedConnection then
					soundEndedConnection:Disconnect()
					soundEndedConnection = nil
				end
				if sound and sound.Parent then
					sound:Destroy()
				end
			end

			soundEndedConnection = sound.Ended:Connect(cleanup)

			-- fallback timeout: in case Ended doesn't fire
			task.delay(sound.TimeLength + 0.5, function()
				if playingSoundForPlayer[player.UserId] then
					cleanup()
				end
			end)
		end
	end
end)


Fix my code the sound only shows up once i want it to come every 20 farts