--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/assets/help.txt Tue Apr 20 18:01:32 2021 -0400
@@ -0,0 +1,2 @@
+[esc] Pause (with options to resume/quit)
+[tab] Switch between panels.
--- a/assets/journal.txt Tue Apr 20 15:13:04 2021 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-September 22, 1987
-Finally got access to a computer terminal.
-
-Cosmic Hyperspace Interferometer R Operations Network
--- a/assets/splash.txt Tue Apr 20 15:13:04 2021 -0400
+++ b/assets/splash.txt Tue Apr 20 18:01:32 2021 -0400
@@ -1,5 +1,11 @@
-TODO: title
+███╗ ███╗██╗ ██╗ ██████╗███████╗██╗ ██╗██╗ ██╗███╗ ███╗
+████╗ ████║╚██╗ ██╔╝██╔════╝██╔════╝██║ ██║██║ ██║████╗ ████║
+██╔████╔██║ ╚████╔╝ ██║ █████╗ ██║ ██║██║ ██║██╔████╔██║
+██║╚██╔╝██║ ╚██╔╝ ██║ ██╔══╝ ██║ ██║██║ ██║██║╚██╔╝██║
+██║ ╚═╝ ██║ ██║ ╚██████╗███████╗███████╗██║╚██████╔╝██║ ╚═╝ ██║
+╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝
by Steve Losh
for the Lisp Game Jam, Spring 2021
-Press any key to start.
+ Press ? at any time for help.
+ Press space to start.
--- a/dark.asd Tue Apr 20 15:13:04 2021 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-(asdf:defsystem :dark
- :name "dark"
- :description "Lisp Game Jam, Spring 2021"
-
- :author "Steve Losh <steve@stevelosh.com>"
-
- :license "MIT/X11"
- :version "0.0.1"
-
- :depends-on (#+sbcl #:sb-sprof
- :alexandria
- :boots
- :cl-pcg
- :iterate
- :local-time
- :losh)
-
- :serial t
- :components
- ((:module "src" :serial t
- :components ((:file "package")
- (:file "main")))))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mycelium.asd Tue Apr 20 18:01:32 2021 -0400
@@ -0,0 +1,24 @@
+(asdf:defsystem :mycelium
+ :name "mycelium"
+ :description "Lisp Game Jam, Spring 2021"
+
+ :author "Steve Losh <steve@stevelosh.com>"
+
+ :license "MIT/X11"
+ :version "0.0.1"
+
+ :depends-on (#+sbcl #:sb-sprof
+ :alexandria
+ :boots
+ :str
+ :chancery
+ :cl-pcg
+ :iterate
+ :local-time
+ :losh)
+
+ :serial t
+ :components
+ ((:module "src" :serial t
+ :components ((:file "package")
+ (:file "main")))))
--- a/scratch.lisp Tue Apr 20 15:13:04 2021 -0400
+++ b/scratch.lisp Tue Apr 20 18:01:32 2021 -0400
@@ -1,4 +1,4 @@
-(in-package :dark)
+(in-package :mycelium)
(ql:quickload :bordeaux-threads)
@@ -12,18 +12,29 @@
(boots%::print-attr
(boots:attr :fg (boots:rgb 1 2 3)))
-
-
-
-
-
-
+(defun key-name (key)
+ (case key
+ (#\tab "tab")
+ (t (string key))))
-abc
-len = 3
-wid = 10
-10 - 3 = 7
+(defun select-box (heading options)
+ (with-chiron-layer
+ (boots:stack (:margin t :width 20 :height (+ (length options) 2) :border t
+ :fill-char #\space :fill-attr +default+)
+ (boots:canvas (:fill-char #\space :fill-attr +default+ :height 1 :border-bottom t) (pad)
+ (boots:draw pad
+ (truncate (- (boots:width pad) (length heading)) 2)
+ 0 heading +default+))
+ (boots:canvas (:fill-char #\space :fill-attr +default+) (pad)
+ (iterate (for y :from 0)
+ (for (key description result) :in options)
+ (boots:draw pad 0 y (format nil "[~A] ~A" (key-name key)
+ description) +default+))))
+ (third (iterate
+ (boots:redraw)
+ (for (values e m) = (boots:read-event))
+ (unless (handle-global-event e m)
+ (thereis (find-if (lambda (option)
+ (boots:event= option e m))
+ options :key #'first)))))))
-0123456789
-
-
--- a/scripts/build.sh Tue Apr 20 15:13:04 2021 -0400
+++ b/scripts/build.sh Tue Apr 20 18:01:32 2021 -0400
@@ -4,7 +4,7 @@
ban Building
/usr/local/bin/sbcl \
- --eval '(ql:quickload :dark)' \
- --eval '(dark:build)' \
+ --eval '(ql:quickload :mycelium)' \
+ --eval '(mycelium:build)' \
--disable-debugger --noinform
--- a/scripts/deploy.sh Tue Apr 20 15:13:04 2021 -0400
+++ b/scripts/deploy.sh Tue Apr 20 18:01:32 2021 -0400
@@ -5,4 +5,4 @@
./scripts/build.sh
ban Deploying
-time rsync -avz build/dark jam:/opt/dark/dark
+time rsync -avz build/mycelium jam:/opt/mycelium/mycelium
--- a/src/main.lisp Tue Apr 20 15:13:04 2021 -0400
+++ b/src/main.lisp Tue Apr 20 18:01:32 2021 -0400
@@ -1,43 +1,51 @@
-(in-package :dark)
+(in-package :mycelium)
-;;;; Global -------------------------------------------------------------------
+;;;; Constants ----------------------------------------------------------------
(defconstant +black+ (boots:rgb 0 0 0))
(defconstant +white+ (boots:rgb 255 255 255))
-(defconstant +amber+ (boots:rgb #xFB #x7D #x01))
-(defconstant +default+ (boots:attr :fg +amber+ :bg +black+))
-(defconstant +reverse+ (boots:attr :fg +black+ :bg +amber+))
-(defconstant +ooc+ (boots:attr :fg +white+ :bg +black+))
+(defconstant +dark-purple+ (boots:rgb #x52 #x2F #x70))
+(defconstant +default+ (boots:attr :fg +white+ :bg +black+))
+(defconstant +bold+ (boots:attr :fg +white+ :bg +black+ :bold t))
+(defconstant +reverse+ (boots:attr :fg +black+ :bg +white+))
+(defconstant +selected+ (boots:attr :fg +white+ :bg +dark-purple+ :bold t))
+
+
+;;;; State --------------------------------------------------------------------
(defvar *event* nil)
(defvar *mods* nil)
+(defvar *seed* nil)
+(defvar *debug* (make-ring-buffer))
+(defvar *pcg* (pcg:make-pcg))
+(defvar *elapsed* nil)
+(defvar *panels* nil)
+(defvar *unlocked* nil)
+(defvar *messages* (make-ring-buffer :size 16))
+(defvar *calories* 0.0)
-(defvar *countdown* nil)
-(defvar *seed* nil)
-
+;;;; Config -------------------------------------------------------------------
+(defparameter *forage-chance* 0.1)
+(defparameter *calories-per-second* 1.0)
;;;; Assets -------------------------------------------------------------------
-(defparameter *asset/splash* (alexandria:read-file-into-string "assets/splash.txt"))
-(defparameter *asset/journal* (alexandria:read-file-into-string "assets/journal.txt"))
+(defun load-asset (path)
+ (_ path
+ alexandria:read-file-into-string
+ (string-right-trim '(#\newline) _)
+ str:lines))
+
+(defparameter *asset/splash* (load-asset "assets/splash.txt"))
+(defparameter *asset/help* (load-asset "assets/help.txt"))
;;;; Utils --------------------------------------------------------------------
-(defparameter *pcg* (pcg:make-pcg))
-
(defun random (bound &optional max inclusive?)
(pcg:pcg-random *pcg* bound max inclusive?))
-(defun press-any-key ()
- (boots:read-event)
+(defun press-key (event)
+ (loop :until (multiple-value-call #'boots:event= event (boots:read-event)))
(values))
-(defmacro with-in-game-colors (&body body)
- `(let ((boots:*border-attr* +default+))
- ,@body))
-
-(defmacro with-ooc-colors (&body body)
- `(let ((boots:*border-attr* +ooc+))
- ,@body))
-
(defmacro with-ui (ui &body body)
(alexandria:with-gensyms (prev)
`(let ((,prev (boots:root boots:*screen*)))
@@ -56,13 +64,18 @@
(boots:event-case (values event mods)
(#(:ctrl #\q) (throw 'quit nil))
(#\esc (pause) t)
+ (#\? (help) t)
(t nil)))
(defun draw-right (pad x y string attr)
(boots:draw pad (1+ (- x (length string))) y string attr))
-
-(defvar *debug* (make-ring-buffer))
+(defun draw-center (pad y string attr &aux
+ (s (string string))
+ (w (boots:width pad))
+ (l (length s)))
+ (boots:draw pad (if (<= w l) 0 (truncate (- w l) 2))
+ y s attr))
(defun dbg (&optional string &rest args)
(if string
@@ -71,154 +84,341 @@
(write-line s)))
(values))
+(defun unlock (&rest keys)
+ (apply #'hset-insert! *unlocked* keys))
+(defun unlockedp (key)
+ (hset-contains-p *unlocked* key))
+
+(defun msg (string &rest args)
+ (rb-push *messages* (apply #'format nil string args)))
+
+
+;;;; Items --------------------------------------------------------------------
+;;; These classes don't represent individual items, but rather the whole
+;;; set/count/pile of a particular type of item.
+
+(defclass* item ()
+ (section
+ key
+ description
+ (owned :initform 0)))
+
+(defclass* mushroom (item)
+ ((section :initform 'mushrooms)
+ (calories :initform 100)))
+
+(defclass* tool (item)
+ ((section :initform 'tools)))
+
+(defmethod print-object ((o item) s)
+ (print-unreadable-object (o s :type t)
+ (format s "~A" (key o))))
+
+(defun make-items (class data)
+ (iterate
+ (for (key description . initargs) :in data)
+ (collect (apply #'make-instance class :key key :description description initargs))))
+
+(defun make-tools ()
+ (make-items 'tool '((trowel "Small trowel" :owned 1)
+ (bucket "Sturdy bucket" :owned 1))))
+
+(defun make-mushrooms ()
+ (make-items 'mushroom
+ '((chantrelle "Chantrelle mushroom" :calories 60)
+ (matsutake "Matsutake mushroom" :calories 200))))
+
+
+;;;; Inventory ----------------------------------------------------------------
+(defvar *inventory* nil)
+(defvar *inventory-index* nil)
+
+(defparameter *sections* '(tools mushrooms))
+
+(defun inv-ref (section key)
+ ;; should have been a setf expander but time is short
+ (gethash key (gethash section *inventory*)))
+
+(defun inv-inc (o &optional key)
+ (if (null key)
+ (incf (owned (gethash (key o) (gethash (section o) *inventory*))) 1)
+ (incf (owned (gethash key (gethash o *inventory*))) 1)))
+
+(defun inv-dec (o &optional key)
+ (if (null key)
+ (decf (owned (gethash (key o) (gethash (section o) *inventory*))) 1)
+ (decf (owned (gethash key (gethash o *inventory*))) 1)))
+
+(defun inv-insert (&rest items)
+ (dolist (item items)
+ (setf (gethash (key item) (gethash (section item) *inventory*))
+ item)))
+
+(defun inv-section-items (section &key only-owned)
+ (iterate (for (nil item) :in-hashtable (gethash section *inventory*))
+ (when (or (not only-owned) (plusp (owned item)))
+ (collect item))))
+
+
+(defun init/inventory ()
+ (setf *inventory* (make-hash-table))
+ (dolist (s *sections*)
+ (setf (gethash s *inventory*) (make-hash-table)))
+ (apply #'inv-insert (make-mushrooms))
+ (apply #'inv-insert (make-tools))
+ (setf *inventory-index*
+ (iterate (for s :in *sections*)
+ (for keys = (sort (alexandria:hash-table-keys (gethash s *inventory*)) #'string<))
+ (collect (list s keys)))))
+
+
+;;;; Hunger -------------------------------------------------------------------
+(defun eat (mushroom)
+ (incf *calories* (calories mushroom))
+ (inv-dec mushroom))
+
+(defun attempt-to-eat ()
+ (let ((options (inv-section-items 'mushrooms :only-owned t)))
+ (if (null options)
+ nil
+ (progn (msg "You feel hungry. You eat a mushroom.")
+ (eat (random-elt options #'random))))))
+
+(defun tick/hunger (delta)
+ (let ((consumed (* delta *calories-per-second*)))
+ (setf *calories* (max 0.0 (- *calories* consumed)))
+ (when (zerop *calories*)
+ (attempt-to-eat))))
;;;; Splash -------------------------------------------------------------------
-(defun draw/splash (pad)
- (boots:draw pad 0 0 *asset/splash*))
+(defparameter *ui/splash/bg*
+ (boots:make-canvas :draw 'draw/splash/bg))
+
+(defparameter *ui/splash/card*
+ (boots:make-canvas :width (reduce #'max *asset/splash* :key #'length)
+ :height (length *asset/splash*)
+ :border t :margin t
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/splash/card))
+
+(defparameter *ui/splash*
+ (boots:pile ()
+ *ui/splash/card*
+ *ui/splash/bg*))
+
+(defun draw/splash/card (pad)
+ (iterate
+ (for y :from 0)
+ (for line :in *asset/splash*)
+ (boots:draw pad 0 y line +default+)))
+
+(defun draw/splash/bg (pad)
+ (dotimes (x (boots:width pad))
+ (dotimes (y (boots:height pad))
+ (boots:draw pad x y
+ (losh:random-elt "\\/_-,.`" #'random)
+ (boots:attr :fg +dark-purple+)))))
(defun splash ()
(with-ooc-colors
- (with-ui (boots:make-canvas :width 50 :height 10 :border t :margin t
- :fill-char #\space
- :fill-attr +default+
- :draw #'draw/splash)
+ (with-ui *ui/splash*
(boots:redraw)
- (press-any-key)))
- (chiron))
+ (press-key #\space)))
+ (game))
-;;;; Journal ------------------------------------------------------------------
-(defun draw/journal (pad)
- (boots:draw pad 0 0 *asset/journal* +default+))
-
+;;;; Panels -------------------------------------------------------------------
+(defclass* panel ()
+ ((draw-function)
+ (selected)
+ (key)
+ (ui)))
-;;;; Email --------------------------------------------------------------------
-(defun draw/email (pad)
- (boots:draw pad 0 0 "this is ur email" +default+))
-
+(defgeneric panel-name (panel))
-;;;; Chiron -------------------------------------------------------------------
-(defun human-countdown ()
- (nest
- (multiple-value-bind (remaining) (truncate *countdown* internal-time-units-per-second))
- (multiple-value-bind (days remaining) (truncate remaining (* 60 60 24)))
- (multiple-value-bind (hours remaining) (truncate remaining (* 60 60)))
- (multiple-value-bind (mins remaining) (truncate remaining 60))
- (multiple-value-bind (secs) (truncate remaining))
- (format nil "~Dd ~2,'0Dh ~2,'0Dm ~2,'0Ds" days hours mins secs)))
+;;;; Forest -------------------------------------------------------------------
+(defparameter *ui/forest/forage*
+ (boots:make-canvas :height 1 :margin-bottom 1 :draw 'draw/forest/forage))
-(defun draw/chiron/top-bar (pad)
- (boots:draw pad 0 0 "CHIRON" (boots:attr :fg +black+ :bg +amber+ :bold t))
- (let ((closing (format nil "Window closes in: ~A" (human-countdown))))
- (boots:draw pad (- (boots:width pad) (length closing)) 0
- closing +reverse+)))
-
-(defun draw/chiron/bottom-bar (pad)
- (boots:draw pad 0 0 "user: elf@chiron" +reverse+)
- (draw-right pad (1- (boots:width pad)) 0
- (format nil "(SEED ~X)" *seed*) +reverse+))
+(defparameter *ui/forest*
+ (boots:shelf (:fill-char #\space :fill-attr +default+)
+ *ui/forest/forage*))
-(defparameter *chiron/top-bar*
- (boots:make-canvas :height 1 :margin-bottom 1
- :fill-char #\space
- :fill-attr +reverse+ :draw #'draw/chiron/top-bar))
+(defclass* forest (panel)
+ ((ui :initform *ui/forest*)
+ (key :initform 'forest)))
+
+(defmethod panel-name ((p forest))
+ "Forest")
+
+(defun draw/forest/forage (pad)
+ (when (unlockedp 'forage)
+ (boots:draw pad 0 0 "[Forage for mushrooms]" +default+)))
-(defparameter *chiron/bottom-bar*
- (boots:make-canvas :height 1 :margin-top 1
- :fill-char #\space
- :fill-attr +reverse+ :draw #'draw/chiron/bottom-bar))
+(chancery:define-rule (random-forage :distribution :weighted)
+ (1 'chantrelle)
+ (1 'matsutake))
+
+
+(defun press/forage ()
+ (if (randomp *forage-chance*)
+ (progn (msg "You found a mushroom.")
+ (inv-inc 'mushrooms (random-forage)))
+ (msg "You don't find anything.")))
-(defparameter *chiron/journal* (boots:make-canvas :draw #'draw/journal))
-(defparameter *chiron/email* (boots:make-canvas :draw #'draw/email))
+;;;; Game ---------------------------------------------------------------------
+(defparameter *ui/game/top-bar*
+ (boots:shelf (:fill-char #\space :fill-attr +default+ :height 1 :border-bottom t)
+ (boots:make-canvas :fill-char #\space :fill-attr +default+
+ :draw 'draw/game/top-bar/panels
+ :margin-right t)
+ (boots:make-canvas :width 10
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/game/top-bar/time)))
-(defparameter *chiron* (boots:pile ()))
+(defparameter *ui/game/messages*
+ (boots:make-canvas :height 8 :border-top t
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/game/messages))
+
+(defparameter *ui/game/inventory*
+ (boots:make-canvas :width 35 :border-left t
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/game/inventory))
-(defmacro with-chiron-layer (widget &body body)
- `(progn
- (push ,widget (boots:children *chiron*))
- (unwind-protect (progn ,@body)
- (pop (boots:children *chiron*)))))
+(defparameter *ui/game/panel*
+ (boots:pile ()
+ (boots:make-canvas :fill-char #\? :fill-attr +default+)))
-(defun key-name (key)
- (case key
- (#\tab "tab")
- (t (string key))))
+(defparameter *ui/game*
+ (boots:pile (:fill-char #\space :fill-attr +default+)
+ (boots:stack ()
+ *ui/game/top-bar*
+ (boots:shelf ()
+ *ui/game/panel*
+ *ui/game/inventory*)
+ *ui/game/messages*)))
+
+
+(defun draw/game/top-bar/panels (pad)
+ (boots:draw pad 0 0
+ (iterate (for panel :in-vector *panels*)
+ (collect (if (selected panel) +selected+ +reverse+))
+ (collect (panel-name panel)))))
+
+(defun draw/game/top-bar/time (pad)
+ (draw-right pad (1- (boots:width pad)) 0
+ (format nil "~Ds" (truncate *elapsed* internal-time-units-per-second))
+ +default+))
-(defun select-box (heading options)
- (with-chiron-layer
- (boots:stack (:margin t :width 20 :height (+ (length options) 2) :border t
- :fill-char #\space :fill-attr +default+)
- (boots:canvas (:fill-char #\space :fill-attr +default+ :height 1 :border-bottom t) (pad)
- (boots:draw pad
- (truncate (- (boots:width pad) (length heading)) 2)
- 0 heading +default+))
- (boots:canvas (:fill-char #\space :fill-attr +default+) (pad)
- (iterate (for y :from 0)
- (for (key description result) :in options)
- (boots:draw pad 0 y (format nil "[~A] ~A" (key-name key)
- description) +default+))))
- (third (iterate
- (boots:redraw)
- (for (values e m) = (boots:read-event))
- (unless (handle-global-event e m)
- (thereis (find-if (lambda (option)
- (boots:event= option e m))
- options :key #'first)))))))
+(defun draw/game/messages (pad)
+ ;; todo make reverse iteration stuff for ring buffers
+ (iterate (for i :from -1 :downto (- (rb-count *messages*)))
+ (for y :from 0)
+ (boots:draw pad 0 y (rb-ref *messages* i) +default+)))
-(defun select ()
- (select-box "SELECT"
- '((#\m "Mail" :mail)
- (#\j "Journal" :journal)
- (#\q "Log Out" :quit)
- (#\tab "Nevermind" :nevermind))))
+(defun draw/game/inventory (pad)
+ (draw-center pad 0 "INVENTORY" +bold+)
+ (iterate
+ (with y = 2)
+ (with h = (boots:height pad))
+ (while (< y h))
+ (for sy = y)
+ (for (section keys) :in *inventory-index*)
+ (iterate (for key :in keys)
+ (for item = (inv-ref section key))
+ (when (plusp (owned item))
+ (incf y)
+ (boots:draw pad 0 y (format nil "~6D ~A"
+ (owned item)
+ (description item))
+ +default+)))
+ (unless (= sy y)
+ ;; only draw section header if we drew anything else
+ (boots:draw pad 0 sy (symbol-name section) +default+)
+ (incf y 2))))
+
-(defun chiron ()
- (with-ui *chiron*
- (with-chiron-layer (boots:stack (:fill-char #\space :fill-attr +default+)
- *chiron/top-bar*
- *chiron/journal*
- *chiron/bottom-bar*)
- (iterate
- (timing real-time :per-iteration-into delta)
- (decf *countdown* delta)
- (boots:redraw)
- (event-case (boots:read-event-no-hang)
- (#\tab (dbg "~S" (select)))
- (t nil))))))
+(defmacro with-layer (ui &body body)
+ `(progn (push ,ui (boots:children *ui/game*))
+ (unwind-protect (progn ,@body)
+ (pop (boots:children *ui/game*)))))
+
+(defun tick (delta)
+ (tick/hunger delta))
+
+(defun game ()
+ (with-ui *ui/game*
+ (iterate
+ (timing real-time :per-iteration-into delta)
+ (incf *elapsed* delta)
+ (tick (/ (float delta 1.0d0) internal-time-units-per-second))
+ (setf (first (boots:children *ui/game/panel*))
+ (ui (find-if #'selected *panels*)))
+ (boots:redraw)
+ (event-case (boots:read-event-no-hang)
+ (nil (boots:wait 1/30))
+ (#\newline (press/forage))
+ (#\tab (msg "TODO"))
+ (t nil)))))
;;;; Pause --------------------------------------------------------------------
+(defparameter *ui/pause*
+ (boots:make-canvas :width 30 :height 4 :border t :margin t
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/pause))
+
(defun draw/pause (pad)
(boots:draw pad 0 0 "Paused" +ooc+)
(boots:draw pad 0 2 "[R]esume" +ooc+)
(boots:draw pad 0 3 "[Q]uit Game" +ooc+))
(defun pause ()
- (with-ooc-colors
- (with-ui (boots:make-canvas :width 30 :height 10 :border t :margin t
- :fill-char #\space
- :fill-attr +ooc+
- :draw #'draw/pause)
- (loop (boots:redraw)
- (multiple-value-bind (e m) (boots:read-event)
- (boots:event-case (values e m)
- ((#\r #\esc) (return-from pause))
- (#\q (throw 'quit nil))
- (t (setf *event* e *mods* m))))))))
+ (with-ui *ui/pause*
+ (loop (boots:redraw)
+ (multiple-value-bind (e m) (boots:read-event)
+ (boots:event-case (values e m)
+ ((#\r #\esc) (return-from pause))
+ (#\q (throw 'quit nil))
+ (t (setf *event* e *mods* m)))))))
+
+
+;;;; Help --------------------------------------------------------------------
+(defparameter *ui/help*
+ (boots:make-canvas :width 50 :height (+ 3 (length *asset/help*))
+ :border t :margin t
+ :fill-char #\space :fill-attr +default+
+ :draw 'draw/help))
+
+(defun draw/help (pad)
+ (boots:draw pad 0 0 "HELP" +default+)
+ (iterate (for y :from 2)
+ (for line :in *asset/help*)
+ (boots:draw pad 0 y line +default+)))
+
+(defun help ()
+ (with-ui *ui/help*
+ (boots:redraw)
+ (press-key t)))
;;;; Main ---------------------------------------------------------------------
(defun init ()
(rb-clear *debug*)
+ (rb-clear *messages*)
+ (init/inventory)
(setf *seed* (cl:random (expt 2 60) (cl:make-random-state))
*pcg* (pcg:make-pcg :seed *seed*)
- *countdown* (* internal-time-units-per-second
- (+ (* 60 60 24 15)
- (random 0 (* 60 60 4))))))
+ *elapsed* 0
+ *calories* (* 1.0 10)
+ *panels* (vector (make-instance 'forest :selected t))
+ *unlocked* (make-hash-set :initial-contents '(forest forage)))
+ (values))
(defun run ()
(init)
@@ -235,7 +435,7 @@
(run))
(defun build ()
- (sb-ext:save-lisp-and-die "build/dark"
+ (sb-ext:save-lisp-and-die "build/mycelium"
:executable t
:save-runtime-options t
- :toplevel #'dark:toplevel))
+ :toplevel #'mycelium:toplevel))
--- a/src/package.lisp Tue Apr 20 15:13:04 2021 -0400
+++ b/src/package.lisp Tue Apr 20 18:01:32 2021 -0400
@@ -1,4 +1,4 @@
-(defpackage :dark
+(defpackage :mycelium
(:use :cl :iterate :losh)
(:shadow :random)
(:export :toplevel :build))