Forest Logo
search
package_2

anti-wallhop

By @cozywitchcraft

Roblox

Mirrored

anti-wallhop

Patches wallhopping from the humanoid controller

[image: Character wallhopping with the anti-wallhop turned off vs. on] [image: Side view of a character wallhopping between two walls with the anti-wallhop turned off vs. on]

Wallhopping occurs because the humanoid state machine runs before the physics simulation every frame. When the player has instant control of the character's rotation (e.g. in first person or mouse lock), its root part can clip into the level geometry. This allows the humanoid to detect floors inside walls before the simulation can force the root part out.

This module works by replacing the built-in landing transition with a custom one running post-simulation, patching wallhopping with minimal effect on the humanoid's physics.

For reference, this change affects the humanoid so little that trussflicking, which is almost functionally identical to wallhopping, is preserved.

[image: Character successfully trussflicking with the anti-wallhop turned on]

For those worried about an in-engine wallhop patch in the future, this module can also serve as a wallhop reimplementation by moving the landing floor detection from post-simulation to pre-animation. I haven't implemented this option for practicality's sake.

I'll write an article further detailing how and why this was made and link it here when finished.

You can test the latest version of the anti-wallhop here. The source code for the testing place can also be found at cozywitchcraft/anti-wallhop-testing.

Features

  • Emulates humanoid floor detection
  • Patches wallhopping
  • Visualizes floor detection raycasts
  • Supports R6 and R15 rigs

Usage

In a LocalScript in StarterCharacterScripts:

-- StarterCharacterScripts/AntiWallhopLoader
local AntiWallhop = require(path.to.AntiWallhop)

local antiWallhop = AntiWallhop.new(script.Parent)
antiWallhop:enable()

Or for those concerned about memory management, try the following in a LocalScript in StarterPlayerScripts:

-- StarterPlayerScripts/AntiWallhopLoader
local Players = game:GetService("Players")

local AntiWallhop = require(path.to.AntiWallhop)

local localPlayer = Players.LocalPlayer

local antiWallhop

local function onCharacterAdded(character: Model)
	antiWallhop = AntiWallhop.new(character)
	antiWallhop:enable()
end

localPlayer.CharacterAdded:Connect(onCharacterAdded)

localPlayer.CharacterRemoving:Connect(function()
	if antiWallhop then
		antiWallhop = antiWallhop:destroy()
	end
end)

if localPlayer.Character then
	onCharacterAdded(localPlayer.Character)
end

Installation

Using Wally

Add cozywitchcraft/anti-wallhop to wally.toml as a dependency.

AntiWallhop = "cozywitchcraft/anti-wallhop@0.1.3"

From the Creator Marketplace

Alternatively, you can get the model here.

From GitHub

API

Functions

new

AntiWallhop.new(character: Model) -> AntiWallhop

Initializes the anti-wallhop as disabled.

enable

AntiWallhop:enable() -> ()

Enables the anti-wallhop.

disable

AntiWallhop:disable() -> ()

Disables the anti-wallhop.

enableDebug

AntiWallhop:enableDebug() -> ()

Enables debug visuals. Each raycast is visualized with a line colored red or green depending on the result.

[image: Transparent character jumping with debug visuals enabled]

disableDebug

AntiWallhop:disableDebug() -> ()

Disables debug visuals and cleans up debug instances.

destroy

AntiWallhop:destroy() -> ()

Cleans up connections and debug instances because character destruction must be handled by the end user.

License

MIT

Package Details

Install command (Click to copy)


Version

0.1.3

License

MIT

check_circle

Safe for commercial use

Automated license review — not legal advice.