• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

For-Loop Issue / Question

Nidoking

Member
Is this really the sort of thing where you're intending to work in a diagonal line? You only need one variable since they're both going to have the same value. If you want to loop over all of the pixels in the board, you'd use nested loops.
 
You can do things like this, not that this particular example is useful:
Code:
    for({var a = 0; var b = 1; var c = 0;}; a < b; {a += 0.5; b += 0.25; }){
        c += 1;
    }
EDIT: And this is me trying to figure out how far you can take it. This compiles and works fine in GMS1.4 at least:
Code:
    for({var a = 0; var b = 1; var c = 0; repeat(5) {c += 1;} show_message("starting"); var text = get_open_filename("", ""); var file = file_text_open_read(text); if(c < 0){exit;}} ; a < b; {a += 0.5; b += 0.25; show_message("incrementing"); show_message(file_text_read_string(file));}){
        c += 1;
    }
}
 
Last edited:

YamboGames

Member
Is this really the sort of thing where you're intending to work in a diagonal line? You only need one variable since they're both going to have the same value. If you want to loop over all of the pixels in the board, you'd use nested loops.
Im doing a connect 4 game, and the moment im not checking the most middle line of all diagonals, this wouldnt work i guess :/
 

YamboGames

Member
You can do things like this, not that this particular example is useful:
Code:
    for({var a = 0; var b = 1; var c = 0;}; a < b; {a += 0.5; b += 0.25; }){
        c += 1;
    }
EDIT: And this is me trying to figure out how far you can take it. This compiles and works fine in GMS1.4 at least:
Code:
    for({var a = 0; var b = 1; var c = 0; repeat(5) {c += 1;} show_message("starting"); var text = get_open_filename("", ""); var file = file_text_open_read(text); if(c < 0){exit;}} ; a < b; {a += 0.5; b += 0.25; show_message("incrementing"); show_message(file_text_read_string(file));}){
        c += 1;
    }
}
This seems really helpful!! Thank you, ill reply later if it worked :)
 
Code:
    for({var a = 0; var b = 1; var c = 0; repeat(5) {c += 1;} show_message("starting"); var text = get_open_filename("", ""); var file = file_text_open_read(text); if(c < 0){exit;}} ; a < b; {a += 0.5; b += 0.25; show_message("incrementing"); show_message(file_text_read_string(file));}){
        c += 1;
    }
}
I busted out laughing just imaging someone actually writing code like this.
 
it seems like it doesnt work in gms2
You can initialize multiple variables just fine by writing it like var xx = 0, yy = 0;. It's not ideal, but for now you can just increment xx in the for loop and add ++yy to the end of the body of the for loop. I recommend filling out a bug report, though. It definitely doesn't make sense that you can't bracket multiple statements in a for loop.

 

TheouAegis

Member
Yeah, in the screenshot,

var xx = 0, var yy = 0;

needs to be

var xx = 0, yy = 0;

And as for writing for loops with multiple parts and who does such things:
TheouAegis said:
Code:
for(var X=2, Y=2, W=(room_width >> 4)-1, H=(room_height >> 4)-1;
    Y < H;
    {X++; if X==W {Y++; X=2;} } )
In a for(A; B; C; )
A;
must be a single declaration. Note that "var a,b,c;" is considered one declaration. "a=0; b=0;" is two and thus invalid. Using brackets won't change that. The IDE won't catch it, but the compiler will.
B; must be a boolean clause within GM's rules. In other words, this would be valid: for(var i=5; i; i--; )
C; just needs to be a valid block of code. Anything beyond one statement must be encapsulated in brackets and must be proper GM syntax.
 

TheouAegis

Member
for({var a = 0; var b = 1; var c = 0; repeat(5) {c += 1;} show_message("starting"); var text = get_open_filename("", ""); var file = file_text_open_read(text); if(c < 0){exit;}} ; a < b; {a += 0.5; b += 0.25; show_message("incrementing"); show_message(file_text_read_string(file));}){ c += 1; } }
That doesn't compile at all for me. The IDE won't catch the error, but the compiler does. Or are you using YYC? I just use the normal compiler.
 

Yal

🐧 *penguin noises*
GMC Elder
It definitely doesn't make sense that you can't bracket multiple statements in a for loop.
I'd say "force people to write readable code" makes sense, Python is designed to force you to indent your code for instance so code style as a design choice for a language isn't unprecedented.

That said, though, GM is very peculiar about for loops - you need exactly one statement in each semicolony. for( ; ; ){} is a perfectly valid infinite loop in C, but is illegal in GM. I occasionally have a need to continue a previous for loop (e.g. when loading a menu with part inventory items and part empty defaults)
for(c = 0; c < firstmax; c++){
do_one_thing()
}
for(; c < secondmax; c++){
do_another_thing();
}

, which isn't valid, so I've settled on the stupid
for(c = 0; c < firstmax; c++){
do_one_thing()
}
for(c = c; c < secondmax; c++){
do_another_thing();
}

instead as a workaround.
 
Last edited:

TheouAegis

Member
I'd say "force people to write readable code" makes sense, Python is designed to force you to indent your code for instance so code style as a design choice for a language isn't unprecedented.

That said, though, GM is very peculiar about for loops - you need exactly one statement in each semicolony. for(;;){} is a perfectly valid infinite loop in C, but is illegal in GM. I occasionally have a need to continue a previous for loop (e.g. when loading a menu with part inventory items and part empty defaults)
for(c = 0; c < firstmax; c++){
do_one_thing()
}
for(; c < secondmax; c++){
do_another_thing();
}

, which isn't valid, so I've settled on the stupid
for(c = 0; c < firstmax; c++){
do_one_thing()
}
for(c = c; c < secondmax; c++){
do_another_thing();
}

instead as a workaround.
At that point, why not just use while? When that situation comes up for me, I switch to while. So if I need to set the starting point, I use for. If I already have the starting point set, I use while. I mean... That's kinda what while is for.

For: When you need to set a starting point and an ending point, ending point could optionally change mid-loop.
While: When you already have a starting point but need an ending point, ending point could optionally change mid-loop.
Repeat: When you already have a starting point and an ending point, ending point cannot change mid-loop (the value may change, but not the point itself).
 

Yal

🐧 *penguin noises*
GMC Elder
At that point, why not just use while? When that situation comes up for me, I switch to while. So if I need to set the starting point, I use for. If I already have the starting point set, I use while. I mean... That's kinda what while is for.

For: When you need to set a starting point and an ending point, ending point could optionally change mid-loop.
While: When you already have a starting point but need an ending point, ending point could optionally change mid-loop.
Repeat: When you already have a starting point and an ending point, ending point cannot change mid-loop (the value may change, but not the point itself).
My use is more like this:
For: when you have a loop of set size
While: when you have a loop of indefinite size and also don't need to keep track of which iteration you're on
Repeat: when you have a loop of set size and don't need to keep track of which iteration you're on
Do-until: when you have a while loop but wanna make sure you run it at least once
 
I'd say "force people to write readable code" makes sense, Python is designed to force you to indent your code for instance so code style as a design choice for a language isn't unprecedented.
Nonsense. A for loop with multiple statements can be perfectly readable, as long as it's not overboard like the purposefully ridiculous one earlier.

That said, though, GM is very peculiar about for loops - you need exactly one statement in each semicolony. for( ; ; ){} is a perfectly valid infinite loop in C, but is illegal in GM. I occasionally have a need to continue a previous for loop (e.g. when loading a menu with part inventory items and part empty defaults)
What are you talking about? for( ; ; ){} is perfectly valid in GM.
 

TheouAegis

Member
I'm using GMS 1.4 something, and the normal windows compiler.
Well like I said,I get an unexpected operator error on the first block. GMS1.4 final.


What are you talking about? for( ; ; ){} is perfectly valid in GM.
I'm on my way to work right now, so I can't verify this one on my computer. Are you sure it is completely 100% valid? The IDE will tell you lots of things are valid, but as soon as you run the compiler you will get errors.
 
I'm on my way to work right now, so I can't verify this one on my computer. Are you sure it is completely 100% valid? The IDE will tell you lots of things are valid, but as soon as you run the compiler you will get errors.
Yep. Runs just fine in GMS2. Have to break it at some point to prevent the obvious infinite loop, though.
 

curato

Member
in the original code xx and yy would have been the same thing as they started with zero and both are incremented at the same rate. You could have replaced them with one variable and got the same effect. I am not 100% of the intended logic but maybe nesting one for loop inside the other would give the effect you are looking for.
 

TheouAegis

Member
You know what, it looks like I copied an extra } at the end there. Could be the reason it wont compile for you.
No, that popped up an IDE error, not a compiler error.

GMS1.4f compile error:
Code:
Remove DnD...System.FormatException: Input string was not in a correct format.
   at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args)
   at System.String.Format(IFormatProvider provider, String format, Object[] args)
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..(List`1 , List`1 , Int32 )
   at ..( , String , String , List`1& , Boolean , Boolean )
finished.
Compile Scripts...finished.
Compile Objects...
Error : gml_Object_obj_Player_StepNormalEvent_1(166) : Expected id or string

Error : gml_Object_obj_Player_StepNormalEvent_1(166) : got 'var' expected ':'

Error : gml_Object_obj_Player_StepNormalEvent_1(166) : unexpected symbol "var" in expression
System.FormatException: Input string was not in a correct format.
   at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args)
   at System.String.Format(IFormatProvider provider, String format, Object[] args)
(I pasted the code inside a switch case that wasn't even going to get called, but the compiler crashed at it. Well, not "crash", since it finished compiling everything else before shutting down.)

In GMS2, the IDE even hates it.
Code:
Compile Objects...
Error : gml_Object_oPlayer_KeyPress_32(0) : Expected id or string

Error : gml_Object_oPlayer_KeyPress_32(0) : got 'var' expected ':'

Error : gml_Object_oPlayer_KeyPress_32(0) : unexpected symbol "var" in expression

Error : gml_Object_oPlayer_KeyPress_32(0) : got 'var' expected ',' or '}'

Error : gml_Object_oPlayer_KeyPress_32(0) : got 'var' expected '}'

Error : gml_Object_oPlayer_KeyPress_32(0) : malformed assignment

Error : gml_Object_oPlayer_KeyPress_32(0) : unexpected symbol "var" in expression

Error : gml_Object_oPlayer_KeyPress_32(0) : got 'var' expected ')'

Error : gml_Object_oPlayer_KeyPress_32(0) : malformed assignment
finished.
...
Error : gml_Object_oPlayer_KeyPress_32(0) : malformed for statement
Final Compile...finished.
...
FAILED: Run Program Complete
For the details of why this build failed, please review the whole log above and also see your Compile Errors window.
 
No, that popped up an IDE error, not a compiler error.

GMS1.4f compile error:
Code:
snip
(I pasted the code inside a switch case that wasn't even going to get called, but the compiler crashed at it. Well, not "crash", since it finished compiling everything else before shutting down.)
@flyingsaucerinvasion is likely using an older version of GMS1. I'm running 1.4.1772 and it compiles and runs just fine there. Some bug between that and the latest version might have gotten fixed that changed functionality. There were plenty of improvements to for loops going from GMS1 to 2, so it makes sense that things were altered even further.
 

Yal

🐧 *penguin noises*
GMC Elder
@flyingsaucerinvasion is likely using an older version of GMS1. I'm running 1.4.1772 and it compiles and runs just fine there. Some bug between that and the latest version might have gotten fixed that changed functionality. There were plenty of improvements to for loops going from GMS1 to 2, so it makes sense that things were altered even further.
Well, GMS2 doesn't like it either (as you would've seen if you'd read TheouAegis' post):
In GMS2, the IDE even hates it.

/.../

Error : gml_Object_oPlayer_KeyPress_32(0) : malformed for statement
 

TheouAegis

Member
for(; c < secondmax; c++)
BTW, now that I've been home, I finally tested this in GMS1.4 and it does work, like nacho said.


for( ; ; ){} is perfectly valid in GM.
In GMS1.4, that's not valid, as only the first part can be left blank. A for loop requires a condition and a consequence. I verified in GMS2, though, that for loops have no requirements at all. So yeah, for( ;; ) is legal in GMS2, but not GMS1. I'm curious how the compiler actually codes that. It's essentially a while(1) loop, but not.

Edit: WTF, that's weird. So for( ;; ) is valid, but not for( ; ; ; ). However in a normal for loop, for( i=0; i<4; i++; ) is fine -- the third semi-colon doesn't affect anything normally unless the for loop is malformed.
 
Last edited:
Top