On May 28 2019 Blizzard release the WarCraft 3 patch 1.31.0 and with it support for lua. Up until then the only way to script WarCraft 3 maps was using the jass language (warning: old). Given the simple structure of jass it is relativley easy to translate jass to lua, even without a “real” parser. Blizzard even has one integrated into the game which lets you run your jass scripts on the lua VM. The opposite however is very difficult and one could argue even pointless.
And yet i had this galaxy-brain idea to do exactl that. It took a few years until i finally had enough motivation to actually do it.
According to my git commits i started it on January 18th, 2023 and released the first public version on April 14th, 2023. Is three months of on-and-off work a reasonable timespan to implement lua? I think it’s atleast allright.
Maybe because everybody understands the utter uselessness of it or because i suck at marketing but the thread has not garnered very much attention. While i would’ve loved to talk about the technical details of, for example, implementing coroutines in jass, i was even more interested if people would pick up that i mostly wrote this whole project as a joke.
Don’t get me wrong, it still is a somewhat complete lua implementation and it took me three months to do it but i was aware from the start that this is practially useless. But i still went ahead and spent my time on it because i thought it was funny and, maybe more important, it gave me a reason to implement some stuff i always wanted to implement, that is coroutines and a garbage collector. And let me tell you, writing a working garbage collector is not easy.
I started writing the garbage collector with at least some cleverness and efficieny in mind. I just didn’t want to write a plain-old stop-the-world mark-and-sweep garbage collector. For one i thought that it might simply be too slow for “real world” usage (which of course will never happen). But i also wanted to exploit certain designs, like the way we allocate custom objects in jass lends itself to potentially freeing all garbage collected objects in constant time, for example. But i couldn’t get it to work. In the end i could’ve probably just threw more time at it but i think the proper way™ is to just start with the simplest design and iterate from there. And yes, actually starting with the most simple design actually worked. I never iterated further on the GC but hey.
Also, maybe because it was just my environment (Jass and Wc3) that made it harder than it should be, but i appreciate a working garbage collector even more now. I think writing a correct and fast garbage collector is serious work.
Implementing coroutines on the other hand was actually not too bad. I always had a vague notion of how coroutines might be implemented but it’s just so much different when you actually have to sit down and program it. It probably helped that, from the get go, i implemented coroutines the most straight forward way: just walk the stack and copy the stackframes somewhere else. And i even gained some insight on the whole stackless- vs stackfull coroutines.
Although in the end i’m not even sure which flavour i actually like more, stackless or stackfull.
I don’t know; writing Software as a joke is encouraged. Another conclusion is that jhcr still rocks. Imagine this setup:
Of course nowadays there is not much usage of jhcr because you really should be using lua (or something that compiles to it) but you really should see if you can get any live-reload in any or your projects. It’s just so nice.
Also everything is relative. People say lua is small, but man, i had to implement a lot of syntax cases; four different loops, really? I jest of course, as lua is probably quite small compared to something like python, but if you come frome something like haskell with its famous very small core it’s still quite a bit.
lep . blog