I'm afraid we'd need significantly more info than that. How have you architected your game. What does your composition look like. You make heavy use of physics? Where do the stutters occur, in physic or in process or what?
Stuttering in scene on Ubuntu: Turning off Vsync slightly fixes it. Using Godot4
- Edited
Hey there Mega, thank you very much for replying to my post. Absolutely, I'd be happy to share more information. I brought my laptop to work just in case.
I'm actually not using heavy physics, yet. Just the following:
- CSGBox3D
- CSGMesh3D (for the floor) with collision on.
- The Player
When you mean if the stuttering occurs in _physics_process or _process, I got to be honest, I'm not very sure, but I can share the code below, it's very short. I am calling move_and_slide in _physics_process() though.
1) Main Scene
The project starts off with this scene. I'm using a Subviewport | VIewport since I plan on doing some post processing effects. Not yet though.
You'll notice the PlayerCamera is on its own, however the Player Scene, located in the Sandbox scene, picks up the Camera and uses it.
Let's look at that real quick:
As you all can see, my player is not a complicated setup, just a CharacterBody3D and its collider. Let me go ahead and share the code though, it's not very long:
extends CharacterBody3D
@export var run_speed: float = 3.0
var _current_speed: float
var _look_axis: Vector2
var _rotation_velocity: Vector2
var _direction: Vector3 = Vector3.ZERO
var _movement_velocity: Vector3 = Vector3.ZERO
@onready var _body_collider: CollisionShape3D = $"BodyCollider"
@onready var _head: Node3D = $"Head"
var _camera: Camera3D
func _ready () -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
_camera = find_parent("SubViewport").find_child("PlayerCamera")
_current_speed = run_speed
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
_look_axis = event.relative
func _process(delta: float) -> void:
_update_camera(delta)
_update_direction()
_reset()
func _physics_process(_delta: float) -> void:
velocity = _movement_velocity
move_and_slide()
_camera.global_position.x = global_position.x
_camera.global_position.z = global_position.z
_camera.global_position.y = _head.position.y
func _update_camera(delta: float) -> void:
_rotation_velocity = _rotation_velocity.lerp(_look_axis * 0.3, delta * 13.0)
_head.rotate_x(-deg_to_rad(_rotation_velocity.y)) # Pitch
rotate_y(-deg_to_rad(_rotation_velocity.x)) # Yaw
_head.rotation_degrees.x = clamp(_head.rotation_degrees.x, -90.0, 90.0)
_camera.global_position.y = _head.global_position.y
_camera.rotation_degrees.x = _head.rotation_degrees.x
_camera.rotation.y = rotation.y
func _update_direction () -> void:
var move_input: Vector2 = Vector2.ZERO
move_input.x = Input.get_action_strength("Move Right") - Input.get_action_strength("Move Left")
move_input.y = Input.get_action_strength("Move Backward") - Input.get_action_strength("Move Forward")
move_input = move_input.normalized()
_direction = transform.basis * Vector3(move_input.x, 0.0, move_input.y)
_movement_velocity = _direction * _current_speed
func _reset () -> void:
_look_axis = Vector2.ZERO
That's all. That' the game so far
In terms of project settings:
- I just made sure Vsync is ENABLED which I believe it is by default
- Viewport Width/Height is set to 1280x720 and the mode is Windowed.
Physics Ticks Per Second was left at the default 60. Nothing else was changed.
I also forgot to mention in my post, I ran nvidia-smi in the terminal I get the following:
NVIDIA-SMI 525.85.05 Driver Version: 525.85.05 CUDA Version: 12.0
If you need more information, I can provide anything you need. I'm refreshing this page all the time so I'm here.
Thanks again!
DonnieDarko When you mean if the stuttering occurs in _physics_process or _process, I got to be honest, I'm not very sure
If you look at the profiler in editor when the stutter occurs in the running game instance, there should likely be a spike or some set of spikes in the profiler graph. Which color line do they occur in? You might have to toggle profiling flag to on for specific things on the right side of the profiler.
- Edited
Hopefully this is what you're referring to, forgive me if it's not though:
The bars all look greenish. The other three options (physics and process time) look unticked but before taking the screenshot they were ticked.
- Edited
Yes, tick the process and physics time on as well. As follow up later also explore perhaps the Script Functions options.
Also while the in editor profiler is good to have it is worth noting there are some good alternatives too such as RenderDoc.
- Edited
- Edited
Also worth looking at the monitor tab. And try and see what happens in the game when the spikes occur.
Mind you it could be as simple as since your project isn't very demanding yet every little thing can cause a relative spike. Once you have more demanding things going on both graphically and with regards to physics the things that are currently noticeable as significant spikes might become just comparatively small noise.
But getting to know the profiling tools is likely going to come in handy since they can help find out what frame the time spikes were on and help you narrow down where and what might be taking place causing them.
- Edited
Got it, just checked! I also updated my previous post with a second screenshot and the spike is in the _process(), huge spike. I also checked the monitor tab and it also seems to point to the process tab.
I might appear offline, but I'm here. Internet is very poor where I am so I need to switch my modems all the time
- Edited
DonnieDarko I also updated my previous post
So did I. Seems I did so a minute later than you. Looking at the screenshot it doesn't seem to be a script function. At least that's not immediately obvious.
1 thought though, what if you temporarily moved things out from underneath the viewport/container and hid or maybe even temporarily removed the viewport and container.
Megalomaniak
That's a good idea, just did. I completely removed the Subviewport|Viewport stuff and it's an even simpler scene:
However I get the same stuttering. I tried removing the update_camera function since the profiler is saying the issue is in _process, but same issue.
That's one thing ruled out, another is to see if the CSG might be causing it. Note: if it is, you can still use CSG meshes and try and see if configuring some properties might affect/improve it or there is also an option to export your CSG mesh as a static one that you can then load into a 3D modeling tool or just import/load back as is into godot as a static mesh.
I just removed all the CSG stuff and imported a GLB of a cube from Blender and unfortunately I still get the stutter. The scene is the Player, PlayerCamera and the cube imported from Blender.
Also did a few more things:
- I removed all the code from the Player Script, there's only one line which is
extends CharacterBody3D
and I'm still getting a spike in the profiler. - Removed everything in the scene, so no code, player, meshes, just an empty Node3D and still getting a spike in Process Time, it's clocking at 25 to 65.3
- Edited
Yeah, so it leads me to conclude that it might just be
Megalomaniak Mind you it could be as simple as since your project isn't very demanding yet every little thing can cause a relative spike. Once you have more demanding things going on both graphically and with regards to physics the things that are currently noticeable as significant spikes might become just comparatively small noise.
Or it could be something in the core of godot that will get fixed in the upcoming releases in which case you have nothing to do until then but just keep working on your project and updating it to newer point releases of the engine until one of them fixes this. But again, it could also be that as your project complexity grows it over takes this and the current stutter you perceive will disappear on it's own as just minuscule background noise.
This is why the age old adage is not to optimize early. Seriously read the link, it actually refutes the notion that you shouldn't be concerned with optimization but the point still holds, you also shouldn't get bogged down with trying to optimize something that turns out not to be a real issue at all in the end.
If you are really still desperate to test something out though, you can try adding a script to every node in the scene and in the _ready(): set the nodes processing to false. Mind you that would just confirm my background noise theory. By default every node processes, just a node without a script processes nothing.
The cost is really tiny, but as I said, if you don't yet have much going on in your project it might seem more significant that it really is.
Understood and thank you for sharing that article btw, I'll 100% give it a read, I was definitely worrying about these spikes too much and I got nothing yet.
You did give me an idea when you spoke about future releases fixing these issues. I downloaded Godot 3.x (LTS) and I didn't add anything, just an empty scene and the profiler doesn't seem to spike like I showed you. I'll try making a quick first person controller and test a little more.
But you're right, I'll keep working on the project in Godot 4 and wait for future releases.
Mega, thanks again for taking the time to help me out. I really appreciate it. Hope you have a great day.