december adventure
table of contents
โ๏ธ
December Adventure is an online event where people pick a project to work on , and log their progress throughout the month of December . you can see a list of adventure logs written by other people here !
2025
december 9th
today i started the documentation generator for pyra , which i'm also using as an opportunity to refine a representation of Nova rules for structural editors that i've been planning .
here's a screenshot of two rules from the painting example program , run through the docs generator :
and here's the original pyra code it corresponds to :
some notes about the design :
- each rule looks like its own "note card"
- the causes have white text , while the effects have pink text . there's also a heavy drop shadow to make the line between them apparent
- facts that will be kept have a green line on the left side
- the stack and fact pairs are separated using vertical lines , which correspond to colons in the textual representation
i still need to incorporate representations for variables , strings , strides , and snippets . and possibly differentiate the causes from the effects even more .
finally , here's the compiler code that generates the HTML for this representation ( don't worry , the divs are just placeholders that'll be replaced with more accessible markup later on ) :
function formatPattern(pattern)
if pattern.stack == ''
then return format(
'<div class="fact">_</div>',
pattern.fact
) else return format(
'<div class="stack">_</div><div class="fact">_</div>',
pattern.stack, pattern.fact
) end
end
for _, rule in ipairs(rules) do
iLine '<div class="rule">'
if #rule.causes > 0 then
iLine '<div class="causes">'
for _, cause in ipairs(rule.causes) do
local keep = ''
if cause.keep then keep = ' keep' end
local stride = ''
if cause.stride then stride = ' stride' end
iLine('<div class="pattern__">_</div>',
keep, stride, formatPattern(cause))
end
iLine '</div>'
end
if #rule.effects > 0 then
iLine '<div class="effects">'
for i = #rule.effects, 1, -1 do
iLine('<div class="pattern">_</div>',
formatPattern(rule.effects[i]))
end
iLine '</div>'
end
iLine '</div>'
end
๐ง song of the day :
test & recognise [ Flume re-work ] slowed โ Seekae
december 8th
i finished more today than i expected ! it feels like the daily cognitive context-loading of December Adventure allowed me to venture deeper into the flow state than usual . changes :
- updated the pyra examples to use the new library and importing scheme
- added support for transitive dependencies , with deduplication
- resisted the urge to improve the examples and library code . this was difficult , but it's low priority and i'd rather spend my time preparing for documentation right now
- added a script to rebuild every example at once
- fixed strings . double quotes are automatically escaped . you can manually escape closing brackets . you also need to manually escape strings that start with a capital . this is an unusual language design decision , but it's the only thing that meshed well with capitalized variables
- pushed the changes to the pyra repo , so you can try them out yourself !
- added myself to the team page on the Nova website
tomorrow , it'll be time to start writing the library documentation generator , which i've been quite excited for !
๐ง song of the day :
ในใใใใใคในใใใ โ Macroblank
december 7th
today i finished organizing the pyra libraries ! so refreshing . here are the libraries we've got now :
- browser
- case
- comparison
- dom
- filesystem
- inline
- iteration
- love
- math
- nokogiri
- stacks
- strings
- system
another thing that'll make the imports cleaner is to add a separate import type for standard libraries that lets you omit the path and extension . that means something like this :
~ include file: ../../libraries/one.nv ../../libraries/two.nv ../../libraries/three.nv
can be written like this :
~ use library: one two three
much shorter , and less fragile ! tomorrow i'll update the examples to use the new libraries in this way .
woah woah WOAH . hold up . you're tellin' me that the song of the day was concocted by autumn this time ? that's right :
๐ง song of the day :
waddle fractal โ autumn nebulae
december 6th
today i began restructuring pyra's libraries . i want to get this out of the way first , since it's the only significantly backward-incompatible change on the list .
the libraries that use snippets are currently organized by backend : lua.nv , ruby.nv , and javascript.nv . this results in a lot of duplication , makes it hard to split them up further , and just doesn't really make much sense .
the first step in ameliorating the situation is to merge them all into one , which we can do by allowing rules to have multiple snippets : one for each backend they support . now you'll be able to use the snippet symbol ^ followed by the name of a backend , and the compiler will insert the correct snippet depending on which program is using the rule . here's an example rule with a ^lua and a ^ruby snippet :
* get the current time
^lua f('result', {os.clock()})
^ruby f 'result', [Time.now.to_f]
i merged the backend-specific libraries using this new capability , so the next step will be to organize the rules based on the function they serve , like logging.nv or iteration.nv . after that , i'll need to update the example projects to use the new library scheme .
another motivation for restructuring the libraries is to prepare for the documentation backend . the compiler now stores which backends a given rule supports , so we can show this information in the documentation !
๐ง song of the day :
CLOCK โ Plaid
december 5th
today's been a quiet day of plotting and scheming ! here's the resulting list of priorities for pyra and beyond :
- restructure libraries around use , not compiler backend
- fix strings that contain quotes , brackets , and uppercase
- HTML docgen backend ร la Hoogle
- self-hosted with Go backend for cross-platform binaries
- project creation commands
- stack changelog for debugging
- documentation on pyra.run
- create utopie using pyra with Godot backend
- create mooncake using utopie
a while ago i renamed the old version of pyra to "stackless pyra" , and "pyra0" to pyra . today i updated the name of the the repo to reflect this .
๐ง song of the day :
Hive โ Mobster
december 4th
i'm done working on my site for now , so it's finally .......
PYRA TIME !!! MUAHAHAHAHA
we're startin' off by gently vaporizing a terribly nettlesome quality of the pyra compiler : it doesn't produce deterministic output ! this becomes a hassle when you have a git repo with a pyra program , and the generated code changes randomly every time you recompile .
the code changes because Lua doesn't ensure an iteration order for tables , and i use Lua tables a lot in the compiler . today i fixed this by introducing a lovely little function by Rici Lake that lets you create ordered tables ! it stores the order that you add keys to the table in a linked list , and overrides the __pairs() iteration function to take that order into account :
local function Ordered()
local key2val, nextkey, firstkey = {}, {}, {}
nextkey[nextkey] = firstkey
local function onext(self, key)
while key ~= nil do
key = nextkey[key]
local val = self[key]
if val ~= nil then return key, val end
end
end
local selfmeta = firstkey
selfmeta.__nextkey = nextkey
function selfmeta:__newindex(key, val)
rawset(self, key, val)
if nextkey[key] == nil then
nextkey[nextkey[nextkey]] = key
nextkey[nextkey] = key
end
end
function selfmeta:__pairs()
return onext, self, firstkey
end
return setmetatable(key2val, selfmeta)
end
after adding this function , i only needed to swap out three tables in the compiler with ordered tables , et voilร , deterministic output ! this also prepares me for making pyra self-hosted , because i can now use the example programs to conveniently verify that updates to the compiler don't change the output by running git diff .
on another note , i made few style fixes on a new website i'm helping to design for the Nouveau Community . Safari has always been the bane of my existence as a web designer . it seems like i'm always discovering new snippets of CSS the WebKit engine can't handle . this time it was text underlines ! (แแฃแ)
i still want to support WebKit browsers for websites i design , in spite of this . i had been using an old Apple device for testing , but today i realized i can install a browser for Linux that uses WebKit instead ! i'm on Fedora , so i installed GNOME Web using the command sudo dnf install epiphany . it worked splendidly for testing the design ; i should've done this a long time ago !
๐ง song of the day :
CHEAT CODES โ TOKYO MACHINE
december 3rd
the managing N24 post is finally complete ! today's portion dives into the VLiDACMel therapy , zeitgebers , and DSPD . it was difficult to include all of the information i wanted without teetering into overwhelming territory . hopefully i struck a good enough balance for people who are new to the subject .
i've been trying out a more casual and playful tone than i usually use in my "serious" informational posts . i noticed how much i've been holding back a more relaxed , and in my opinion , more authentic side of myself . the shift may not be apparent from the exterior , but it feels more nourishing . a small step toward the unfolding of the internet i long to inhabit .
finally , i sent an email to the creator of VLiDACMel , to thank them for how much they've helped .
๐ง song of the day :
81 Special [Slowed + Reverb] โ Caravan Palace
december 2nd
today i collected , ordered and structured all of the scattered notes i've taken about N24 into a friendly article-like shape . the first section is now live on the managing N24 page . i'm planning to edit and post the remaining sections tomorrow !
many of my notes were copied directly from written conversations i've had with friends , which has been a fun source to harvest from !
december 1st
the main project i'd like to work on this month is my programming language , pyra ! however , there's one page on my website that i want to finish first .
i have a rare circadian rhythm disorder called N24 . i recently learned how to manage the condition using a protocol called VLiDACMel , and have been writing an article about my experiences .
something i want to include is an actogram of the sleep data i captured between October of 2023 and November of 2024 . i used a sleep tracker called Plees Tracker , which is a great app , but there's no built-in way to create a visualization how i want . thankfully , it exports data as a CSV that looks like this :
12,1696711105697,1696744567977,4, 13,1696806609732,1696836850079,3, 14,1696902967015,1696940138010,2, 15,1697001200047,1697033781756,0, ...
the second and third columns are the important bit , and store the start and end times of each recorded rest period , encoded in milliseconds elapsed since the Unix epoch . not wanting to create a visualizer from scratch , i found a project that was close to what i needed and looked simple to modify . from there , i made a few modifications to the CSV parsing code and graph styling . the resulting script is available here !
processing my sleep data with the script results in the following graph ( click here to view larger ) :
this is actually the first time i've seen this data laid out so clearly , and it's interesting how chaotic it looks ! it almost resembles ISWRD , but i'm pretty sure that's an effect of having an unusually long phase delay and frequent interruptions .
today i also added an updates page , to list all of the other changes i've been making to my site recently !
backlinks
- index: โ๏ธ december adventure log โ๏ธ
- updates: december adventure
- wiki: december adventure