Script not counting studs right

In a game I am working on, I have a pretty simple fall damage script:

local char = script.Parent -- Character
local top = 0
char.Humanoid.FreeFalling:Connect(function(bool)
	if bool then
		top = char.HumanoidRootPart.Position.Y
	else
		local dist = top - char.HumanoidRootPart.Position.Y
		if dist >= 10 then
			char.Humanoid:TakeDamage((dist-10)*10)
		end
		print(dist)
		top = 0
	end
end)

However, it doesn’t seem to count the drop distance (dist) correctly. When falling from 23 studs, it counts a varying distance somewhere from 10 to 15 studs. The printed number changes each time and sometimes shows two numbers like this from one drop:

11.473815917969
6.4241333007813

I have no idea what is causing it to act so strange or unreliably. Any help would be appreciated!

Wouldn’t the reason for the double printout be that the FreeFalling function is recognized twice as the character is falling?
Also I think you’re dealing with trying to recognize instantly that the player is free falling. Even in 1/10th of a second your player is going to fall a distance so the time it takes the script to recognize the player falling and then go through the calculations will be quick, but not instantaneous, hence the difference in your values.

First, from what I know, events fire extremely quick, so it would be much quicker that 1/10th of a second.

Second, it prints the number twice on landing instead of once on landing how it’s supposed to.

Third, wouldn’t the calculations take about the same time each time, meaning there wouldn’t be nearly a 5 stud difference between tests?

If you are falling, then the function is going to be recognized the first time at 11.47 studs, then as the script senses you still falling at 6.42 studs it’s going to fire again.
Are you running this in a complex game that may cause some lag issues, or just on a blank baseplate with no lag at all?

FreeFall can fire false ending as stated in documentation.

Although the Freefall state generally ends when the Humanoid reaches the ground, this event may fire with active equal to false if the state is changed while the Humanoid is falling. For this reason, you should use Humanoid.StateChanged and listen for the Landed state to work out when a Humanoid has landed.

You need to utilize Landed event as well to make it work better.