I've included a TLDR and examples at the bottom if you want the short version, otherwise...
Just giving you a quick warning. Was working on some semi-complex triggers in a map tonight and I hit save. Guess what error I get?
"Code jump out of bounds (Try reducing the size of very large functions)"
Great. Just what I needed. First, it appears the limit on the size of code seems arbitrarily small (I didn't have any extremely large functions), and that means I can't finish any of my triggers, meaning the last 100 hours I've put into this map were wasted.
So, I scan through the generated code to figure out what's taking up so much space, and lo and behold, it's two specific triggers. Both have nested "For" statements. One of them has relatively uncomplex actions within the for loop, but has 4 nested loops. I start comparing code sizes. The entire set of generated code is about 240,000 characters.
The function with 4 nested loops is taking up a whopping 100,000 (!) characters of that, and the other nested function is taking up another 80,000. WTF!
I took a closer look, and it appears Blizzard's implementation of nested For loops is extremely messy. So, I decided to try something, and changed one of the 4 nested For loops to a While loop (the outermost loop) with exactly the same functionality, so instead of 4 For loops, it's 3 For loops and 1 While loop. The generated size of the function dropped from 100,000 characters to 40,000 immediately. I replaced the rest and have not had a problem since.
TLDR: Nested For loops are VERY inefficient and generate ridiculously large blocks of code, which will take up a large part of your space allocated for triggers. USE WHILE LOOPS INSTEAD OF FOR LOOPS if you will be nesting them and avoid the hour of frustration I just endured.
P.S., Blizzard, it would be extremely grand if you could clean the nested For code generation up for us! =D
Okay, here's the example. Both functions are completely identical, one using nested While loops, the other using nested For loops.
yeah, i noticed this yesterday actually i had 3 for each int loops in one trigger (inside eachother) and i ended up with a code jump out of bounds error, i replaced them with whiles and it reduced the lines of code in my map by over 200 lines, and fixed the error
its too bad since the while loops are more annoying to use, oh well
as I said there, "interesting" . And ive already submitted it to the news thread ^_~
Though... im a for loop user.. I dislike the while for w/e reason... Has anyone else -confirmed- this? just seems so random.
Yeah, I love for loops too... so much, in fact, that I coded my own custom for loop action so I could have the same functionality without all the code mess and/or hassle of setting up whiles properly. =P
I just posted in the Blizzard thread as to how you can verify it yourself Molsterr, shouldn't take more than 5-10 min to test. Go ahead and give it a whirl.
A for loop is just a while loop with a variable for iterating and a break inside of an if statement when the iterator gets too big.
The increase in code size is probably because of nested loop optimization which are signs of good programming rather than any kind of bug or mistake.
Why use nested loops in scripting any way? Any system you create doing that for even moderately sized data sets is going to tear apart the game logic time frame. Find some other way to do it, use a data structure that you update or poll.
Blizzard should spend less time making it that user friendly.... It just screws up the look of it all.
They should not check which value is higher, and state that the first value must be higher then the second value. and remove all those stupid if statements of theirs.
or add 1 simple check if the first is higher then the last. if not the swap the variable content around so it does match the criteria of the first value being higher then the last.
Think I'll just go create a new For Loop myself that fixed this so it is usable.
It has little to do with being user friendly and a whole lot to do with keeping the game from hanging or freezing.
Heck, the code expansion and the limit might even be a "keep dummies from breaking this" kind of fail-safe for GUI users because they don't know that you can break a game by doing too much at once.
Heck, the code expansion and the limit might even be a "keep dummies from breaking this" kind of fail-safe for GUI users because they don't know that you can break a game by doing too much at once.
It's more like a "we don't know how to implement virtual machines properly".
I got 244k chars in my code but it seems fine... for now.
Edit: Ok guess it's not total code size so I should be fine. Duplicated all my code 3 times to get 704k chars and saved & played fine. I'll try to find the bounds for function code size.
The main problem with the For loops is that they generate an If..else statement. Now, apparently, the else part of each If..else statement would be used in cases where it is a decrementing For loop. Hence, the GUI has to therefore copy the entire loop body into the else statement.
Now, a For loop is either incrementing or decrementing making half of every For loop completely useless. Blizzard should start, then, by fixing the if..else statements that create whole copies of the same code.
Is this a problem for non-nested For loops? Should we still use While loops over a single For loop? Or is the efficiency problem only apparent once you start nesting them?
For-loops are always messy. For a non-nested loop is much less problematic. A while loop would still be more efficient, but the different is far smaller.
If your nesting 6 loops deep your doing something wrong IMO
also when doing heaving looping put a wait in for .01 this helps keep you from overloading the trigger system in SC2
I really dont understand what you could possibly need to nest 6 loops deep. sounds like terrible logic to me.
The actual problem you ran into that you stated at the top of this post is due too to much code in a single trigger. I had this problem myself. So I took a good chunk of my code and moved it to an extrenal function that this trigger would call. That solved the -Code jump out of bounds (Try reducing the size of very large functions)"
This is just a link to my thread in the Blizzard forums, but I think it's incredibly important all mapmakers read it.
http://us.battle.net/sc2/en/forum/topic/628237153
@TheFallenOne222:
Thanks a lot for the warning. Poor For Loops, I will miss yee.
This needs to be frontpage. Is very important for all the large projects out there.
as I said there, "interesting" . And ive already submitted it to the news thread ^_~
Though... im a for loop user.. I dislike the while for w/e reason... Has anyone else -confirmed- this? just seems so random.
yeah, i noticed this yesterday actually i had 3 for each int loops in one trigger (inside eachother) and i ended up with a code jump out of bounds error, i replaced them with whiles and it reduced the lines of code in my map by over 200 lines, and fixed the error
its too bad since the while loops are more annoying to use, oh well
Yeah, I love for loops too... so much, in fact, that I coded my own custom for loop action so I could have the same functionality without all the code mess and/or hassle of setting up whiles properly. =P
I just posted in the Blizzard thread as to how you can verify it yourself Molsterr, shouldn't take more than 5-10 min to test. Go ahead and give it a whirl.
No biggie. =D Used loops in wc3, but I like the while loops better any who.
A for loop is just a while loop with a variable for iterating and a break inside of an if statement when the iterator gets too big.
The increase in code size is probably because of nested loop optimization which are signs of good programming rather than any kind of bug or mistake.
Why use nested loops in scripting any way? Any system you create doing that for even moderately sized data sets is going to tear apart the game logic time frame. Find some other way to do it, use a data structure that you update or poll.
@adovid: Go
bloody hell (excuse my french)
Blizzard should spend less time making it that user friendly.... It just screws up the look of it all.
They should not check which value is higher, and state that the first value must be higher then the second value. and remove all those stupid if statements of theirs.
or add 1 simple check if the first is higher then the last. if not the swap the variable content around so it does match the criteria of the first value being higher then the last.
Think I'll just go create a new For Loop myself that fixed this so it is usable.
I made a post on the b.net thread.
It has little to do with being user friendly and a whole lot to do with keeping the game from hanging or freezing.
Heck, the code expansion and the limit might even be a "keep dummies from breaking this" kind of fail-safe for GUI users because they don't know that you can break a game by doing too much at once.
It's more like a "we don't know how to implement virtual machines properly".
Read the link i put on the b.net thread. The guy who wrote that writes software for VMWare.
[Edit]Nm. That was another article, but anyway, virtual machines have performance and interactivity limitations.
@TheFallenOne222: Go
8 years in development and we get a @#%@ editor. Mega sigh...........
Wait what's the limitation exactly?
I got 244k chars in my code but it seems fine... for now.
Edit: Ok guess it's not total code size so I should be fine. Duplicated all my code 3 times to get 704k chars and saved & played fine. I'll try to find the bounds for function code size.
arghh, I hope they fix this.
Good god nested for loops w/ variables are so bad.
Is this a problem for non-nested For loops? Should we still use While loops over a single For loop? Or is the efficiency problem only apparent once you start nesting them?
Know your code - learn galaxy :D
@ZarafFaraz: Go
For-loops are always messy. For a non-nested loop is much less problematic. A while loop would still be more efficient, but the different is far smaller.
If your nesting 6 loops deep your doing something wrong IMO
also when doing heaving looping put a wait in for .01 this helps keep you from overloading the trigger system in SC2
I really dont understand what you could possibly need to nest 6 loops deep. sounds like terrible logic to me.
The actual problem you ran into that you stated at the top of this post is due too to much code in a single trigger. I had this problem myself. So I took a good chunk of my code and moved it to an extrenal function that this trigger would call. That solved the
-Code jump out of bounds (Try reducing the size of very large functions)"