Character Stuck in Infinite Jump Loop After Releasing Ledge (Modular Movement System)

  1. What do you want to achieve? Keep it simple and clear!
    I am working on a modular movement system. The ledge climbing mechanics (grabbing, climbing, and releasing) are separated into different actions. I am trying to achieve a smooth “Ledge Release” where the player lets go of the wall and falls down naturally without any unintended physics glitches.

  2. What is the issue? Include screenshots / videos if possible!
    When I jump and grab the ledge, everything works as expected. However, the problem occurs when I release the ledge. The character pushes back a few studs (as intended), but then immediately enters an infinite jumping loop. The character keeps jumping automatically upon touching the ground until I press the spacebar again to reset the state.

Here is a video demonstrating the issue: Watch Roblox-2026-01-11T14_13_20.566Z | Streamable

  1. What solutions have you tried so far? Did you look for solutions on the Creator Hub?
  • I searched the Creator Hub and DevForum for similar “infinite jump” or “humanoid state” issues but couldn’t find a fix for this specific context.
  • I tried manually setting Humanoid.Jump = false before releasing.
  • I tried changing the Humanoid state to Freefall, Physics, and GettingUp, but the jump loop persists.
  • I suspect the issue is related to how PlatformStand interacts with the Jump controller when disabled close to a wall, but I can’t pinpoint the exact cause.
-- ~/StarterPlayer/StarterPlayerScripts/InputSystem (LocalScript) Line 172-192
["LedgeRelease"] = {
		["Name"] = "LedgeRelease",
		["CreateTouchButton"] = false,
		["KeyCodes"] = {
			["Keyboard"] = Enum.KeyCode.LeftControl
		},
		["OnInput"] = function(ActionName: string, InputState: Enum.UserInputState, InputObject: InputObject)
			local PlayerAttributes = Player:GetAttributes()
			
			if not PlayerAttributes["GrabbingLedge"] then
				return Enum.ContextActionResult.Pass
			end
			
			if InputState == Enum.UserInputState.Begin then
				Humanoid.Jump = false
				HumanoidRootPart.Anchored = false
				Humanoid.PlatformStand = false
				--The line causing the problem
				--but at the same time it is a must do for the player to continue.

				Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)

				Player:SetAttribute("GrabbingLedge", false)
				ActionEvent:FireServer("LedgeGrab", false)

				return Enum.ContextActionResult.Sink
			end
		end
	}

Any insights on why the Humanoid keeps jumping or how to properly reset the jump state after unanchoring would be appreciated!

The problem was actually caused by another action.

	["LedgeClimb"] = {
		["Name"] = "LedgeClimb",
		["CreateTouchButton"] = false,
		["KeyCodes"] = {
			["Keyboard"] = Enum.KeyCode.Space
		},
		["OnInput"] = function(ActionName: string, InputState: Enum.UserInputState, InputObject: InputObject)
			print("LedgeClimb")
			local PlayerAttributes: { [string]: any } = Player:GetAttributes()

			if not PlayerAttributes["GrabbingLedge"] then
				print("LedgeClimb triggered but wasn't holding a ledge.")
				return Enum.ContextActionResult.Pass
			end
			
			return Enum.ContextActionResult.Pass --> This line was not here
			-- And so it was causing the problem.
		end
	}

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