godotengine / godotengine/godot

Forward + and Mobile renderers cause jitter in player position movement over time on machine with 1070 ti

Open
#89,128 9 comments 1 reaction 0 assignees View on GitHub
bug needs testing topic:rendering
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

Reproducable in in latest 4.3 and 4.2.1

### System information

Windows 11, Ryzen 5 5500, GTX 1070 Ti. Driver 551.61

### Issue description

My son's player character was built following this tutorial: https://www.youtube.com/watch?v=KceMokK2qFA

On his computer the character/camera will seem to lag for a frame, then for a couple frames, and eventually vibrate the screen as the character moves. When printing the X position, we were able to see that as far as the game was concerned, the player always moved consistently. We then detatched the camera from the player to see if it was a camera issue. When we did this, the player would be the only thing to begin to vibrate (again, progressively worse as the game ran).

My friend and I pulled the code up on our own machines, and low and behold we didn't see the issue. I went back to my son's machine and after several tests (including the latest Godot dev build), finally started changing renderers. We found the compatibility renderer resolved the issue. The only major difference between my son and I's machine is our graphics cards. His is a Ryzen 5 5500 cpu with 16gb ram and a 1070ti, mine is a 5800x3d, 16gb ram, with an rx 6600.
Character Script:
```gdscript
extends CharacterBody2D

@export var MAX_SPEED = 30
@export var axis = Vector2.ZERO
@export var FRICTION = 1200
@export var ACCELERATION = 500
@export var HUNGER = 100
@export var MAX_HUNGER = 100
func _physics_process(delta):
move_and_slide()

func _process(delta):
if HUNGER > 100:
HUNGER = 100

if Input.is_action_just_pressed("attack"):
$AnimationAttackPlayer.play("hit")


move(delta)


func get_input_axis():
axis.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
axis.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
return axis.normalized()

func move(delta):
get_input_axis()

if axis==Vector2.ZERO:
apply_friction(FRICTION * delta)
else:
apply_movement(axis * ACCELERATION)
func apply_friction(amount):
if velocity.length() > amount:
velocity -= velocity.normalized() * amount
else:
velocity = Vector2.ZERO


func apply_movement(accel):
velocity += accel
velocity = velocity.limit_length(MAX_SPEED)
```

Character Scene:
```
[gd_scene load_steps=13 format=3 uid="uid://ck07ddw077t14"]

[ext_resource type="Texture2D" uid="uid://dvwqmt5gam3s2" path="res://player stuff/yinou sheet.png" id="1"]
[ext_resource type="Script" path="res://player stuff/Yinou.gd" id="2"]
[ext_resource type="Texture2D" uid="uid://bm7leb73ong83" path="res://heart.png" id="3_hul3j"]
[ext_resource type="Texture2D" uid="uid://cinh8dwww5bpx" path="res://apple.png" id="4_iwnrh"]
[ext_resource type="Texture2D" uid="uid://b8lfyn1almnvc" path="res://attack.png" id="5_3la2l"]

[sub_resource type="Animation" id="1"]
resource_name = "norm"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CharacterBody2D/YinouSheet:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0]
}

[sub_resource type="Animation" id="2"]
resource_name = "up"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CharacterBody2D/YinouSheet:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [1]
}

[sub_resource type="AnimationLibrary" id="AnimationLibrary_c26su"]
_data = {
"norm": SubResource("1"),
"up": SubResource("2")
}

[sub_resource type="Animation" id="Animation_n0c7b"]
resource_name = "hit"
length = 1.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CharacterBody2D/AttackCollider/Attack:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("CharacterBody2D/AttackCollider:disabled")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.1, 0.3, 0.8),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [true, false, true]
}

[sub_resource type="AnimationLibrary" id="AnimationLibrary_w417y"]
_data = {
"hit": SubResource("Animation_n0c7b")
}

[sub_resource type="RectangleShape2D" id="RectangleShape2D_rwii4"]
size = Vector2(19.6201, 20.2144)

[sub_resource type="RectangleShape2D" id="RectangleShape2D_e8mm3"]
size = Vector2(14.8687, 17.2418)

[node name="Player" type="Node2D"]
texture_filter = 1
scale = Vector2(0.363822, 0.349291)

[node name="CharacterBody2D" type="CharacterBody2D" parent="." groups=["Player"]]
scale = Vector2(1, 1.186)
collision_layer = 5
script = ExtResource("2")

[node name="YinouSheet" type="Sprite2D" parent="CharacterBody2D"]
texture_filter = 1
position = Vector2(2.25702, -1.55343)
texture = ExtResource("1")
hframes = 2

[node name="AnimationPlayer" type="AnimationPlayer" parent="CharacterBody2D"]
root_node = NodePath("../..")
libraries = {
"": SubResource("AnimationLibrary_c26su")
}

[node name="AnimationAttackPlayer" type="AnimationPlayer" parent="CharacterBody2D"]
root_node = NodePath("../..")
libraries = {
"": SubResource("AnimationLibrary_w417y")
}

[node name="CollisionShape2D" type="CollisionShape2D" parent="CharacterBody2D"]
position = Vector2(0.692766, 1.87747)
scale = Vector2(1, 1.77246)
shape = SubResource("RectangleShape2D_rwii4")
debug_color = Color(0.996078, 0, 0.152941, 0.419608)

[node name="AttackCollider" type="CollisionShape2D" parent="CharacterBody2D" groups=["attack"]]
position = Vector2(21.989, 2.414)
shape = SubResource("RectangleShape2D_e8mm3")
disabled = true
debug_color = Color(0.423529, 0.603922, 0, 0.419608)

[node name="Attack" type="Sprite2D" parent="CharacterBody2D/AttackCollider"]
position = Vector2(-5.4972, 2.41394)
rotation = 3.14159
scale = Vector2(0.869056, -0.84317)
texture = ExtResource("5_3la2l")
hframes = 11
frame = 10

[node name="Camera2D" type="Camera2D" parent="CharacterBody2D"]
scale = Vector2(1, 1)
zoom = Vector2(10, 10)

[node name="ProgressBar" type="ProgressBar" parent="CharacterBody2D/Camera2D"]
modulate = Color(0.141176, 1, 0.466667, 1)
self_modulate = Color(0.780392, 0.780392, 0.780392, 1)
offset_left = -153.921
offset_top = -74.8324
offset_right = -82.9214
offset_bottom = -47.8324
scale = Vector2(1.0073, 0.684069)
value = 100.0

[node name="Heart" type="Sprite2D" parent="CharacterBody2D/Camera2D/ProgressBar"]
texture_filter = 1
position = Vector2(62.7593, 14.1152)
scale = Vector2(0.674541, 0.882202)
texture = ExtResource("3_hul3j")

[node name="ProgressBar2" type="ProgressBar" parent="CharacterBody2D/Camera2D"]
modulate = Color(0.960784, 0.247059, 0, 1)
self_modulate = Color(0.780392, 0.780392, 0.780392, 1)
offset_left = -153.921
offset_top = -53.1069
offset_right = -82.9214
offset_bottom = -26.1069
scale = Vector2(1.0073, 0.684069)
value = 100.0

[node name="Apple" type="Sprite2D" parent="CharacterBody2D/Camera2D/ProgressBar2"]
texture_filter = 1
position = Vector2(62.7593, 14.1152)
scale = Vector2(0.496374, 0.61629)
texture = ExtResource("4_iwnrh")
```

### Steps to reproduce

run game project
press 'Play' menu button
wait about 10-15 sec and notice that any movement of the player from the arrow keys causes jitters if your Graphics card is affected.

### Minimal reproduction project (MRP)

https://github.com/VinDoughty/CrumbledMap2

Contributor guide

Open the contributing guide

Research direction

Run the linked Minimal reproduction project and compare movement after 10–15 seconds with the Forward+, Mobile, and Compatibility renderers on the reported hardware. Start from the Character Script and Character Scene, then trace the renderer entry points involved in player and Camera2D movement; done means the jitter is reproduced, its cause is isolated, and the affected renderer behavior is covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, godot
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.