Well as far as making VB dll's, the decorated names don't change everytime... You just check the first time it is compiled. (Actually I think for all functions this is the decoration they use):
?FuncName@ModuleName@@AAGXXZ
Speaking of the interpreter library.. let them pass in the code or whatever they want to use to the library, (or maybe just make a bunch of function calls to 'explain' to the interpreter what they are trying to do; sort of like a "macro recorder". Say for example -- "pseudo" C++ code:
(assume interp is a pointer to the class exposed by the interpreter library... probably wouldnt be the case though because other languages won't support C++ classes necessarily, except thru COM)
int idVortex = interp->CreateTrigger("Vortex");
interp->BeginMacroRecord(idVortex);
// now here they can call the functions that their trigger would do.
interp->SetVortex(x,y,z,a,b);
interp->EndMacroRecord();
// now when the trigger is called this "macro" will be played back.
The only problem with this model would be how the trigger "macro" would access needed vars such as instances of Units, etc. (well: the interpreter would have to store them because the language frontend wouldn't be able to invoke their methods directly.. maybe just allow them to get handles and perform actions via the handle.)
Also, if the language can't export true functions, maybe have the interpreter accept a pointer to a function. (Many languages can do this "normally"... including VB with it's AddressOf operator)
But since OP2 calls triggers using the text name, the interpreter would have to export a bunch of generically named triggers eg. Trigger1, Trigger2 ... Trigger99
Then inside each of those trigger procs, the pointer to the function would be invoked and the custom trigger code would be run.
Sound good?