Hello,

Trying out Godot for the first time (3.4.4 stable official). Clean project, only root Node2D with a Sprite child node. Imported a small PNG image and attached it to the Sprite node. Haven't touched anything except image filtering in Import. Haven't touched preferences.

Attached this script to the Sprite:

extends Sprite

var time = 0

func _process(delta):
	time += delta
	self.position.x += 10 * sin(time * 3)
	self.rotation += delta

This moves the sprite from right to left as expected. However, every 5 seconds or so I get a dropped frame or two, and then 10 seconds later I see the sprite suddenly speeding up and "catch up" to where it's supposed to be. The motion continues and the whole thing repeats.

This happens both when play the project with Command+B and when running an exported executable. I'm running macOS Monterey 12.4 on a 2015 iMac (which has no problem with much more complex tasks including 3D games).

Does anyone know why this is happening?

Thanks a lot for your help.

  • I think, that the problem is that your code is not invariant to the frame rate changes.
    You might've just meant self.position.x = 10 * sin(time * 3), and it should work fine. But if you didn't - then let me explain.
    Image your game running at 60 FPS and at 30 FPS. In both cases, the process function will be called once per frame, so in the first case, you'd be calling it twice as much.
    Now, we can say, that value of 10 * sin(time * 3) is roughly the same for adjacent frame calls. So, if your game would run at 60 FPS, your sprite would move roughly twice as much, compared to 30 FPS. I would guess, that this is exactly what happens - your FPS fluctuates somewhat, and it leads to inconsistent movement.
    Let's consider a simple example, like self.position.x += 10. In this case, your sprite would move by 600 and 300 pixels per second, accordingly. To make it consistent, you could multiply the added value by the delta. Now, your sprite would move by 10 pixels per second in both cases. You can think of 10 as velocity and delta as time. As you probably know - time * velocity = distance.
    The same logic applies to your example - to fix it you should use self.position.x += 10 * sin(time * 3) * delta. This will make aptitude rather small, so you should probably replace 10 with 500, or something like that.
    A lot of beginners struggle with this concept, so if you still don't "get it", I would recommend you to read something like this http://kidscancode.org/godot_recipes/basics/understanding_delta/
    And as for the frame drops - I think they are pretty common on debug builds, especially on older pcs (in my experience, anyway). I'm not sure whether you can do anything about it.
    P.S. you don't have to write self.something. You can simply write position.x += 10 * sin(time * 3)

I can't duplicate this on linux. Maybe it's a mac issue.

Thank you for trying. The behavior is reproducible but is pretty random. I've managed to do a screen capture..

This looks like a major issue in the rendering or math pipeline, and doesn't look very inviting I must say (this is the first thing I try with the engine...)

Any ideas?

I doubt this has to do with Godot, for most people Godot runs well without hickups.

Do you run a virus checker ?
Any other background process, maybe caught a miner ?
Disk almost full ?
Disk damaged ?
Out of memory ?

Try analizing your pc's processes, its memory use and mass storage unit. That'll be my ideas ...

    Pixophir I have none of the conditions you mentioned. At any rate, if you look at the video I posted, you'll see that the problem is not only frames dropping, but the calculation itself going completely through the window.

    If there were only frame drops due to some background process, I would say I can understand this -- although it would seem very strange considering this is a 100-pixel sprite transformed with a sine function (I'm running Divinity Original Sin 2 and Minecraft on the same machine with no frame drops, with Mail and Safari open btw). Frame would be dropped but I'd still see the object where it's supposed to be at every moment of the animation.

    But here, frames are not only dropping, they are disturbing the mathematical calculations themselves, sending the object to positions it's not supposed to be in. IMHO, and unless I'm missing something very basic, this needs to be addressed.

    I think, that the problem is that your code is not invariant to the frame rate changes.
    You might've just meant self.position.x = 10 * sin(time * 3), and it should work fine. But if you didn't - then let me explain.
    Image your game running at 60 FPS and at 30 FPS. In both cases, the process function will be called once per frame, so in the first case, you'd be calling it twice as much.
    Now, we can say, that value of 10 * sin(time * 3) is roughly the same for adjacent frame calls. So, if your game would run at 60 FPS, your sprite would move roughly twice as much, compared to 30 FPS. I would guess, that this is exactly what happens - your FPS fluctuates somewhat, and it leads to inconsistent movement.
    Let's consider a simple example, like self.position.x += 10. In this case, your sprite would move by 600 and 300 pixels per second, accordingly. To make it consistent, you could multiply the added value by the delta. Now, your sprite would move by 10 pixels per second in both cases. You can think of 10 as velocity and delta as time. As you probably know - time * velocity = distance.
    The same logic applies to your example - to fix it you should use self.position.x += 10 * sin(time * 3) * delta. This will make aptitude rather small, so you should probably replace 10 with 500, or something like that.
    A lot of beginners struggle with this concept, so if you still don't "get it", I would recommend you to read something like this http://kidscancode.org/godot_recipes/basics/understanding_delta/
    And as for the frame drops - I think they are pretty common on debug builds, especially on older pcs (in my experience, anyway). I'm not sure whether you can do anything about it.
    P.S. you don't have to write self.something. You can simply write position.x += 10 * sin(time * 3)

      shelerr Your answer highlights my mistake in the clearest possible manner. Thanks a lot for your detailed reply.