In modernizing my DikuMUD (ultimately a ROM deriv) I want to replace hundreds of "progs" with something more flexible. Currently, these are either modified to core functions themselves (e.g., do_say) or invoked via function pointers based on a lookup table, so whenever someone does an action the MUD might scan the room and check every entity for a my_action_prog function and if set, run it.
Ultimately, what I want is to provide a way for people to extend very specific parts of the codebase via hooks that aren't written in C and part of the MUD itself.
So what I'm wondering is what people have had success with, useful resources, etc.
I've done a lot of tinkering implementing python into ROM. This was sometime ago, so I'm not entirely sure how far along it is, but I was using boost::python. The ultimate downside is sandboxing python is next to impossible. It's very hard to constrict the language :).
Any way you go is going to be a lot of work. You simply have to add hooks in order for it to function where you want it too. This is what ultimately lead me to translate ROM to python. I suggest you start by exposing all the do_functions to whatever language you choose. This will give you the most initial functionality to test with.
There was a time when I had a pretty much identical quandary. In addition to the concerns you raised, there's the problem that regardless of the scripting syntax you choose, you may have to write your own interpreter, not just the various hooks and the code that makes those hooks useful. An interpreter in C can be a painful thing.
At the time, I remember finding a custom codebase with an integrated JS interpreter, but I also remember not being impressed with how far this person was able to take it (not far at all). I also came across some Lua script engines, but again, pretty basic, and each came married to its own codebase that I didn't really care for.
End of the day, for a C codebase, it seems to me it's quite a challenge to end up with something better than digiscripts. You'd have to really care about sandbox scripting, too, because in practice I've found spec procs to be plenty capable for any fancy footwork. The only downside to spec procs really is that they most often require code access (they can be sandboxed, but that's a different kind of work).
To save you the suspense, finally, I just decided to do more with spec procs and defer any fancy script engines for when I had a wholly interpreted codebase that lent itself to that sort of thing.
Just to throw another, equally not easy, option out there… if you like the DikuMUD gameplay mechanics, and are not tied to the actual C code itself, you could consider the idea of using a different codebase entirely and writing a mudlib that emulates the DikuMUD models for gameplay.
For example, an LPMUD already does what everyone seems to want when it comes to scripting that can be accessed by anyone, without needing access to the entire game's code. It's not impossible to rewrite (or write from scratch) a mudlib in LPC that acts just like the DikuMUD driver itself. It's not trivial, but neither is embedding a language into a DikuMUD in a useful way.
There are a couple other alternatives too, but LP is the only one I'm familiar with. Evennia is a python MUD written in python and using python for scripting. CoffeeMUD is similar for Java, but I don't think it's as heavily sandboxed.
Switching codebases is definitely off the table, as the codebase I have has already grown 3-4 times the size of its original "stock" base. A mudlib seems like overkill since only want (or need, I guess) to hook the scripting language into a very small number of pieces of the code. I suppose I'll try down the path of Lua and see how it goes.
I'm in the exact same boat as you (DikuRom->Rom) and looking to options for scripting. I'm mainly looking at Python and Lua. Nick Gammon incorporated Lua into Smaug and that might be a good place for you to look if you're interested in Lua as it may have a lot of the leg work done for you.
My [biased] opinion is that Lua is what you're looking for. At Aarchon (Rom based) we have been using embedded Lua scripting for a few years now and it's been great.
As pointed out above, Gammon has a good sample of how to start doing this in Smaug (which I used as a starting point as well).
Also check out Lunacy which is an example of how to do Lua scripting in Merc http://www.mudbytes.net/file-2735/. In the end our Aarchon implementation looks a lot closer to Lunacy than Gammon's Smaug code.
Aardwolf is using Lua as well, and though their implementation code is not public, their website does have some info on their interface, which is good to get ideas from at least https://www.aardwolf.com/lua.html.
Similarly, our Aarchon code is not publicly available, but if you're curious you can check out our online docs here: http://tester.aarchonmud.com/dokuwiki/do... In any case, I'm willing to discuss some design specifics and share some code if you want to send me private message.
Regarding Lua vs Python, the biggest drawback to Python IMO is the lack of support for sandboxing (also mentioned above). In Lua, sandboxing is very straightfoward using setfenv() [Lua 5.1]. http://lua-users.org/wiki/SandBoxes
The biggest decision you have to make is to try and sandbox each lua script individually, or sandbox a single lua interpreter to handle ALL scripts.
The lua process can only access data which has bee explicitly shared to it, so you're left with the ugly choices of… export everything in a single "world" container, and accept the security issues this will cause, or hand pick what to export and have to change it frequently as you discover more things you want to script.
IMO you have no choice but to run user scripts (progs written by builders) in a heavily sandboxed environment. We use a global interpreter which at the global level is not sandboxed in any way. Anything that runs directly in the global environment is written by myself or other core game developers and exists as part of our core codebase (Lua core infrastructure code, Lua based do_ commands, Lua libraries). The actual in game scripts (mob/obj/room/area progs) run in sandboxed environment tables with A LOT of protection against stupid and/or malicious scripts. Without protection, for instance, a script can alter, replace, or delete standard libraries or functions, or other nasty stuff, so we need to protect against this. Likewise, we have some functions that we don't want all scripters to access such as our global function 'clearloopcount()' which bypasses our infinite loop protection. So we have a security level associated with each global function and each game object attribute and method. CH:say() for instance is security 1, clearloopcount() is security 9. Any given script will run with a specific security level, typically the same security level as is associated with the builder. Any accesses to members above the current script's security setting will result in an script error.
It takes some work to implement all these things, but with Lua you have to the power and flexibility manage the security at different levels, as much as you desire.
But yes, it's correct that it takes some work to expose all your C structures and functions to Lua. For me, the starting point was just to expose what already was exposed to "regular" mob progs, since the goal was to replace them. Since then we just add new interface code as needed.