[plt-scheme] How to use Eval for a MUD
Jay McCarthy wrote:
> Sounds like a cool project. I've always wanted to make an awesome MUD
> engine with Scheme.
Heh well... mostly doing it for a friend, but I agree it'd really be
nice to have something reliable out there that wasn't written from a
hacked 10 year old C core someone scribbled out one night in their
basement. I enjoy this sort of stuff, and devoting a few minutes to it
every so often is nice.
I could put the code I have so far up on git or something. It actually
functions, to a degree, but I haven't added in my little natural
language parser, and the only "namespace" it keeps track of is the
global one of built-in commands, and the identifiers that the user just
happens to (define ...) in their specific sandbox session.
Would definitely like to make it so "say hi" works. ._.
> it might be
> simpler to manage the namespace creation in a functional way...
> creating it fresh everytime the user changes context.
> Another simple
> idea to do is have a stack of namespaces (global -> user -> area ->
> room -> "mode" [fighting, shop, etc]) that are extracted from the
> environment objects as the user inputs other commands.
> Then when you
> want to use 'eval' you first eval in the tightest namespace, falling
> back if the compilation fails, etc.
Or perhaps a combination of both ways, in that there's a stack of
namespaces, but I combine them somehow into one big namespace for each
user. That lends the question of which names need to be defined though.
I think it might be possible to analyze user-generated code to determine
what identifiers they need to be defined, and build a namespace only
from those. If someone makes a program that says (tell me "Hi there")
then I don't want to evaluate the properties for "tell", "look", "eat",
"frobnicate", "sell", "post", "beaver", and "attack" every time I run
that program. So one important thing is being able to figure out what
lack of identifiers will cause a failure, and include a list of those
with each program, like (((tell me) . (tell me "Hi there")) ((tell me
location) . (tell (location me) "Hi guys!")))
Maybe that's something eval would have to do... so if you said (eval
'(tell (eval 'me) "Recursion is rad.")) the outer eval instead of
raising an exception for unknown identifiers would look them up from the
namespace stack, and then query the database evaluating and adding the
identifiers to a namespace. (tell eval) would be the result, and the
second evaluator would do the same thing, querying various locations to
find out what identifier 'me is.
I wouldn't mind having a huge blob of identifiers for each namespace,
it's just the notion of repeatedly loading certain properties from disk,
which contain procedures that themselves need to be evaluated, that
would slow me down. Could possibly store compiled versions of the
procedures on disk, but it's still something I'd only want to evaluate
when necessary.