My KRF Lisp game frame by frame

Changed-computing-forever is not a category for the lispgamejam rankings! I am looking forward to a solid last place. I deliberately played / read / voted my competition out of the running. But other jammers still want to viscerally experience whatever it was I created. More importantly, I was talking to mdhughes and aral about a hypothetical game where peoples’ Kittens played together online with only occasional participation from their owners. (Er, you visited small-web.org right? Aral /just/ pushed a release). I intend to proximally tangle with that srs-game, but I better fulfill my promise to the dot matrix to do a less mad scientist (lisp lone wolf, surely) version of my game jam simple random walk through dandelions. Instead of a video which you have to pause, I am going to do a screenshot by screenshot every couple of times I just-press-the-<F8>-button in this document. The code comes from my jam submission source, though viz the playing-the-game contribution, with several fixes I discovered where html rendering ate the backslash from #\" and forgotten loadks for example. Also shows how I am using eev eepitch and writing for the kitten.

The jam src is the one-typo-in-the-git-link-corrected https://screwlisp.small-web.org/lispgames/last-five-hours-lispgame/ one.

The first moment

I am in emacs. You will appreciate the glaring whiteness of my not-changed-to-tsdh-dark color theme in these screenshots.
 (eepitch-shell)
cd
git clone https://codeberg.org/tfw/pawn-75.git Qawn-75
mkdir -p ~/leocommunity
cp -r Qawn-75/Pawn-75 ~/leocommunity/Qlant-insect-gamer

I changed the letter P to Q so as to not clash with it-already-being-on-my-boxen. Oops, sorry that repository is a hundred meg. It has a bunch of books on the topic packaged with it.

The only thing I have done is press <F8> on the codes lines. I did slip in a change to my prompt.

At this point, we have a software individual Qlant-insect-gamer. Note that now I am assuming you have the common lisp compiler, gnu clisp (and it /has/ to be gnu clisp) and slime. Actually, sly would probably work, but it is untested.

Starting the lisp software-individual

 (setq inferior-lisp-program "clisp -E ISO-8859-1 -modern")
 (slime)
 (setq eepitch-buffer-name "*slime-repl clisp*")
(require "asdf")
(uiop:chdir "~/leocommunity/Qlant-insect-gamer/demus/Process/main/")
(load #p"../../../remus/Startup/cl/acleo.leos")
(cle)
I scrolled back to the top so you can see slime started in the expected way.

Create Game Knowledgebase

crek game-kb
loadk game-kb
setk game-kb

create types-and-fun entityfile

crefil types-and-fun
loadk types-and-fun

type thingtype entities for plant/insect/tile

I guess this is a really-knowledge-y part, adding these types.

put organism type thingtype
put organism attributes {row col map sensor-range}
addmember (get types-and-fun contents) organism

put plant type thingtype
put plant  attributes {row col map sensor-range}
put plant subsumed-by {organism}
addmember (get types-and-fun contents) plant

put insect type thingtype
put insect attributes {row col map sensor-range}
put insect subsumed-by {organism}
addmember (get types-and-fun contents) insect

put tile type thingtype
put tile attributes {row col contains}
addmember (get types-and-fun contents) tile
writefil types-and-fun
loadk types-and-fun

I snuck in a (get insect subsumed-by) check directly to the repl.

Add an organism

crefil organisms
loadk organisms

put dandelion-01 type plant
put dandelion-01 row 1
put dandelion-01 col 2
put dandelion-01 map test-map
addmember (get organisms contents) dandelion-01
writefil organisms

add test-map

Here, I experimented with common lisp one-liners in my krf.

crefil test-map
loadk test-map

. (defparameter *tiles-in* (loop :for idx :below 25 :for (row col) := (multiple-value-list (truncate idx 5)) :collect (intern (format nil "tile-~d-~d" row col))))
. ;; cle uses readline. Sorry about the one-liners.
. (loop :for tile :in *tiles-in* :do (setf (get tile 'type) 'tile))

. (setf (get 'test-map 'contents) `(seq& ,(append '(test-map) *tiles-in*)))

. (loop :for idx :from 0 :for (row col) := (multiple-value-list (truncate idx 5)) :for tile :in *tiles-in* :do (setf (get tile 'row) row (get tile 'col) col))

writefil test-map

(It was at this moment I was kicked out of the library where I was writing for not moving to sit with the group of people hanging out who looked like me!)

add an explicitly typed live-life action

I guess this is the hard step, because there are three places to look. Since I guess you “get it” about the eev in my src blocks, I show the repl and the before/after of the stub for-me-to-edit in the file.

put living-life type lispdef
addmember (get types-and-fun contents) living-life
writefil types-and-fun

The stub:

And the lisp code

(leodef live-life live-life ()
	(loop :for organism :in (cdadr (get 'organisms 'contents))
	      :do
		 (case (get organism 'type)
		   (plant
		    (let* ((new-name (gensym "dandelion-"))
			   (prev-row (get organism 'row))
			   (prev-col (get organism 'col))
			   (tile (intern
				  (format nil "tile-~d-~d"
					  prev-row
					  prev-col)))
			   (new-row (+ prev-row
				       (1- (random 3))))
			   (new-col (+ prev-col
				       (1- (random 3))))
			   (new-tile
			     (intern
			      (format nil "tile-~d-~d"
				      new-row
				      new-col))))
		      (when (and (get new-tile 'type)
				 (null
				   (get new-tile
					'contains)))
			(setf
			 (get new-tile 'contains)
			 new-name
			 (get new-name 'row) new-row
			 (get new-name 'col) new-col
			 (get new-name 'type) 'plant)
			(nconc
			 (cadr (get 'organisms 'contents))
			 `(,new-name))))))))

inserted:

I guess this is a bit of a pain point. The idea is that different people think different code editors are the best.

render test-map to text

Similarly. Oops, we probably had to loadk types-and-fun in the middle here. Mea culpa. Inserted.

loadk types-and-fun
put render type lispdef
addmember (get types-and-fun contents) render
writefil types-and-fun

Similarly similarly.

(leodef do-render do-render ()
	(loop :for tile :in (cadr (get 'test-map 'contents))
	      :for idx :from 0
	      :for (row col) :=
			     (multiple-value-list
			      (truncate idx 5))
	      :for thing := (get tile 'contains)
	      :when (zerop col) :do
		(terpri)
	      :when thing :do
		(princ "*")
	      :else :do
		(princ #\")
	      :finally (terpri)))

oh, interesting typo! the webified markdown page ate a backslash. Well, fixed here.

loadk types-and-fun
loadk organisms
loadk test-map

I think I missed loadk organisms and loadk test-map in my uploaded source.

running a few steps

live-life
live-life
do-render
. (loop :repeat 2 :do (live-life))
. (do-render)

While it was a frought journey of personal discovery for both of us, I feel we discovered a lot of ground. I am going to adopt this approach for my Kitten playing experience.

Fin. <3