So I’ve kind of ended up taking over the PRC Compednium, I think. A sentiment that gets expressed a lot is “make it more modular”. Does anyone know how the heck you would go about doing this in nwscript? Here’s a list of the ways I can think of to do any kind of modularisation/polymorphism:
#include - due to prototypes and implementations being in the same file (unlike C with .c and .h files) there’s no runtime linking. This means it’s effectively compile-time copy and paste. Useful for breaking up files into smaller files and creating shared code, but useless for modularisation (the dependency is still there).
ExecuteScript - can do runtime dynamic polymorphism (exactly what we want) but my reading suggests that it has significant overhead, has sharp limits on stack size (cannot be nested more than 8 calls deep) and child scripts count towards parent script execution limit. Also cannot return values without messing around with Set/GetLocalInt.
DelayScript - as above, but doesn’t count towards parent execution limit and the child script doesn’t have access to a few things. Can’t be used for a serial process.
Events - with UserEvents, these would be ideal. The PRC wouldn’t need any knowledge of its modules. However my understanding is that they’re just ExecuteScript under the hood and objects can’t have more than one handler for any given event (and all UserEvents count as one Event). Also, the API is really clunky.
If statements - Spaghetti. Still requires all code to be present when compiling. Will make things even buggier (every if means you’ve just doubled the paths through the code). Bad, bad, bad.
In summary: they all either suck or have some horrible drawback. Is there anything better I can use to do basic runtime polymorphism? The absolute ideal would be to be able to invert control so that modules could inject themselves into a core that has no knowledge of them.
Were this not nwscript, I would modularise it by implementing some kind of event/callback system. If it were C/C++, I could do this with function pointers and structs, an object oriented language I could use objects that implement a callback interface and in a functional language I could just pass the PRC some functions at load time that it can call later. Unfortunately, nwscript is a procedural language, which has no pointers, no lamda functions and no goto. It doesn’t even have arrays - as far as I can tell it only has forks.
P.S: What I’ve written above may be wrong. I’m writing based on my understanding. I don’t have the actual experience to back up anything I’m saying here. I’m an experienced programmer but not a very experienced with NWN scripter.