[ab] How to Implement an In-Game REPL

Elliott Slaughter elliottslaughter at gmail.com
Mon Dec 31 19:11:50 CST 2007


I am trying to implement a REPL in my game, the idea being that when
the user presses a certain key, the game pauses and lets them enter
commands into the command line. I wrote a quick hack which gets the
job half-done, but which has the serious disadvantage of not being
able to leave the loop:

(defvar *prompt* "> ")

; in main function...
(sdl:with-events ()
  (:quit-event () t)
  (:key-down-event (:key key)
    (when
      (sdl:key= key :sdl-key-backquote)
        (loop
	  (fresh-line)
	  (princ *prompt*)
	  (prin1 (eval (read))))))
  (:idle ()
    ; more code...
    ))

The problem with this code is that it evaluates the entered form in
the null lexical environment, so you can't access local variables from
the REPL, and you also can't return from the REPL to resume the game
(if you enter (return) into the above loop, it errors saying there is
no surrounding block named nil). The lack of access to local variables
is inconvenient, but probably a good thing the long run. But I am
having difficulty thinking of ways to allow you to return from the
loop without adding an explicit exit condition (i.e. a form that
evaluates false terminates the loop) or hard coding listeners for
return forms (i.e. if the user enters "(return)" then exit the loop
instead of evaluating the form).

Any advice on how to solve this problem, or about implementing REPLs
in general would be appreciated.

Thanks, and have a happy new year!

-- 
Elliott Slaughter

"Any road followed precisely to its end leads precisely nowhere." -
Frank Herbert


More information about the application-builder mailing list