--- layout: ../Site.layout.js --- # Common Lisp Hurkle Interface Manager I got a few from notes from gamedev-of-the-ages [mdhughes](https://mdhughes.tech) about my common lisp class fulfilling Bob Albrecht's Hurkle. So so far I made a common lisp ASDF system, with a package following [my own ASDF introduction](/programming/completely-reasonable-common-lisp-asdf-system-with-eev-demo), with my [common lisp object system class whose methods span Hurkle](../itching-for-hurkles). This article add the McCLIM GUI packages ('actual game') to the aforesaid. ([git link](https://codeberg.org/tfw/hurkle)) As `mdh` says, the interface was basically just a debug interface: ``` CL-USER> (asdf:load-system :hurkle/class) T CL-USER> (use-package :hurkle/class) T CL-USER> (make-instance 'game-grid :rows 6) # CL-USER> (defparameter *g* *) *G* CL-USER> (look-board *g*) 0 ? ? ? ? ? ? ? ? ? ? 1 ? ? ? ? ? ? ? ? ? ? 2 ? ? ? ? ? ? ? ? ? ? 3 ? ? ? ? ? ? ? ? ? ? 4 ? ? ? ? ? ? ? ? ? ? 5 ? ? ? ? ? ? ? ? ? ? + 0 1 2 3 4 5 6 7 8 9 NIL ... CL-USER> (investigate *g* 3 0) 0 ? ? ? ? ? ? ? ? ? ? 1 ? ? ? SE ? ? ? ? ? ? 2 ? ? ? ? ? ? ? ? ? ? 3 E E ? E ? ? E ? ? ? 4 ? ? ? ? ? ? ? ? ? ? 5 ? ? ? ? ? ? ? ? ? ? + 0 1 2 3 4 5 6 7 8 9 NIL CL-USER> (investigate *g* 3 7) 0 ? ? ? ? ? ? ? ? ? ? 1 ? ? ? SE ? ? ? ? ? ? 2 ? ? ? ? ? ? ? ? ? ? 3 E E ? E ? ? E SE ? ? 4 ? ? ? ? ? ? ? ? ? ? 5 ? ? ? ? ? ? ? ? ? ? + 0 1 2 3 4 5 6 7 8 9you ran out of time! NIL ``` Real talk: I got east and west mixed up in my head while playing above. This is the primary difficulty I have experienced Hurkling. The next step today is to declaratively generate a common lisp interface manager GUI using [jackdaniel](https://turtleware.eu)'s [McCLIM](https://codeberg.org/McCLIM/McCLIM/) implementation of the spec. Aside, CLIM is the modern successor to the lisp machine dynamic-windows engineering and experiments. ## Add the package-inferred file=package mixing the hurkle class and CLIM into it ```  (eepitch-sbcl) (with-open-file (*standard-output* #p"~/common-lisp/hurkle/frame.lisp" :direction :output :if-exists :supersede :if-does-not-exist :create) (format t " #| \ (eepitch-sbcl) \ (eepitch-kill) \ (eepitch-sbcl) |# (uiop:define-package :hurkle/frame (:mix :hurkle/class :clim :clim-lisp :cl) (:export #:hurkle-frame #:define-hurkle-frame-command #:display-hurkles)) (in-package :hurkle/frame) ")) ``` # McCommon Lisp Interface Manager Hurkle Frame ``` ;;; #P"~/common-lisp/hurkle/frame.lisp" ; continued (define-application-frame hurkle-frame (game-grid standard-application-frame) () (:pane :application :display-function 'display-hurkles :incremental-redisplay t)) (defmethod display-hurkles ((obj hurkle-frame) pane) (with-slots (grid) obj (formatting-table () (loop :initially (terpri) :with count := 0 :for row :in grid :do (formatting-row () (loop :initially (formatting-cell () (princ count)) (incf count) :for col :in row :do (updating-output (pane) (formatting-cell (pane) (present col))))) :finally (formatting-row () (loop :initially (formatting-cell () (princ ".")) :for x :below (length (car grid)) :do (formatting-cell () (princ x)))))))) ``` Trying it: ``` (asdf:load-system :hurkle/frame) (use-package :hurkle/frame) (find-application-frame 'hurkle-frame) ``` (Before I added numbers:) Looks like we're in business (trivially so). Note I had to add the export `#:grid` to our `:hurkle/class` (pull your git or w/e). ## Hurkle common lisp interface manager commands We add a new package in our game directory for commands because it must happen logically-after we defined `hurkle-frame` so we can use `define-hurkle-frame-command` ``` (with-open-file (*standard-output* #P"~/common-lisp/hurkle/commands.lisp" :direction :output :if-exists :supersede :if-does-not-exist :create) (format t " #| \ (eepitch-sbcl) \ (eepitch-kill) \ (eepitch-sbcl) |# (uiop:define-package :hurkle/commands (:mix :hurkle/frame :hurkle/class :clim :clim-lisp :cl) (:export #:com-investigate)) (in-package :hurkle/commands) ")) ``` and its source: ### Investigate ``` (define-hurkle-frame-command (com-investigate :menu t) () (let ((frame *application-frame*)) (let ((position (accepting-values (t :own-window t) (reverse (list (accept 'integer :prompt "Col=x") (accept 'integer :prompt "Row=y")))))) (apply 'investigate frame (append position '(:stream nil)))))) ``` ### Quick note about those clim forms (besides, the default text entry being too big for my case) - Enter -> (Next form) - alt enter -> Submit form Hmm, maybe try slime or a raw repl rather than `eepitch-sbcl`. Still, # Useage (Observing that I am too tired right now) ```  (eepitch-sbcl) (asdf:load-system :mcclim) (in-package :clim-user) (asdf:load-system :hurkle/commands) (use-package :hurkle/class) (use-package :hurkle/frame) (use-package :hurkle/commands) (find-application-frame 'hurkle-frame) ``` # Conclusion I got kinda morally exhausted during the changes from *frame works* to *rows and columns are numbered* (not because of you/Hurkles, just the weight of the world on my shoulders). Calling it here. I went back and added a `stream` keyword to `hurkle/class.lisp` so that McCLIM doesn't guess I am trying to get it to display this text `investigate` is producing. Further notes, if you please! I think the final installment of this triumverate will be the-frame-as-a-published-game on itch actually, then the `parenscript` `kittenification` will be another thing. I dunno, what do you think? The McCLIM is a straightforward and orthogonal extension to the CLOS class, right? # Fin. See you in [the Mastodon thread](https://gamerplus.org/@screwlisp/114611664134145784). No pressure but I already [told Sacha of emacsconf that we will unleash emacs smallweb kittens](https://gamerplus.org/@screwlisp/114606155202539991). I am actively trying to help share lisp knowledge and useage! Please share this in any and every manner that occurs to you, and prod me to provide improvements at your leisure.