Why is body force sometimes bug and be unreliable?

The P and D are part of a different API:
https://developer.roblox.com/en-us/articles/BodyMover

There was a mix-up and you can kindly ignore that for now on.

2 Likes

According to the BodyForce example, the player’s jump height is affected by two factors:

  1. Acceleration
  2. Mass

…which is Newton’s second law of motion, describing force.

The acceleration depends on the workspace.Gravity. The most important factor that varies between players is the mass. The mass is different for each player’s size but also sometimes accessories and the tools they are holding.

2 Likes

So what do I do to fix this bug and have players get pushed up better and the same amount?

2 Likes

For each character, you need to get the total mass. This function would help getting the total mass, since each character are models.

local function getMassFromModel(model)
	local mass = 0
	for _, object in pairs(model:GetDescendants()) do
		if object:IsA("BasePart") then
			mass += object:GetMass
		end
	end
	
	return mass
end

After that, remember Newton’s second law of motion: Multiply the mass with the workspace’s gravity and then multiply it again with an alpha with an interval between 0 to 1, depending on how much of gravity you want to negate. 0 for nothing and 1 for total anti-gravity.

2 Likes

can you explain to me what mass+= object:GetMass does??

2 Likes

The += is a compound operator that was introduced during Luau’s implementation. Equivalent of:

mass = mass + object:GetMass()

2 Likes

what will i do with this mass?

2 Likes

As I have mentioned earlier, you mathematically calculate one value which, I forgot to mention, should be used for the Y value for the BodyForce.

Also a less relevant point here: Do not use the parent parameter of Instance.new, just parent it after all properties are set.

2 Likes
local function getMassFromModel(model)
	local mass = 0
	for _, object in pairs(model:GetDescendants()) do
		if object:IsA("BasePart") then
			mass += object:GetMass
		end
	end
	
	return mass
end
local bodyforce = Instance.new("BodyForce")
bodyforce.Force = getMassFromModel

I dont know what to do

1 Like

The function should be called with the character model. If a remote fired it, then you would use player.Character into the parameter, assuming that player was already assigned from the arguments. Then it would return the mass.

bodyforce.Force = Vector3.new(0, workspace.Gravity * getMassFromModel(player.Character) * factor ,0)

Replace factor with any number between 0 to 1, as I have previously explained. And finally, parent it.
bodyforce.Parent = player.Character.HumanoidRootPart

1 Like

What does factor do… . . …?

1 Like

If you read in a previous post above:

Factor is an interval between 0 to 1(or above if you decide to fly into space), which is the amount of gravity mitigated. 0 and 1 can be translated as 0% to 100%.

1 Like

What does all of this have to do with fixing my glitch, is this the only way?

The factor doesn’t have anything to do with the “glitch”, it’s only an option. it is merely because of different physical mass per player and using these steps should resolve the issue of different jump heights.

None of you has actually hit on the real reason for the erratic behavior, which is that you have no way to apply the force for a consistent interval. If a player’s machine can’t maintain 60 FPS, they are going to have a longer times between physics steps, and consequently a longer time spent accelerating. This is why “laggy” players can jump higher in many games.

The same principle applies when using BodyVelocity, if trying to accelerate too quickly.

In general, it’s a hard problem to implement a fixed-energy impulse in a system with a variable time step. You kind of have to except that the results are going to vary player-to-player and build the tolerance for it into your game. The only way to get everyone jumping exactly the same is to roll your own kinematics system that doesn’t use Roblox physics simulation and is entirely deterministic.

Also, just FYI, it matters exactly when you measure the mass of a players avatar. The total mass changes during avatar load, as body parts are swapped and accessories are converted to massless. Make sure you actually have the final mass of the character if you’re using BodyForces.

2 Likes

ok thank you but im still confused on how to make a player masless, and does masless help you with bodyforce bugs?

For some reason it only effectively works in LocalScripts. Therefore, you’ll have to fire a remote.

bodyforce works on local scripts?

Yeah, I have jumppads that use localscripts. I tried doing it on the server and it wouldn’t work at all. Just fireallclients to the client and send the plr, pad, humanoidrootpart, and power or whatever.

Then you’d check to see if Plr.Name == to the localplayer’s name. if it is you’ll add the bodyforce and things to the rootpart. add a debris or whatever.

Also noticed: player.Character.Humanoid.Jump = true

That should be player.Character.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)