0 votes

Learning Godot has worked great for me so far, but I'd like my games to be more performant. I suspect I have some culprits in them, that hold back performance, since they don't seem to be flawlessly smooth. Does anyone have a good source, where you can learn such things?

in Engine by (840 points)

1 Answer

+4 votes
Best answer

Performance on what? If you are talking about frames per second, there are mainly two impacting factors you can tweak: CPU and GPU.

CPU usage can be reduced by making your game perform less calculations:
Choose appropriate nodes, choose the correct data structures (array? dictionary?), use fast algorithms, know what's fast and slow in the language you use, prefer signals and events instead of _process, use servers directly if nodes have too much overhead etc...

GPU usage can be reduced by making your graphics card do less work:
Draw less pixels, draw less geometry, don't stack too many elements on screen, don't stall the GPU by getting data from it, write efficient shader code (that one also depends on which platform you run on).

Optimizing your game depends on which of these two you are bound to. It's not always due to scripts, and it doesn't always mean you will need C++. It's down to knowing what things cost (which you can learn by reading docs and by experience).

If your game has performance problems, a good starting point is to have a look at the profiler tab of the editor, while you are debugging it, to see which part takes more time.
(and as always, remember it will always run a bit slower in editor than once exported).

As for optimization tutorials... it's a wide topic that can become very specific at the same time, so you may find lots of things with a web search.
So yeah... I don't know a general optimization tutorial on Godot, but if you have a more specific example showing slowness I might be able to explain more what can be done.

by (28,740 points)
selected by

Wow, didn't expect to get such a comprehensive answer! Thanks for that! So, I have a few questions on that, relating to my project (Replika of Gibbets:Bow Master for learning purposes):

  • You said, that in the editor the project runs a bit slower than once
    exported. Weirdly for me it's the other way around. Why?
  • As you can see in the project, I wrapped the scenes in
    ViewportContainer/Viewport structures, so that their sprites do not
    overlap each other during transitions. Idk if you are able to test on
    device right now, but if you did, then you'll notice that this
    structure results in a huge fps drop. Why is that?
  • If I use just Node2D and put the background and water in the
    SceneManager, so that nothing overlaps anyways, performance is way
    better, but still a bit slow, considering it's such a simple game.
    Any idea?

I hope I'm not demanding too much! If I am, just ignore what's too much!
Thank you!

  • Where are you running your exported game on? Mobiles are a lot weaker than PCs so expect less performance available from CPU and GPU (so indeed, even in the editor your game would run on a PC, which is why it runs faster)

  • I suspect that Viewports cause an entire screen redraw, because what happen is, the viewport renders itself (think of it as a "secondary screen"), then the output is re-rendered on the final viewport (the actual screen), which means the GPU has to draw twice as much pixels to get the final result. Pixels (aka "fillrate") are costy on mobile. So at this point I would say you are "GPU bound". But that's just a guess, I never used viewports for other purposes than offscreen rendering. Is the framerate improving if you don't have such structure?

  • Your water image is so big... and you draw two of them. Remember the GPU has to fill all pixels that are within the screen, even if they are later hidden by another sprite. Try to reduce that overlap maybe?

  • I tried to use the profiler but it seems broken, so I couldn't see much info... also the game tends to crash as well :(

  • Also, did you look at the logs of your game on mobile? If something is printed every frame, that might also cause a slowdown CPU-side.

I had a glance at the water code:

func _process(delta):
    for c in get_children():
        match c.name:
            "Light":
                c.translate(Vector2(-speed, 0) * delta)
                if c.get_position().x < -1079.99:
                    c.set_position(Vector2(0, c.get_position().y))
            "Dark":
                c.translate(Vector2(speed, 0) * delta)
                if c.get_position().x > 1079.99:
                    c.set_position(Vector2(0, c.get_position().y))

This could be rewritten like this, then you don't need to do a for/match loop:

onready var _light = $Light
onready var _dark = $Dark

func _process(delta):

    _light.translate(Vector2(-speed, 0) * delta)
    if _light.get_position().x < -1079.99:
        _light.set_position(Vector2(0, _light.get_position().y))

    _dark.translate(Vector2(speed, 0) * delta)
    if _dark.get_position().x > 1079.99:
        _dark.set_position(Vector2(0, _dark.get_position().y))

It's not causing a significant slowdown anyways, but it's just an example of how code can be optimized :) (and it can still be reduced but I'm too lazy for now xD)

Wow, that was a a lot of useful information again, thanks so much! What you say about the viewport structure, makes a lot of sense. And it seems to be true, because using this instead of regular Node2Ds causes a cut of 10-20 fps. Also, you opened my eyes a bit about not relying on good hardware nowadays and cutting the unnecessary, like with the water sprite. Example: I made it so big, because I thought maybe it would make the game interesting if you raised it with levels...but what if not? I even got the idea to just use custom drawing for the water and expand the vertices if necessary to solve this problem, since I already know how to do this. Also, you're right that the loop is overkill here and doesn't even result in less code xD.

So, I think I'm gonna keep both eyes open for those things instead of half one from now on, to avoid having to deal with it afterwards!

Thanks a lot again!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.