77 lines
3.4 KiB
Org Mode
77 lines
3.4 KiB
Org Mode
* Minimal Fennel Love2D Setup
|
|
|
|
In a lead up to the annual [[https://itch.io/jam/autumn-lisp-game-jam-2018][Autumn Lisp Game Jam]] I thought I'd look into Phil Hegelberg's approach to last Aprils Jam, using [[https://love2d.org/][love2d]] in concert with [[https://fennel-lang.org/][fennel]]. Phil outlines his approach on his [[https://love2d.org/][blog]].
|
|
|
|
The first step is to see how fennel works as a standalone execution environment, then slowly integrate some of the love2d API.
|
|
|
|
This repo contains the minimal viable setup to get started with Phil Hegelberg's game design process, plus some additional libraries.
|
|
|
|
#+BEGIN_SRC bash
|
|
PROJECT=project-name
|
|
git clone https://gitlab.com/alexjgriffith/min-love2d-fennel.git $PROJECT
|
|
cd $PROJECT
|
|
rm -rf .git
|
|
#+END_SRC
|
|
|
|
* Phil's Modal Callbacks (PMC)
|
|
Phil Hegelberg's [[https://gitlab.com/technomancy/exo-encounter-667/][exo-encounter-667]] is structured using a modal callback system. Each game state has a mode and each mode has a series of specific callbacks.
|
|
|
|
If you design your game as a series of states in a very simple state machine, for example *start-screen*, *play* and *end*, with unidirectional progression, you can easily separate the logic for each state into state/mode specific callbacks. As an example, in order to have state dependant rendering that differs between start-screen,play and end you could provide a *draw* callback for each of those states. Similarly if we need state dependent logic and keyboard input we could provide *update* and *keyboard* callbacks. As you iterate you can add and remove callbacks and states/modes as needed with very little friction.
|
|
|
|
|
|
* Emacs Setup
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(autoload 'fennel-mode "/path/to/fennel-mode" nil t)
|
|
(require 'fennel-mode)
|
|
|
|
;; By default fennel-mode moves focus to the \*inferior-lisp\* buffer
|
|
;; setting `fennel-mode-switch-to-repl-after-reload' to nil prevents this
|
|
(customize-save-variable 'fennel-mode-switch-to-repl-after-reload nil)
|
|
|
|
(add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode))
|
|
|
|
;; you can bind this to whatever you like
|
|
(defun run-love ()
|
|
(interactive)
|
|
(run-lisp "love ."))
|
|
|
|
;; for some reason when I load a fnl file it starts the slime minor mode
|
|
;; I have included the hook below to prevent this
|
|
(defun fennel-mode-hook-fun ()
|
|
(interactive)
|
|
(slime-mode nil))
|
|
|
|
(add-hook 'fennel-mode-hook 'fennel-mode-hook-fun)
|
|
#+END_SRC
|
|
|
|
* Known Issues
|
|
Presently fennel.lua has to be in the main directory for =fennel-reload= from fennel-mode.el to work. The issue is
|
|
|
|
#+BEGIN_SRC elisp
|
|
(let [old (require :module-name)
|
|
_ (tset package.loaded :module-name nil)
|
|
(ok new) (pcall require :module-name) ;; fails if fennel not in base directory
|
|
new (if (not ok) (do (print new) old) new)]
|
|
(when (= (type new) :table)
|
|
(each [k v (pairs new)] (tset old k v))
|
|
(each [k (pairs old)] (when (not (. new k)) (tset old k nil)))
|
|
(tset package.loaded :module-name old)))
|
|
#+END_SRC
|
|
|
|
|
|
The error that gets thrown is.
|
|
#+BEGIN_SRC
|
|
./module-name.fnl:#Some Number#: module 'fennel' not found:
|
|
no field package.preload['fennel']
|
|
no 'fennel' in LOVE game directories.
|
|
no file 'fennel' in LOVE paths.
|
|
no file './fennel.lua'
|
|
no file '/usr/local/share/luajit-2.0.5/fennel.lua'
|
|
no file '/usr/local/share/lua/5.1/fennel.lua'
|
|
no file '/usr/local/share/lua/5.1/fennel/init.lua'
|
|
no file './fennel.so'
|
|
no file '/usr/local/lib/lua/5.1/fennel.so'
|
|
no file '/usr/local/lib/lua/5.1/loadall.so'
|
|
#+END_SRC
|