"That, dear Aeslin, was a buffer! And a compiler! And also a loop unroller, just in case! So - what I did here is...
"Imagine that you have...instructions, for magic, like beads on a string. And there's a bead you can hang on the string, that tells magic to make a string composed of these beads.
"And you take that bead, and the bead you hang on the string after it, is a bead that says 'cast this and keep it hanging around!'
"And that was the square.
"So I put the intent I use to create light with into that square.
"And then, because I'm an overachiever, I tried something even more bullshit, and actually managed to get the magic to -
"Alright, it's time to properly explain for loops!
"So for loops are pretty simple, semantically speaking; you have the 'for' token, an initializer section, a continue-until section, and the section where you actually do the loop - there's also usually a section for 'things you execute when the loop ends', but it's not necessary for this explanation even though I used it in my code. And, here's a key thing, you don't actually need to write code that way. You could write, say, if you wanted to make five lights, 'make light one, make light two, make light three, make light four, make light five' - but it's easier to think, 'for integer i =' - okay, programmers do a lot of zero-indexed ordered lists, it's just kind of a Thing - 'for integer i = 0, i less than 5, make light i, increment i'. And that's where a compiler comes in: because it's a pain in the ass for computers to jump back and forth in the code they execute, compilers unroll loops and do a bunch of other stuff, so you can turn it into the 'make light one two three four five' of earlier.
"So, we start from the buffer. I 'compile' approximately half an intent to make lights into that buffer; I compile, actually, a method to make lights that can vary.
"And then, I unrolled a loop like that example from earlier, except, in the middle, I read the buffer for my make-a-light intent, which I had set up as a part-of-a-spell so I could feed it values - and then I fed that back into the buffer, which I then executed!
"And then, it ran! Take that, magic! I have defeated your stupid arbitrary no-looping thing!"