What's this?

The December Adventure is low key. The goal is to write a little bit of code every day in December …doesn’t even really have to be code! Let the December Adventure be for all kinds of creative pursuits.
— eli, December Adventure

IRC: #decadv @ irc.libera.chat:6697
Fediverse tag: #DecemberAdventure

Start!

📆 Use the calendar below to jump to the latest entry. Or any entry

Su Mo Tu We Th Fr Sa
  01 02 03 04 05 06
07 08 09 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

A december adventure seems perfect for me: do something, anything, whatever amount, every day, and make note of it. My goal this month is to use Trial, a game engine written in Common Lisp, to re-implement this basic FPS demo from Raylib:

2025-12-01__00-07-58.png
Figure 1: examples/core/core_3d_camera_fps.c

It's a simple demo too. I'm basically recreating the FPS camera from my nohgl project, grounding it to the xz plane, and adding a couple of fields to simulate quake-like movement. The difficult part is figuring out the Trial-provided mechanisms to glue it all together. Once I get the ball rolling (heh), collision and other stuff can be built on top of it. Eventually, we can have an actual FPS demo that could qualify as a game.

01

Alright, said I was going to focus on the FPS demo, but I sidetracked. I'm using org-publish to build my site, and it's ~okay'ish.

Emphasis on the ish

I do not like Org mode. Ten years of Emacs and I still despise it. All the options, different ways of setting options, hidden precedence of options, how difficult it is to figure out what is calling what; this thing is an ORGanic pile of spaghet. Apologies to all the skilled Emacs hackers that work on Org mode and understand it: I do not, but I do appreciate your work. It's what I fucked around with for the first day of my adventure so I'm a little grumpy but getting over it now since I can finally just write.

write

In order to just write, the yakkin was a bit of a need. The less friction the better. For the rest of the month I won't think about how any of this is getting uploaded.


Using org-publish facilities I define three projects:

  • zyd.lol/org : grab all the org files it can find recursively
  • zyd.lol/data : directory i use for attachments and the like
  • zyd.lol/assets : css etc

And a fourth 'meta' project that just builds each of the above three

  • zyd.lol
(setq org-publish-project-alist
      '(("zyd.lol/org"
         :base-extension "org"
         ;; Include file
         :exclude "base.org"
         :base-directory "~/notes/zyd.lol/"
         :publishing-directory "~/docs/zyd.lol/"
         :publishing-function org-html-publish-to-html
         :recursive t)
        ("zyd.lol/data"
         :base-extension any
         :base-directory "~/notes/zyd.lol/data/"
         :publishing-directory "~/docs/zyd.lol/data/"
         :publishing-function org-publish-attachment
         :recursive t)
        ("zyd.lol/assets"
         :base-extension any
         :base-directory "~/notes/zyd.lol/assets/"
         :publishing-directory "~/docs/zyd.lol/assets/"
         :publishing-function org-publish-attachment
         :recursive t)
        ("zyd.lol" :components ("zyd.lol/org" "zyd.lol/data" "zyd.lol/assets"))))

Each individual org file #+INCLUDE's base.org to set up some nonsense

OPTIONS: title:nil toc:nil html-style:nil ^:nil num:nil html5-fancy:t
OPTIONS: author:nil html-postamble:nil
HTML_DOCTYPE: html5
HTML_HEAD: <link rel="stylesheet" type="text/css" href="/assets/style.css"/>
HTML_HEAD: <link rel="icon" type="image/x-icon" href="/assets/favicon.jpg" />

To build all these files and test out path resolving as if its on an actual web server, I'm using simple-httpd.

M-x zyd/build-site and point my browser @ localhost:8080

(defun zyd/publishing-directory (project)
  (org-publish-property
   :publishing-directory
   (assoc project org-publish-project-alist)))

(defun zyd/build-site (&optional stop-server)
  (interactive "P")
  (let ((org-html-prefer-user-labels t)
        (org-export-with-broken-links t)
        (org-html-self-link-headlines t)
        (dir (zyd/publishing-directory "zyd.lol/org")))
    (org-publish "zyd.lol")
    (if stop-server (httpd-stop)
      (httpd-serve-directory dir))
    dir))

And to actually upload I'm using Sourcehut:

(defun zyd/push-site ()
  (interactive)
  (let* ((inhibit-message t)
         (site (zyd/build-site t))
         (tarball (format "%ssite.tar.gz" site)))
    (shell-command
     (format "cd %s && \
              rm -f %s && \
              tar -cvz * > %s"
             site
             tarball
             tarball))
    (async-shell-command
     (format "hut pages publish -d zyd.lol %s" tarball))))

One frustrating thing about Org that I haven't been able to 'fix' is when linking local .org files, in the HTML export they end up being transformed into anchor tags with hrefs that use the file:// protocol. I tried figuring out how I was expected to configure this but ended up just monkey patching org-html-link which is responsible for transforming org links.

(defun string-replace-> (replacements in-string)
  "Return a string after a list of string replacements '((from-string
to-string)) have been applied to IN-STRING."
  (let ((%in-string (copy-sequence in-string)))
    (pcase-dolist (`(,from-string ,to-string) replacements)
      (setq %in-string (string-replace from-string to-string %in-string)))
    %in-string))

(defun zyd/filter-org-html-links (fn &rest args)
  "Hack to replace file:// protocol links and index.html"
  (string-replace->
   '(("file://" "")
     ("/index.html" "/"))
   (apply fn args)))

(advice-add 'org-html-link :around 'zyd/filter-org-html-links)

pcase is cute and all my homies love destructuring

So that's all I wrote today. Not a lot but it took way longer than I'd care to admit, specifically figuring out how to deal with org links. It's 7PM now, maybe I can find another burst of executive function and start working on the FPS demo. Who knows.

02

  • Added a calendar to the log. Idea inspired/stolen from devine's own adventure log. Intent is that it'll be easy for folks regularly checking in to jump to the latest entry while also making chronological sense to anyone reading for the first time.
  • Fiddled with website look and settled on it, so we're moving on to our actual goal of the FPS demo. One thing to note for future logs, decadv or otherwise, is the need to set up the page/site, and any workflow, before we start. Ended up getting extremely distracted by setting it up on a moment's notice but what else can be done? At least the very existence of this log keeps reminding me of what I set out to do. Hoping any future side quests this month will stay related to game programming.