(this should go without saying, but the #1 best way to speed up loops in a game is to figure out ways to avoid running it 50,000 times in the Draw event)
First of all, thank you for this. I got much joy from a demo copy of game maker that came in a friends moms friends book they let me burrow. Didn't have internet at home until I was old though, and I had to give it back a long time ago back when I was a kiddo. So, now, out of practice, I have struggled a while with my rigid old person brain to make game maker games like a I usedta, but with the new software, and brain was noncompliant. But your tutorials are very comprehensible and short and open ended and that makes them the best in my op. NEEEEEEEXT, not to make an ass of myself or anything, but I think DO loops are burrowed from BASIC and ASM. Unless I'm from a parrallel universe. In which case, in this universe, they're probably burrowed from Fortran, Algol, or that one that was lost to time but has a similar name to Fortran 🤔 (name is on the tip kf the tongue but I think it's staying there for now lol). My point, it's FROM somewhere. My brain lit up, and I was like "OH, THEY HAVE THOSE TOO, I LOVE THOSE!!!" Btw, do you know by any chance if they have "goto" and a way to label procedures? If not, those commands are basically baby stuff, so, I didn't suspect they would, I was just curious (I like them too though (in case you haven't noticed my brain thinks in parentheses (even if linguistic parenthesis aren't supposed to be nested or contain punctuation, lol)) so yeah) Rock on
I legit did not know you could use a comma in the initialization of a for loop. Now that I'm thinking about it, of course you can, just like you can declare multiple vars with a single "var" using commas... it just never occurred to me to do it in the for loop itself.
In practice, I find repeat() loops beneficial when FINALIZING optimizations for reusable systems. Though, I consider repeat() easier to read, so I almost always exclusively use it anyway!
there are quite a few places where it can be good for readability - eg if you need to literally repeat an action some number of times, and don't need anything by way of persistence between them like a loop counter
I'm no expert at but have used gamemaker for +4 years tho, and what I saw right now, goes to show how little I know about gamemaker. For starters, I use // to comment out. using shift + mouse drag in front the code lines you want to select. Didn't know you can also do: /* */ I haven't checked it myself and not sure if you already tested this as well, but at about 5:18 I can see you declaring a local variable N every step of the draw event. From what I've learned, running functions within draw event should be avoided and all calculations/functions should ideally be placed inside a step event. And from my experience, this has helped reduce calculation time a lot and increase framerate. And if you already know that N is most likely 50000, then why even call the function and declare it as a local variable within draw event? And assuming the number would change during the course the game, why not use an instance variable only, and only change that variable whenever needed. Wouldn't this reduce the numerous times of nonsensical local variable declaring + array_length function usage within a draw event? Or am I missing something here, because this is the way I've been taught, and shows a lot of potential performance wise. Then again, I haven't really messed around and tested the difference in performance when working with such huge number of objects. So feel free to correct me if my current knowledge on the subject is faulty.
take everything you've ever heard about the Draw event being slow and get rid of it. that comes from a misconception about what the Draw event actually is that's been floating around since before the GM8 days, and it's time for that myth to die
Would it run faster if you stored positions at which the sprite was already drawn? I.e maybe there's a hash/lookup table that uses x, y pairs as keys for a boolean that indicates whether that position has been drawn already or not.
That would most likely be a little more work on the CPU side, but it would potentially prevent fragments from being drawn if they don't have to be so it could save work on the GPU. In the particular case that you described, it probably wouldn't help much for small sprites like this one - but if you were drawing something larger it definitely might.
You could have done get_time() before and after for-loops to get difference, and then show_debug_message to see it in console. I think that would have been better than looking at fps. But maybe it was easier/clearer for this video
I'm sure this video would be great for people who know a bunch of GML, but honestly I found this to be just confusing with variable language i'm not famiiliar with
What about removing the double-access to the array (fetching ducks[i].x and ducks[i].y)? Would it speed up to get "var duck=ducks[i]" and draw_sprite with duck.x and duck.y?
(this should go without saying, but the #1 best way to speed up loops in a game is to figure out ways to avoid running it 50,000 times in the Draw event)
First of all, thank you for this.
I got much joy from a demo copy of game maker that came in a friends moms friends book they let me burrow.
Didn't have internet at home until I was old though, and I had to give it back a long time ago back when I was a kiddo.
So, now, out of practice, I have struggled a while with my rigid old person brain to make game maker games like a I usedta, but with the new software, and brain was noncompliant. But your tutorials are very comprehensible and short and open ended and that makes them the best in my op.
NEEEEEEEXT, not to make an ass of myself or anything, but I think DO loops are burrowed from BASIC and ASM. Unless I'm from a parrallel universe.
In which case, in this universe, they're probably burrowed from Fortran, Algol, or that one that was lost to time but has a similar name to Fortran 🤔 (name is on the tip kf the tongue but I think it's staying there for now lol).
My point, it's FROM somewhere.
My brain lit up, and I was like "OH, THEY HAVE THOSE TOO, I LOVE THOSE!!!"
Btw, do you know by any chance if they have "goto" and a way to label procedures?
If not, those commands are basically baby stuff, so, I didn't suspect they would, I was just curious (I like them too though (in case you haven't noticed my brain thinks in parentheses (even if linguistic parenthesis aren't supposed to be nested or contain punctuation, lol)) so yeah)
Rock on
11:58 "We simply drop a giant ice cube in the ocean every now and then"
Wow i learned so much of GMS2 in a simple way, and practical stuffs, it really feels like magic :)
Amazing content, ty so much : )
Great video, just one question: Can I lower my hand now?
give it another ten minutes, it's a good workout
I legit did not know you could use a comma in the initialization of a for loop. Now that I'm thinking about it, of course you can, just like you can declare multiple vars with a single "var" using commas... it just never occurred to me to do it in the for loop itself.
In practice, I find repeat() loops beneficial when FINALIZING optimizations for reusable systems.
Though, I consider repeat() easier to read, so I almost always exclusively use it anyway!
there are quite a few places where it can be good for readability - eg if you need to literally repeat an action some number of times, and don't need anything by way of persistence between them like a loop counter
I'm no expert at but have used gamemaker for +4 years tho, and what I saw right now, goes to show how little I know about gamemaker.
For starters, I use // to comment out. using shift + mouse drag in front the code lines you want to select. Didn't know you can also do: /* */
I haven't checked it myself and not sure if you already tested this as well, but at about 5:18
I can see you declaring a local variable N every step of the draw event.
From what I've learned, running functions within draw event should be avoided and all calculations/functions should ideally be placed inside a step event.
And from my experience, this has helped reduce calculation time a lot and increase framerate.
And if you already know that N is most likely 50000, then why even call the function and declare it as a local variable within draw event?
And assuming the number would change during the course the game, why not use an instance variable only, and only change that variable whenever needed.
Wouldn't this reduce the numerous times of nonsensical local variable declaring + array_length function usage within a draw event?
Or am I missing something here, because this is the way I've been taught, and shows a lot of potential performance wise.
Then again, I haven't really messed around and tested the difference in performance when working with such huge number of objects.
So feel free to correct me if my current knowledge on the subject is faulty.
take everything you've ever heard about the Draw event being slow and get rid of it. that comes from a misconception about what the Draw event actually is that's been floating around since before the GM8 days, and it's time for that myth to die
Now that's a Where's Walduck image if I ever saw one ^^
You are mindblowing ❤️
Would it run faster if you stored positions at which the sprite was already drawn? I.e maybe there's a hash/lookup table that uses x, y pairs as keys for a boolean that indicates whether that position has been drawn already or not.
That would most likely be a little more work on the CPU side, but it would potentially prevent fragments from being drawn if they don't have to be so it could save work on the GPU. In the particular case that you described, it probably wouldn't help much for small sprites like this one - but if you were drawing something larger it definitely might.
What about, say: for (var j = string_length(__CTRL_Name); j >= 1; j--) {...}
is j = string_length(str) checked only once in a step -1 for-loop?
iterating backwards also works
@@DragoniteSpam meaning that the string_length() call happens only once and not each iteration?
@@Ragnark1 yeah, whatever happens in the initialization section of the loop only runs once
You could have done get_time() before and after for-loops to get difference, and then show_debug_message to see it in console. I think that would have been better than looking at fps. But maybe it was easier/clearer for this video
it could have, but it's more dramatic looking at fps, and the debugger gives you microsecond timing anyway
I'm sure this video would be great for people who know a bunch of GML, but honestly I found this to be just confusing with variable language i'm not famiiliar with
What about removing the double-access to the array (fetching ducks[i].x and ducks[i].y)? Would it speed up to get "var duck=ducks[i]" and draw_sprite with duck.x and duck.y?
Infinitesimally, yes.