screwlisp proposes kittens

ANSI CL McCLIM Lisp Game Jam: The other threeish checkmarks involving pictures and doorways between maps using my own NicCLIM

;; Assign img-symbol to symbol's `:bitmap`
# «.🎭»	(to "🎭")
;; take peek at a map
# «.†»	(to "†")
;; Make a door (to somewhere else)
# «.🚪»  (to "🚪")

Last time, we made several symbolic map files being

and the jam checklist I made of

  1. Make a map, as above ✓
  2. Fill in subrectangles of a map with another map ✓
  3. Pop up some pictures and dialog using CLIM’s accepting-values
  4. Use a door in the map to enter another map

so let us continue and take out the last three points which turn out to be closely related. I have the general plan that the game controls will just be :up :down :left :right and maybe (:control :up) and (:control :down) since we are actually in hextille and need six directions.

My simple idea is when we walk over a lambda expression, we automatically funcall it to insert host lisp into our game. Then, the lambda symbol can be given a graphic like other symbols, which we will see in a moment. This game’s art is being graciously provided to the world by https://analognowhere.com .

Same Setup As Usual

• (setq inferior-lisp-program "ecl")
• (setq eepitch-buffer-name "*slime-repl ECL*")
• (slime)
(ql:Quickload :McCLIM)
(compile-file "~/Downloads/nicclim.lisp" :load t)
(in-package :nic)
(string '~/game)
(ensure-directories-exist *)
(uiop:chdir (string '~/game/))
(uiop:chdir (string '~/game/)) ;; Twice, for some reason.

Setting my NicCLIM :bitmap properties for solid, rock, tree, grass, and lambda (!)

Admittedly, maybe not the world’s greatest tribute to #unix_surrealism but I painstakingly cut these from fragments of lo0, canyon and a few others. https://analognowhere.com/_/archive/

Thinking about it, I should do the opposite of what I just did. Instead of saying by god I am going to find something that fits the word SOLID and cut it out, I should have just browsed Analog Nowhere and opportunistically grabbed and accurately named the copious fragments that present themselves.

Setting ROCK’s :bitmap property to IMGS/ROCK.PNG and so forth

This can be done inside of NicCLIM,but we might as well do it our developed lisp repl style.

«🎭» (to “.🎭”)

;; symbol like ROCK
;; image symbol like IMGS/ROCK.PNG
(setf (get ** :bitmap) *)

Whence.

So this looks a little repetitive but it is also kind of declarative looking I think. Remembering that we are just discovering-what-whatever-we-do-turns-out-to-be-like here. I like to imagine someone is following along and making a vastly superior game (not that one could improve on #unix_surrealism surrealistically).

'SOLID
'IMGS/SOLID.PNG
;; (to "🎭")

'ROCK
'IMGS/ROCK.PNG
#.+++

'TREE
'IMGS/TREE.PNG
#.+++

'GRASS
'IMGS/GRASS.PNG
#.+++

'LAMBDA
'IMGS/LAMBDA.PNG
#.+++

Oh, interesting. What I found was that it was okay to retrieve (to "🎭") once, but then it was basically a hassle (what do I do, insert a bookmark in my environment?). However lisp has a dispatch macro, #. which means read-time evaluation of. And +++ means what I sent you, three non-error times ago. So #.+++ in the lisp repl sends the read-time evaluation of +++, the thing I sent three times ago i.e. do it again. It only works because 🎭 was just one expression.

What does the NicCLIM map look like now (pictures?)

Er, reproducing our peek from before. (I need a clear realization of ~ #INCLUDE)

«†» (to “.†”)

(enclose-map *)

and so

What the Mountain-cave GUI view is now

'mountain-cave.map
;; (to "†")

Interesting. We can see that for symbols in the top level of a cell with a :bitmap property, images are rendered on top of each other with left-most being further back. When the value of the cell is retrieved, it is the symbols themselves that are retrieved as normal so our composite pictures can be understood as programs (as will be the case in lambdas).

So solid is that deformed blue-purple sigil, and rock is the brown rock sticking out of the ground. solid I intended to mean -and-is-unpassable. Admittedly, it looks pretty silly. On the other hand CAVERN did not get a :bitmap png yet, so there is the ROCK picture with the word CAVERN printed in black atop it.

I guess my tiles should be maybe 2-3 times bigger, and I should turn off the rectangular cell borders in release. Still, it works (as such). I just picked to try making 32x32 images arbitrarily. It turned out to be too small and look kind of silly in my first try.

This seems to be working so let us move on to hacking useage of host lisp lambdas into the game.

Lambda the ultimate

I guess doors equate to map changes. So I will change one cell to, oh we better add a footnote as DM tells me to call them

«🚪» (to “.🚪”)

`(lambda
     (&rest r)
   (execute-frame-command
    *application-frame*
    '(com-change-map ,*)))

Now, I want the lambda expression in the map, not some compiled / interpreted thing.

A door to grass-clearing.map

'grass-clearing.map
;; (to "🚪")

yields

(LAMBDA (&REST R)
  (EXECUTE-FRAME-COMMAND
   *APPLICATION-FRAME*
   '(COM-CHANGE-MAP GRASS-CLEARING.MAP)))

Let us just lisp-side manually send some commands to the last frame we were popping up with enclose-map, which is stored in *nic* for moments like this.

(execute-frame-command
 *nic*
 `(com-set-cur1 ,*))
(execute-frame-command
 *nic*
 `(com-cur1-rotatef))

Sorry for hitting you with the dark magic. This is simply the explicit way of manipulating a frame from the repl rather than inside its own user interface.

I guess this does look like dark magic (I (non-)secretly did it interactively). I see the cursor cons ends up smashed somewhere weird o_o.

Worked though. So we can make and use doors, though they could be prettier, and it needs to be less verbose and not leave the cursor on a funny cons.

Conclusions

…Escaping from that quickly.

While lambda clearly worked as intended, using it for execute-frame-command forms ended up being cumbersome. So as well as lambda, I guess I will expose NicCLIM’s existing com-execute-list for lists of NicCLIM macro commands suitable for purposes like doors to other maps. I guess I will fold this into my in-game-arrowkey-movement for the jam though.

Ideally at some point soon in the jam future programming of the game is going to be a set of knowledgebased specific activities inside the game as such as we have made it.

How to jump back when using eev-mode anchors is a bit of a question. But people with different environments seem to have to answer it differently. Drop a cursor position bookmark in emacs? (vi/vim?).

I am fairly happy with actively using the lisp repl special variables and macro characters like #.+++ since it is very explicit (implicit?) what is being done in the context of eepitching-lines-to-the-repl.

Current state of the checklist:

  1. Make a map, as above ✓
  2. Fill in subrectangles of a map with another map ✓
  3. Pop up some pictures and dialog using CLIM’s accepting-values
  4. Use a door in the map to enter another map ✓

so we just have to introduce CLIM’s own-frame accepting-values, according to this list anyway.

I feel like we got a shade hard to follow this article, but jamming new ground is inevitably going to be at least a little difficult.

Fin.

See you on the Mastodon thread as always!

If you were interested, please consider either sharing your opinions, or boosting the toot / sharing it in your own medium to fish up others’ opinions.

screwlisp proposes kittens