function KeyboardMovement.Enable(G)if not UserInputService.KeyboardEnabled then return end local w=0 local E=0 local a=0 local A=0 local L=function()MasterControl:AddToPlayerMovement(-currentMoveVector)currentMoveVector=Vector3.new(a+A,0,w+E)MasterControl:AddToPlayerMovement(currentMoveVector)end local H=function(G,E,a)if E==Enum.UserInputState.Begin then w=-1 elseif E==Enum.UserInputState.End then w=0 end L()end local T=function(G,w,a)if w==Enum.UserInputState.Begin then E=1 elseif w==Enum.UserInputState.End then E=0 end L()end local m=function(G,w,E)if w==Enum.UserInputState.Begin then a=-1 elseif w==Enum.UserInputState.End then a=0 end L()end local v=function(G,w,E)if w==Enum.UserInputState.Begin then A=1 elseif w==Enum.UserInputState.End then A=0 end L()end local W=function(G,w,E)MasterControl:SetIsJumping(w==Enum.UserInputState.Begin)end ContextActionService:BindActionToInputTypes("\102\111\114\119\097\114\100\077\111\118\101\109\101\110\116",H,false,Enum.PlayerActions.CharacterForward)ContextActionService:BindActionToInputTypes("\098\097\099\107\119\097\114\100\077\111\118\101\109\101\110\116",T,false,Enum.PlayerActions.CharacterBackward)ContextActionService:BindActionToInputTypes("\108\101\102\116\077\111\118\101\109\101\110\116",m,false,Enum.PlayerActions.CharacterLeft)ContextActionService:BindActionToInputTypes("\114\105\103\104\116\077\111\118\101\109\101\110\116",v,false,Enum.PlayerActions.CharacterRight)ContextActionService:BindActionToInputTypes("\106\117\109\112\065\099\116\105\111\110",W,false,Enum.PlayerActions.CharacterJump)local function q()local G=getHumanoid()if G then MasterControl:AddToPlayerMovement(-currentMoveVector)currentMoveVector=Vector3.new(0,0,0)w,E,a,A=0,0,0,0 MasterControl:SetIsJumping(false)end end local function l(G)MasterControl:SetIsJumping(false)end SeatJumpCn=UserInputService.InputBegan:connect(function(G,w)if G.KeyCode==Enum.KeyCode.Backspace and not w then local G=getHumanoid()if G and(G.Sit or G.PlatformStand)then MasterControl:DoJump()end end end)TextFocusReleasedCn=UserInputService.TextBoxFocusReleased:connect(q)TextFocusGainedCn=UserInputService.TextBoxFocused:connect(l)WindowFocusReleasedCn=UserInputService.WindowFocused:connect(q)end function KeyboardMovement.Disable(G)ContextActionService:UnbindAction("\102\111\114\119\097\114\100\077\111\118\101\109\101\110\116")ContextActionService:UnbindAction("\098\097\099\107\119\097\114\100\077\111\118\101\109\101\110\116")ContextActionService:UnbindAction("\108\101\102\116\077\111\118\101\109\101\110\116")ContextActionService:UnbindAction("\114\105\103\104\116\077\111\118\101\109\101\110\116")ContextActionService:UnbindAction("\106\117\109\112\065\099\116\105\111\110")if SeatJumpCn then SeatJumpCn:disconnect()SeatJumpCn=nil end if TextFocusReleasedCn then TextFocusReleasedCn:disconnect()TextFocusReleasedCn=nil end if TextFocusGainedCn then TextFocusGainedCn:disconnect()TextFocusGainedCn=nil end if WindowFocusReleasedCn then WindowFocusReleasedCn:disconnect()WindowFocusReleasedCn=nil end MasterControl:AddToPlayerMovement(-currentMoveVector)currentMoveVector=Vector3.new(0,0,0)MasterControl:SetIsJumping(false)end return KeyboardMovement
--[[ Public API ]]
--
function KeyboardMovement:Enable()
	if not UserInputService.KeyboardEnabled then
		return
	end

	local forwardValue = 0
	local backwardValue = 0
	local leftValue = 0
	local rightValue = 0

	local updateMovement = function()
		MasterControl:AddToPlayerMovement(-currentMoveVector)
		currentMoveVector = Vector3.new(leftValue + rightValue, 0, forwardValue + backwardValue)
		MasterControl:AddToPlayerMovement(currentMoveVector)
	end

	local moveForwardFunc = function(actionName, inputState, inputObject)
		if inputState == Enum.UserInputState.Begin then
			forwardValue = -1
		elseif inputState == Enum.UserInputState.End then
			forwardValue = 0
		end
		updateMovement()
	end

	local moveBackwardFunc = function(actionName, inputState, inputObject)
		if inputState == Enum.UserInputState.Begin then
			backwardValue = 1
		elseif inputState == Enum.UserInputState.End then
			backwardValue = 0
		end
		updateMovement()
	end

	local moveLeftFunc = function(actionName, inputState, inputObject)
		if inputState == Enum.UserInputState.Begin then
			leftValue = -1
		elseif inputState == Enum.UserInputState.End then
			leftValue = 0
		end
		updateMovement()
	end

	local moveRightFunc = function(actionName, inputState, inputObject)
		if inputState == Enum.UserInputState.Begin then
			rightValue = 1
		elseif inputState == Enum.UserInputState.End then
			rightValue = 0
		end
		updateMovement()
	end

	local jumpFunc = function(actionName, inputState, inputObject)
		MasterControl:SetIsJumping(inputState == Enum.UserInputState.Begin)
	end

	-- TODO: remove up and down arrows, these seem unnecessary
	ContextActionService:BindActionToInputTypes(
		"forwardMovement",
		moveForwardFunc,
		false,
		Enum.PlayerActions.CharacterForward
	)
	ContextActionService:BindActionToInputTypes(
		"backwardMovement",
		moveBackwardFunc,
		false,
		Enum.PlayerActions.CharacterBackward
	)
	ContextActionService:BindActionToInputTypes("leftMovement", moveLeftFunc, false, Enum.PlayerActions.CharacterLeft)
	ContextActionService:BindActionToInputTypes(
		"rightMovement",
		moveRightFunc,
		false,
		Enum.PlayerActions.CharacterRight
	)
	ContextActionService:BindActionToInputTypes("jumpAction", jumpFunc, false, Enum.PlayerActions.CharacterJump)
	-- TODO: make sure we check key state before binding to check if key is already down

	local function onFocusReleased()
		local humanoid = getHumanoid()
		if humanoid then
			MasterControl:AddToPlayerMovement(-currentMoveVector)
			currentMoveVector = Vector3.new(0, 0, 0)
			forwardValue, backwardValue, leftValue, rightValue = 0, 0, 0, 0
			MasterControl:SetIsJumping(false)
		end
	end

	local function onTextFocusGained(textboxFocused)
		MasterControl:SetIsJumping(false)
	end

	SeatJumpCn = UserInputService.InputBegan:connect(function(inputObject, isProcessed)
		if inputObject.KeyCode == Enum.KeyCode.Backspace and not isProcessed then
			local humanoid = getHumanoid()
			if humanoid and (humanoid.Sit or humanoid.PlatformStand) then
				MasterControl:DoJump()
			end
		end
	end)

	TextFocusReleasedCn = UserInputService.TextBoxFocusReleased:connect(onFocusReleased)
	TextFocusGainedCn = UserInputService.TextBoxFocused:connect(onTextFocusGained)
	-- TODO: remove pcall when API is live
	WindowFocusReleasedCn = UserInputService.WindowFocused:connect(onFocusReleased)
end

function KeyboardMovement:Disable()
	ContextActionService:UnbindAction("forwardMovement")
	ContextActionService:UnbindAction("backwardMovement")
	ContextActionService:UnbindAction("leftMovement")
	ContextActionService:UnbindAction("rightMovement")
	ContextActionService:UnbindAction("jumpAction")

	if SeatJumpCn then
		SeatJumpCn:disconnect()
		SeatJumpCn = nil
	end
	if TextFocusReleasedCn then
		TextFocusReleasedCn:disconnect()
		TextFocusReleasedCn = nil
	end
	if TextFocusGainedCn then
		TextFocusGainedCn:disconnect()
		TextFocusGainedCn = nil
	end
	if WindowFocusReleasedCn then
		WindowFocusReleasedCn:disconnect()
		WindowFocusReleasedCn = nil
	end

	MasterControl:AddToPlayerMovement(-currentMoveVector)
	currentMoveVector = Vector3.new(0, 0, 0)
	MasterControl:SetIsJumping(false)
end

return KeyboardMovement
