MOO VR LISPM
I had to delete ‘fantasy’ from the title since it is already real
This is the natural and key progression of my recent articles showing MOO VR driving LISP driving MOO VR. Instead of having esoteric tags visible to the user, there is just a lispm object. A player sends strings to the lispm object. A demon — screwbot — is notified to send the string to the external lisp implementation. The returns and any output are set on the lispm properties.
See the prior articles which have detailed setup details.
This cheatsheet is pretty handy: https://lisdude.com/moo/quick-prog-ref.txt
Screwbot’s moo.el connection
#+BEGIN_EXAMPLE
M-x mud-add-world
PersonalMOO-bot
<ret>
<ret>
localhost
7777
MOO
#+END_EXAMPLEStart local lambdaMOO
#+BEGIN_QUOTE
$ ./MOO-1.8.1/moo db/003.db db/004.db
#+END_QUOTE003.db is my Personal LambdaCore db evolution with screwlisp and screwbot programmer users from the last article.
Starting slime lisp
Emacs lisp:
#+begin_src elisp
(slime)
(setq slime-enable-evaluate-in-emacs t)
(load “~/gits/scroo/scroo.init.el”)
#+end_src
In there:
#+begin_src lisp
(load “~/gits/scroo/scroo.lisp”)
(change-class moo:*player* ‘moo:lisps)
#+end_srcEnabling lisp to drive emacs and changing moo:*player* to be a moo:lisps is how I am having the lisp image be able to autonomously drive the moo.
Log screwbot in
#+BEGIN_EXAMPLE
M-x mud
PersonalMOO-bot
#+END_EXAMPLE
and use my start-mooing:
#+BEGIN_EXAMPLE
M-x start-mooing
#+END_EXAMPLEand connect:
#+BEGIN_EXAMPLE
co screwbot QaVEX
*** Connected ***
The First Room
This is all there is right now.
You see word (un)scrambler here.
You have new mail (1 message). Type ‘help mail’ for info on reading it.
This is your first time connected.
There is new news. Type `news’ to read all news or `news new’ to read just new
news.
>@nn
Message 1 on screwbot (#97):
Date: Sat Oct 17 12:29:29 2026 PDT
From: Wizard (#2)
To: *New-Prog-Log (#29) and screwbot (#97)
Subject: @programmer screwbot (#97)
I just gave screwbot a programmer bit.
- - - - - - - - - - - - -
>
#+END_EXAMPLEinvestigate screwbot:
#+BEGIN_EXAMPLE
>@show me
Object ID: #97
Name: screwbot
Parent: generic programmer (#58)
Location: The First Room (#62)
Owner: screwbot (#97)
Flags: player programmer
<truncated>
#+END_EXAMPLESince I am just going to hardcode screwbot’s object ID in the lispm.
Get screwlisp / screwtape’s stories in your inbox
Join Medium for free to get updates from this writer.
Log screwlisp in
#+BEGIN_EXAMPLE
M-x mud-add-world
PersonalMOO
<ret>
<ret>
localhost
7777
MOO
#+END_EXAMPLEand M-x mud PersonalMOO and connect (oops I got ahead of myself and made/moo-programmed the lispm here too):
#+BEGIN_EXAMPLE
>co screwlisp sybAj
,*** Connected ***
The First Room
This is all there is right now.
You see word (un)scrambler here.
screwbot is here.
Last connected Sat Oct 17 15:55:47 2026 PDT from localhost
There is new news. Type `news' to read all news or `news new' to read just new
news.
>@create $thing named lispm
You now have lispm with object number #100 and parent generic thing (#5).
>drop lispm
You drop lispm.
>@property lispm.standard_output ""
Property added with value "".
>@property lispm.last_input ""
Property added with value "".
>@property lispm.last_error ""
Property added with value "".
>@property lispm.returns {}
Property added with value {}.
>@verb lispm:run this on any
Verb added (1).
>@program lispm:run
Now programming lispm:run(1).
[Type lines of input; `?' for help; end with `.', `@abort' or `@edit'.]
>#97:tell(this.lisp_prefix + "(moo-run \"" + iobjstr + "\")");
>player:tell("The secret alien technology takes your input.");
>.
0 errors.
Verb programmed.
>@prop lispm.lisp_prefix "<lisp> \"AAmIFIHwnD8jU\" "
Property added with value "<lisp> \"AAmIFIHwnD8jU\" ".
>@program lispm:run
Now programming lispm:run(1).
[Type lines of input; `?' for help; end with `.', `@abort' or `@edit'.]
>#97:tell(this.lisp_prefix + "(moo:moo-run \"" + iobjstr + "\")");
>player:tell("The secret alien technology takes your input.");
>.
0 errors.
Verb programmed.
>
#+END_EXAMPLEbetter add moo:moo-run on the lisp-side
#+begin_src lisp
(defmacro moo:moo-run
(iobjstr)
`(let*
((proc "*PersonalMOO-bot*")
(rets)
(out)
(err
(ignore-errors
(setq
out
(with-output-to-string
(*standard-output*)
(setq
rets
(multiple-value-list
(with-input-from-string
(*standard-input* ,iobjstr)
(eval (read))))))))))
(moo:moo
(format
nil
";#100.returns = {~{\"~s\"~^, ~}};"
rets)
proc)
(moo:moo
(format
nil
";#100.standard_output = ~s;"
out)
proc)
(moo:moo
(format
nil
";#100.last_error = ~s;"
err)
proc)
(moo:moo
(format
nil
";#100.location:announce(~s);"
"The lispm's display lights up enticingly.")
proc)))
#+end_srcMake a lispm
Okay, that was a slightly educational experience. It turns out that screwbot needs to own the object to interact with its properties, which are not public so I had the wizard transfer ownership with $wiz_utils:set_owner. But then my player, screwlisp could not simply look at the properties any more so screwbot added the verb lispm:check and lispm:get_returns().
#+BEGIN_EXAMPLE
>run lispm on (values 1 "2")
The secret alien technology takes your
input.
The lispm's display lights up
enticingly.
>check lispm
The returns panel includes:
1
2
>
>;#100:get_returns();
=> {1, 2}
>
#+END_EXAMPLECode for check:
#+BEGIN_EXAMPLE
>@verb lispm:check this none none
Verb added (2).
>@program lispm:check
Now programming lispm:check(2).
[Type lines of input; `?' for help; end with `.', `@abort' or `@edit'.]
>player:tell("The returns panel includes:");
>for s in (this.returns)
> player:tell(s);
>endfor
>.
0 errors.
Verb programmed.
>
#+END_EXAMPLECode for get_returns():
#+BEGIN_EXAMPLE
>@verb lispm:get_returns tnt
Verb added (3).
>@program lispm:get_returns
Now programming lispm:get_returns(3).
[Type lines of input; `?' for help; end with `.', `@abort' or `@edit'.]
>return this.returns;
>.
#+END_EXAMPLEConclusions
While there is certainly lots to do and later redo (something is going wrong with sending strings actually which I am sure is obvious to you now and me later), basically I have a lisp machine in my lambdacore PersonalMOO VR at this point and hence can just write and use pretty arbitrary lisp programs in-MOO.
In particular, I am looking forward to having “Ted Nelson Icon” MOO object classes, i.e. pictures whose pieces are manipulated by gestures, and have these syncronise with the MOO virtuality in both directions.
Talk on the Mastodon thread link I will put in the comments please. Oh, if you are reading this — having Jeff Shrager with Kent on the show on Tuesday-night-in-the-Americas (0UTC “Wednesday”). Please tell as many people as you can, since so far I have missed episodes while overseas.









