HTML5 Captured Mode: Mouse Events Trigger Sudden Camera Jumps . Critical Bug

Godot 4.7 and 4.6 and probably other versions.

Hello, mouse input in HTML5/web exports produces large random jumps (both relative and screen_relative), both at the moment mouse capture mode is enabled, and randomly while it’s already active. This happens consistently and essentially makes it impossible to build 3D first or third person games. I’ve searched extensively online and understand that it’s harder to handle on web due to the underlying browser APIs being different. However, this issue has somehow been solved in other engines.

If anyone has knowledge on this subject or has already encountered this problem, I’d love to know what you did to work around it. Thank you.

func _unhandled_input(event):
	if event is InputEventMouseMotion and d.device == "Computer":
		if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) or d.shiftLock:
			d.camY = clamp(d.camY - event.screen_relative.y * defaultSensivity * 1.15, -1.2, 0.85)
			d.camX -= event.screen_relative.x * defaultSensivity * 1.15

So update : for now i use a hacky solution that work pretty well on my end. But i’m not sure about how it’d work for other mouse etc..

func set_mouse_captured():
	previous_x = number
	previous_x_difference = number
	previous_y = number
	previous_y_difference = number
	mouse_frame_protection = 16
	frame_protection_multiple = 0
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

var number = 20
var previous_x = number
var previous_x_difference = number
var previous_y = number
var previous_y_difference = number
var mouse_frame_protection = 0
var frame_protection_multiple = 0
var time_reset_protection = Time.get_unix_time_from_system()

func _unhandled_input(event):
	if event is InputEventMouseMotion and d.device == "Computer":
		if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) or d.shiftLock:
			if mouse_frame_protection > 15:
				var difference_x = abs(previous_x - event.relative.x)
				var difference_y = abs(previous_y - event.relative.y)
			
				if difference_x > previous_x_difference * 5 or difference_y > previous_y_difference * 5:
					previous_x = number
					previous_x_difference = number
					previous_y = number
					previous_y_difference = number
					frame_protection_multiple += 1
					time_reset_protection = Time.get_unix_time_from_system()
					if frame_protection_multiple >= 3:
						mouse_frame_protection = 0
                        frame_protection_multiple = 0

					return
					
				previous_x_difference = max(difference_x,number)
				previous_x = max(event.relative.x,number)
				previous_y_difference = max(difference_y,number)
				previous_y = max(event.relative.y,number)

			d.camY = clamp(d.camY - event.screen_relative.y * defaultSensivity * 1.15, -1.2, 0.85)
			d.camX -= event.screen_relative.x * defaultSensivity * 1.15

func _process(_delta: float) -> void:
	mouse_frame_protection += 1
	if frame_protection_multiple != 0 and Time.get_unix_time_from_system() - time_reset_protection > 1:
		frame_protection_multiple = 0```

Update : While it work correctly on 500Hz mouse and below, anything above will still bug no matter my code or not. So it’s unplayable for high polling mouse. And without my controle damage code it’s unplayable on all mouse polling

This is not a bug I have ever seen, and my mouse is a high end gaming mouse that definitely can move faster than 500hz. I’ve never had an issue with a captured mouse pointer being responsive, and in fact typically have to make the mouse less responsive to make it work smoothly.

The issue is in your code, but you have not provided your full code. What you have provided seems overly complex for what you are trying to accomplish.

It looks like you’re trying to do a 3rd-person controller. Check out my Camera3D Plugin. It works fine in a browser export. You can either adapt the code or just use the plugin.

It’s not about my code, it’s about event jump. I can even show you the problem from an empty place just by printing the event. Unity used to have the same bug a few years ago but have been solved. Some popular web game that have been made with other engine can have the issue as well but it’s less common

And without any code to detect the unatural mouse motion, it’s unplayable basically, as the event jump every 10-30 seconds when it’s in captured mode.

If it’s an engine bug then you should go to Godot issues on GitHub and:

  1. Search to see if an existing bug has been raised already
  2. If it has, then vote up the issue and add any additional context you might have found
  3. If not, then raise a new bug with a minimum reproducible example
1 Like


here you can see just the event print. It would be the same with or without your plugin.

Thank you i planned to do a post about it, but yea was just looking here before actually report the bug, just in case

1 Like

Not in my code it doesn’t. Case in point: My game Prisoner 42 is a web game that has no Gameply stuttering with its 3rd person controller. If you don’t believe me, try it.

Again, you did not post full code, and I believe what you are seeing is a result of your code and not Godot’s performance.

I have also just tested it with my plugin, and I do not get numbers anywhere near to what you got.

What you say is just the event print, is demonstrably not just that. This code would be that.

func _input(event: InputEvent) -> void:
	print(event.screen_relative)

I recommend you try changing screen_relative to relative in your code and see if the problem goes away. While the documentation recommends using screen_relative for mouse aiming, I have found in testing that relative provides smoother performance.

Empty place 100%. Nothing only one script and the html5 export. The bug occur.
What version of godot your game use ? In case you think thoses are natural movements, it’s pretty much impossible to go from 0 to 380+ in a single mouse movements without momentum @dragonforge-dev

The game uses 4.4.1. I’ve also used it in 4.5.1, 4.6.1, and 4.7-dev1. I just did all my testing in 4.6.1

In 4.6.1, this is what I get when I print event.relative.x with a captured mouse:

Summary

3.0
-7.0
-14.0
-15.0
-18.0
-14.0
-5.0
-2.0
-6.0
-7.0
-11.0
-15.0
-13.0
-8.0
-2.0
3.0
14.0
24.0
31.0
26.0
31.0
34.0
30.0
25.0
19.0
10.0
2.0
6.0
12.0
21.0
19.0
14.0
11.0
11.0
8.0
3.0
2.0
1.0
0.0
-2.0
-4.0
-4.0
-7.0
-10.0
-12.0
-11.0
-11.0
-12.0
-11.0
-12.0
-11.0
-10.0
-11.0
-8.0
-14.0
-17.0
-14.0
-8.0
-4.0
-1.0
-1.0
-7.0
-9.0
-13.0
-14.0
-18.0
-15.0
-11.0
-10.0
-9.0
-8.0
-10.0
-15.0
-17.0
-17.0
-21.0
-14.0
-11.0

If you’ve got an MVP, I recommend you post the bug. This seems like it could be a hardware or driver issue.

1 Like

Okay so i have published my game in Itch io to see. And yes in Itch io it look like it’s like 95% fixed. Small bumps when i lock but seem to stay consistent when i’m lock, nothing like inside godot. I’ll test a bit longer and mark your answer as a solution if the problem don’t persist. Thanks @dragonforge-dev

1 Like

Ok so yea inside itch io it’s almost perfect. Hopefully other hosting game website work like itch io

1 Like