Jumping beside terrain water lets player climb too fast

So what I am talking about is a bug with the water physics on roblox. It does not function properly as expected as seen in the videos below:
(! TURN OFF SOUND ! ) How it should happen:


How you go up when you jump on the side:

This seemed to occur since the start of smooth terrain, it never really bothered me until I started making a Mario type swimming game.
To reproduce this, first make a big place of a water tube going up, go in the middle and press nothing, to get the bug, go all the way to the side of the water and hold your jump button. This is really annoying as this is just unfixable for me and the game wouldnā€™t be fair if this still existed, it would be considered cheats.

It happens on all games currently and thereā€™s no fix to it at all.

It doesnā€™t have to do with the graphics as this happens on all devices.
It started happening since the release of smooth terrain water around 2014-2015 I think.

My only fix I can think of is changing the ammount of voxels being used in terrain, currently it is 4 voxels.
My guess would be changing it to 1 voxel instead of 4 so the colission can be tracked with more ease.

1 Like

Another fix that comes to mind, while tedious, would be to build a transparent ring of blocks which intersect the water at its edges and prevent users from entering/exiting from or touching the outer surface of the water. This comes with the unfortunate side-effect that you canā€™t have them seamlessly exit and enter the tube through the side but it would fix your problemā€¦

(Obviously the walls can be completely transparent, this is just for demo purposes:)


(Walls donā€™t have to be very far from the inside surface, just the outside surface):

There are of course a few issues with this- the blocks have to be thick enough from the outside that every part of a charcater is prevented from touching it at any point in their jumping animation (You see me testing that in the first part of the video). In my testing I found about a 3 stud distance from the very surface of the water works pretty well (w/ a default animation pack and regularly sized R15 character, havenā€™t tried anything else.) Inside the column, the wall doesnā€™t have to extend much at all because the swim animation will prevent them from approaching the relative surface of the water (at least in my testing.)

If you didnā€™t want to make full walls, you could always make small ā€˜ringsā€™ which instead of blocking users from the entire surface of the water, will knock players off/stop them from jump-spamming up the side (as seen is the second portion of the video where I try to jumpspam up the exposed surface of water.

**Iā€™m unsure as to exactly how players should be able to enter the water tube, but there are many variations of this fix that should accommodate most of your needs.

Doesnā€™t seem as if there is any perfect solution to this but this is the simplest I could think ofā€¦

1 Like

Please just note Iā€™m not looking for solutions, as this also doesnā€™t really help as the objective for my game is to literally swim on the sides of the water but not with that bug ofcourse.

When this is happening the character is in a loop of:

Jumping
Freefall
Swimming
Jumping

This happens because the check to enter the swimming state and the check for preventing jumping while in water are slightly different.

The check to enter the swimming state just checks if the HumanoidRootPart is colliding with water, the same way part buoyancy is normally checked.

The check for jumping is a coarse check to see if the center of the HumanoidRootPart is in a water cell. This allows the character to ā€œjumpā€ out of water when they are swimming on the surface.

For now as a workaround you can try disabling the Jumping state as soon as the Humanoid enters the Swimming state and re-enabling it when it leaves the Swimming state by landing or climbing out:

humanoid.StateChanged:Connect(function(old, new) 
	if new == Enum.HumanoidStateType.Swimming then
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
	else
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
	end
end)

Note that this would disable jumping out of water while swimming on the surface!

You could further mitigate that issue by adding a raycast check down from the center of the HumanoidRootPart to check for water surface while swimming, and enabling the Jumping state while thereā€™s water surface below that center point.

This would let you jump while over water surface, but not with water in front of you.

Hereā€™s an example you can drop in a LocalScript in StarterCharacterScripts that seems to work around the issues (Note: for simplicity it doesnā€™t safely handle the character being removed from workspace):

local RunService = game:GetService("RunService")

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

local steppedConnection = nil
humanoid.StateChanged:Connect(function(old, new) 
	if new == Enum.HumanoidStateType.Swimming then
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
		steppedConnection = RunService.Stepped:Connect(function() 
			local part, point, normal, material = workspace:FindPartOnRay(Ray.new(humanoid.RootPart.Position, Vector3.new(0, -humanoid.HipHeight, 0)), character)
			humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, part and material == Enum.Material.Water or false)
		end)
	else
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
		if steppedConnection then steppedConnection:Disconnect() steppedConnection = nil end
	end
end)

Weā€™ll have to think more about the cost/benefit of adding a check like this in Humanoid itself. Seems like we should, but Iā€™m not sure what the risk of game breaking would be for a change like that yetā€¦

6 Likes

Apologies for the bump, its been (well over) a year, is there any sight of news ahead yet?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.