6
\$\begingroup\$

Is there a do ... while (condition) loop in GDscript? The documentation explains while but makes no mention of do while.

I have some code that I want to execute at least once, and then continue looping until a condition is met. Using a plain while is insufficient because it may not execute at all depending on the value of the condition at the start.

The editor tells me that the following is invalid:

  do:
      # a bunch of stuff
  while (condition == true)

Do I need to duplicate the "bunch of stuff" (or replace with function call) and run it once directly and then loop with a while loop (and remember to change both every time I change the code), or is there a do-while-equivalent structure in GDScript?

\$\endgroup\$
4
  • \$\begingroup\$ This page suggests to do a "while true", then at the end, check your condition and "break" if the condition is met. I understand having a "real" do-while loop would be the best solution, but that other option might be a bit cleaner than some other. \$\endgroup\$
    – Vaillancourt
    Feb 23, 2022 at 1:56
  • 1
    \$\begingroup\$ Interesting. I didn't realize Python also doesn't have a do while. That led me to stackoverflow.com/q/743164/866022, which presents a couple options that I think should work for emulating this type of loop. \$\endgroup\$
    – yoozer8
    Feb 23, 2022 at 2:03
  • \$\begingroup\$ You can always replace a do-while with a simple while, so I guess there is no explicit need for such a construct. \$\endgroup\$
    – QBrute
    Feb 23, 2022 at 9:59
  • 1
    \$\begingroup\$ @QBrute yes, but having language-level support for "do this at least once" is nice. It's not a huge pain (there are fairly simple workarounds), just a minor annoyance. \$\endgroup\$
    – yoozer8
    Feb 23, 2022 at 14:11

1 Answer 1

9
\$\begingroup\$

Is there a do ... while (condition) loop in GDscript?

There isn't. The documentation does not mention anything like that, as you found out.


I have some code that I want to execute at least once, and then continue looping until a condition is met.

You can do something like this:

while true:
    # some other code
    if condition:
        break

You, of course, don't have to use break at the end. You can use this approach to exit early at any point of the loop.


Do I need to duplicate the "bunch of stuff" (or replace with function call) and run it once directly and then loop with a while loop (and remember to change both every time I change the code), or is there a do-while-equivalent structure in GDScript?

Unrolling the first iteration before the loop is viable too, however there isn't much point in doing that in GDScript. And yes, making a function is also an option, which you could call once before the loop. Something like this:

iteration()
while not condition:
    iteration()

If you are considering making a function, consider also having it return a bool, and in the function you can exit early with return. You would then use it like this:

while iterate():
    pass

And if you really want to over-engineer this… Although Godot does not have proper generator functions, it is possible to make a custom iterator.

But why? Use break, it is fine.

\$\endgroup\$
3
  • \$\begingroup\$ Although I don't disagree with just using break, I do think there's readability-improvements to having an iterator function. At least it's a useful pattern in Python, haven't tried it yet in Godot - but about to. \$\endgroup\$
    – Cyclops
    Nov 9, 2023 at 14:40
  • \$\begingroup\$ @Cyclops if by iteration function you mean a generator, GDScript does not have them (although GDScript has coroutines, they do not make up an iterator). The custom iterator you can make in GDScript is a class. \$\endgroup\$
    – Theraot
    Nov 9, 2023 at 15:48
  • \$\begingroup\$ Theraot, looking at that doc, it says it can be used in a for-loop. Yeah, you have to do an iterator.new() first, but close enough. \$\endgroup\$
    – Cyclops
    Nov 10, 2023 at 17:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .