Sometimes gaining 0 stats

For some reason whenever I get to like really high numbers of stat gain it’s just 0 but I don’t think its a capcity bug because when I’m in training zones which gives way more I gain the stat but when I’m not it just gives me 0 heres my helper functions module

local ClientModules = RS.Modules
local BigNum = require(ClientModules.BigNum)

local Helpers = {}

--// Helpers To Our Helpers

-- Check if the current time has exceeded the cooldown period
function Helpers.CheckDebounceTime(debounce, cooldown)
	return debounce < os.time() - cooldown
end

-- Add amount to a BigNum stat
function Helpers.BigNumAdd(stat, amount)
	local bNum = BigNum.new(stat.Value)
	local res = BigNum.mt.add(bNum, BigNum.new(amount))
	stat.Value = BigNum.mt.tostring(res)
end

-- Subtract amount from a BigNum stat
function Helpers.BigNumSub(stat, amount)
	local bNum = BigNum.new(stat.Value)
	local res = BigNum.mt.sub(bNum, BigNum.new(amount))
	stat.Value = BigNum.mt.tostring(res)
end

function Helpers.BigNumMul(a, b)
	return BigNum.mt.tostring(BigNum.mt.mul(BigNum.new(a), BigNum.new(b)))
end


-- Calculate and update player's health based on their endurance
function Helpers.CalculateHealth(Player, Endurance)
	local Char = Player.Character
	if not Char then
		warn("[CalculateHealth] No character for", Player.Name)
		return
	end

	local Humanoid = Char:FindFirstChildOfClass("Humanoid")
	if not Humanoid then
		warn("[CalculateHealth] No Humanoid found for", Player.Name)
		return
	end

	local Endu = tonumber(Endurance.Value)
	if not Endu then
		warn("[CalculateHealth] Invalid Endurance.Value for", Player.Name, "Value:", Endurance.Value)
		return
	end

	local EnduBigNum = BigNum.new(Endu)
	local rawHealth = BigNum.mt.add(BigNum.mt.mul(EnduBigNum, 10), BigNum.new(100))
	local healthNum = tonumber(BigNum.mt.tostring(rawHealth))

	if not healthNum then
		warn("[CalculateHealth] Failed to convert BigNum to number for", Player.Name)
		return
	end

	local oldMax = Humanoid.MaxHealth
	Humanoid.MaxHealth = healthNum

	-- Heal to full (optional, comment if not wanted)
	Humanoid.Health = healthNum

end


function Helpers.Train(Player, StatName, isAutoTraining)
	local Char = Player.Character
	if not Char then return end

	-- Retry to find PhysicalStats
	local physicalStats
	for i = 1, 5 do
		physicalStats = Player:FindFirstChild("PhysicalStats")
		if physicalStats then break end
		wait(0.2)
	end

	if not physicalStats then
		warn("PhysicalStats not found for player " .. Player.Name)
		return
	end

	local Stat = physicalStats:FindFirstChild(StatName)
	if not Stat then
		warn("Stat " .. StatName .. " not found in PhysicalStats!")
		return
	end

	local Multi = Player:FindFirstChild("Multipliers") and Player.Multipliers:FindFirstChild(StatName .. "Multi")
	local GemMulti = Player:FindFirstChild("GemMultipliers") and Player.GemMultipliers:FindFirstChild("Gem" .. StatName .. "Multi")
	local PowerMultiplier = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("PowerMultiplier")
	local GeneticsPowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("GeneticsPowerMulti")
	local DoublePowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("DoublePowerMulti")
	local BoostdoublePowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("BoostdoublePowerMulti")

	local Tool = Char:FindFirstChildOfClass("Tool")
	local IsPushUpTool = Tool and Tool.Name == "PushUpTool"

	local multiplier = Multi and Multi.Value or 1

	if not IsPushUpTool then
		local ZoneMulti = Helpers.IsInUsableZone(Player, StatName, isAutoTraining)
		multiplier = multiplier * ZoneMulti
	end

	-- Helper function to safely multiply and debug multipliers
	local function debugMultiplier(name, value)
		local num = tonumber(value)
		print("[Multiplier Debug] " .. name .. " = " .. tostring(value))
		if not num or num <= 0 then
			print("[Warning] Multiplier '" .. name .. "' is invalid or zero. Using 1 instead.")
			return 1
		end
		return num
	end

	multiplier = multiplier * debugMultiplier("PowerMultiplier", PowerMultiplier and PowerMultiplier.Value)
	multiplier = multiplier * debugMultiplier("GeneticsPowerMulti", GeneticsPowerMulti and GeneticsPowerMulti.Value)
	multiplier = multiplier * debugMultiplier("DoublePowerMulti", DoublePowerMulti and DoublePowerMulti.Value)
	multiplier = multiplier * debugMultiplier("BoostdoublePowerMulti", BoostdoublePowerMulti and BoostdoublePowerMulti.Value)

	if GemMulti then
		multiplier = multiplier * debugMultiplier("GemMulti", GemMulti.Value)
	end

	print("[Final Multiplier] For stat '" .. StatName .. "' multiplier is: " .. multiplier)

	-- Final training addition
	Helpers.BigNumAdd(Stat, Helpers.BigNumMul("1", multiplier))

	if StatName == "Endurance" then
		Helpers.CalculateHealth(Player, Stat)
	end
end


function Helpers.IsInUsableZone(Player, StatName, isAutoTraining)
	local Char = Player.Character
	if not Char then return 1, false end

	local HRP = Char.PrimaryPart
	if not HRP then return 1, false end

	-- Retry to find PhysicalStats up to 5 times with small wait
	local physicalStats
	for i = 1, 5 do
		physicalStats = Player:FindFirstChild("PhysicalStats")
		if physicalStats then break end
		wait(0.75)  -- Wait for 0.2 seconds before trying again
	end

	if not physicalStats then
		warn("PhysicalStats not found for player " .. Player.Name)
		return 1, false
	end

	local Stat = physicalStats:FindFirstChild(StatName)
	if not Stat then
		warn("Stat " .. StatName .. " not found in PhysicalStats!")
		return 1, false
	end

	local ZoneMulti = 1
	local hitAZone = false

	-- Check if the player is auto-training push-ups (endurance) and skip zone multiplier calculation
	if isAutoTraining and StatName == "Endurance" then
		-- If auto-training endurance, just return no zone multiplier
		return 1, false
	end

	-- Only check zone multipliers for auto-training if the stat is "Strength" (for punching)
	if isAutoTraining and StatName == "Strength" then
		local origin = HRP.Position
		local Range = -30
		local Dir = Vector3.new(0, Range, 0)

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {game.Workspace.TrainingZones}
		raycastParams.FilterType = Enum.RaycastFilterType.Include

		local ZoneRay = Ray.new(origin, Dir)
		local Zone = workspace:FindPartOnRayWithWhitelist(ZoneRay, workspace.TrainingZones:GetDescendants())
		if Zone and string.split(Zone.Name, ' ')[1] == StatName and BigNum.mt.ge(Stat.Value, Zone.Req.Value) then
			ZoneMulti = Zone.Multiplier.Value
			hitAZone = true
		end
	else
		-- If not auto-training, perform the normal zone check
		local origin = HRP.Position
		local Range = -30
		local Dir = Vector3.new(0, Range, 0)

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {game.Workspace.TrainingZones}
		raycastParams.FilterType = Enum.RaycastFilterType.Include

		local ZoneRay = Ray.new(origin, Dir)
		local Zone = workspace:FindPartOnRayWithWhitelist(ZoneRay, workspace.TrainingZones:GetDescendants())
		if Zone and string.split(Zone.Name, ' ')[1] == StatName and BigNum.mt.ge(Stat.Value, Zone.Req.Value) then
			ZoneMulti = Zone.Multiplier.Value
			hitAZone = true
		end
	end

	return ZoneMulti, hitAZone
end

return Helpers