In this post I talk about how I went about setting up a stat visualization page for my rockbox mp3 player.
+
+
+
+A static site generation experiment
+
+
+
+
Preamble: Digital Sovereignity & Rockbox
+
+ I've been building up a pretty sizeable collection of digital music
+ over the last couple of years. I think there's a lot of value in owning
+ the music I pay for and being able to choose how I listen to it.
+ Purchasing music also allows me to support artists in a more direct
+ and substantial way than the fractions of cents for using streaming services,
+ but that's more of a happy consequence than some moral obligation I feel.
+
+
+ Over the years, I've enjoyed listening to my music in a variety of ways.
+ For years I kept all of my music files on all of my devices and used
+ various local music clients depending on the platform, most notably mpd
+ and ncmpcpp on linux. Eventually, as I charged headlong into the glorious
+ world of self-hosting, I began using a central Jellyfin media server that
+ I stream music and video from. It's super convenient, and works on all of
+ my devices (including my TV!).
+
+
+ My media server is great, and it's been the primary way I listen to music
+ for a while now. But it has limitations. For example, I don't expose my media
+ server to the internet, so I'm unable to stream from it while I'm out and
+ about. And even if I could, the bandwidth requirements would be pretty high.
+ I figured I would need a dedicated music player if I wanted to take my music
+ library on the go, and settled on the HIFI Walker H2 after reading some
+ online recommendations. The ability to install Rockbox, an open-source firmware,
+ was a big factor in my decision. I couldn't tell you how the device works
+ out of the box, since I flashed the firmware pretty much immediately once I got it,
+ but I've been super impressed with how the device works while running Rockbox.
+
+
+
+
+ I'm using a modified version of the InfoMatrix-v2 theme, which looks great.
+
+ Rockbox comes with many codecs for common audio formats including FLAC and MP3. The
+ device boots extremely quickly, and the interface is snappy. Virtually every aspect
+ of the user experience is tweakable and customizable to a crazy degree. I've even begun
+ listening to music on my player even at home, since a device specifically for the
+ purpose provides less distraction while I'm trying to be productive.
+
+
+ All this to say I'm pretty much sold on Rockbox. But there's certain things I
+ still miss from my days of being a user of popular services like Spotify with
+ fancy APIs and data tracking. Things like Spotify wrapped or third-party apps
+ for visualizing playback statistics are a fun way to see what my listening history
+ looks like and could potentially be used to help find more music that I'd enjoy.
+ This is why when I noticed that Rockbock has a playback logging feature, a little
+ lightbulb lit up over my head.
+
+
+
+
Generating and Parsing Logs
+
+
+
+ The logging feature can be accessed through the settings menu.
+
+ Rockbox has a feature that logs playback information to a text file. This feature can
+ be enabled by setting Playback Settings > Logging to "On". With this setting enabled, a
+ new line gets added to the end of the .rockbox/playback.log file every time you play a track,
+ containing info about what you played and when.
+
+
+ The logging feature is actually already used by the LastFM scrobbler plugin that comes preloaded with
+ Rockbox, which is probably the simplest way to get insights into your playback. However,
+ I personally want to avoid using third-party services as much as possible, because it's more fun.
+
+
+ If I take a look at a logfile generated after a bit of listening, I'll see that I've wound up with
+ a series of lines that each look something like this:
+
+
1758478258:336689:336718:/<microSD0>/Music/This Is The Glasshouse/This Is The Glasshouse - 867/This Is The Glasshouse - 867 - 01 Streetlight By Streetlight.flac
+ An example of a log entry for "Streetlight by Streetlight" by This is the Glasshouse.
+
+
+
+
+ I wasn't really able to find any information online about the format of these logs, but they appear
+ to be simple enough to figure out. From what I can tell, each event is broken up into 4 pieces:
+
+
Timestamp: The number of milliseconds since the UNIX epoch.
+
Playback Duration: The amount of the song that was played, in milliseconds.
+
Total Track Length: The length of the played track, in milliseconds.
+
File Path: An absolute path to the file containing the track on the filesystem.
+
+ All of this is enough to know what I was listening to and when. I can use the file path to check for
+ audio tags which can help glean even more information about my listening habits.
+
+
Now that I have this information and know how to interpret it, I'm ready to start processing it!
+
+
+
Analyzing Playback History
+
+ In order to get some useful information out of my playback history, I think it's a good idea to start by
+ building
+ a database. I created a sqlite database with the following tables:
+
+
+
+
+
songs
+
+
+
+
+
id
+
i64
+
PK
+
+
+
title
+
String
+
+
+
+
artists
+
JSON
+
+
+
+
album_id
+
i64?
+
+
+
+
genre
+
String?
+
+
+
+
+
+
+
+
+
+
albums
+
+
+
+
+
id
+
i64
+
PK
+
+
+
title
+
String
+
+
+
+
artist
+
String
+
+
+
+
cover_art
+
Blob?
+
+
+
+
+
+
+
+
+
+
history
+
+
+
+
+
id
+
i64
+
PK
+
+
+
timestamp
+
Datetime
+
+
+
+
duration
+
i64
+
+
+
+
song_id
+
i64
+
+
+
+
+
+
+ I can add more columns later, but this is a good place to start.
+
+
+ Now, as I read through the logfile line-by-line, I can check if each album exists before
+ inserting it into the database:
+
+
for line in log_file.lines().flatten() {
+println!("{line}");
+// Skip comments
+if line.starts_with("#") {
+continue;
+}
+let chunks = line.split(":").collect::>();
+
+let timestamp = DateTime::from_timestamp_secs(
+i64::from_str_radix(chunks[0], 10).context("Failed to parse timestamp")?,
+)
+.context("Failed to convert timestamp")?;
+
+// Load tags from file on device
+let file_path = chunks[chunks.len() - 1][1..]
+.split_once("/")
+.context("Missing file")?
+.1;
+let tags = Tag::new()
+.read_from_path(args.mount_point.join(file_path))
+.context("Failed to read audio tags")?;
+
+//...
+}
if let Some(existing_album) =
+sqlx::query("SELECT id FROM albums WHERE title=$1 AND artist=$2")
+.bind(album_title)
+.bind(album_artist)
+.fetch_optional(&mut *db)
+.await
+.context("Failed to execute query to find existing album")?
+{
+let album_id: i64 = existing_album.get("id");
+info!("Album already exists, id {album_id}");
+//...
+} else {
+info!("Inserting new album: {album_title} by {album_artist}");
+//...
+let result = sqlx::query(
+"INSERT INTO albums (title, artist, cover_art) VALUES ($1, $2, $3);",
+)
+.bind(album_title)
+.bind(album_artist)
+.bind(cover)
+.execute(&mut *db)
+.await
+.context("Failed to execute query to insert album into database")?;
+
+//...
+}
+ Checking for an album with matching artist and title before creating a new row in the
+ database.
+
+ I did something similar with the songs and history tables, basically building up a cache
+ of history information and skipping anything that's already in the database on repeat runs.
+
+
+ With this database constructed, it's pretty easy to get a bunch of different information
+ about my listening. For example (forgive me if my SQL skills are kind of ass lol):
+
+
SELECT
+songs.title AS song_title,
+songs.artists AS song_artists,
+songs.genre AS song_genre,
+albums.title AS album_title,
+albums.artist AS album_artist,
+history.timestamp AS timestamp,
+history.duration AS duration
+FROM history
+CROSS JOIN songs ON songs.id = history.song_id
+CROSS JOIN albums ON albums.id = songs.album_id
+ORDER BY timestamp DESC;
+ Querying for a list of each history entry along with track metadata, sorted from most to
+ least recent.
+
+
+
SELECT
+songs.genre,
+SUM(history.duration) AS total_duration
+FROM history
+CROSS JOIN songs ON history.song_id = songs.id
+GROUP BY genre
+ORDER BY total_duration DESC
+LIMIT 10;
+ Querying for the top 10 most listened genres by playtime.
+
+
+
+ It's all well and good to be able to view this information using a database client,
+ but it would be really cool if I could visualize this data somehow.
+
+
+
+
Visualizing this Data Somehow
+
+ I wanted to make this data available on my website for people to view, and for a bunch of mostly trivial
+ reasons I won't get into here, I have a couple of requirements for pages on this site:
+
+
Pages need to be static.
+
Pages need to be JavaScript-free.
+
+ This means any chart rendering needs to be done automatically at build time before
+ deploying. I don't currently use a static site generator for my site (just for fun),
+ so I'm basically going to need to write one specifically to generate this page.
+
+
+ I won't get too deep into the specifics of how I queried the database and generated each visualization
+ on
+ the page, but I can explain the visualizations I created using the queries from the previous section.
+ For the
+ listening history I wanted to generate a table displaying the information. To accomplish this, I first
+ used a combination of sqlx's ability to convert a row to a struct and serde to serialize
+ the rows as JSON values.
+
+
+ Struct definition for a history entry, allowing conversion from a sqlx row and
+ de/serialization from/to JSON.
+
+
+
+ In order to keep the generation as painless as possible, I decided to use the Tera template
+ engine, which allows me to define a template HTML file and substitute in values from
+ a context which I can define before rendering. In the case of the table, I can just generate a <tr>
+ matching the data for each item:
+
+
+
+ A Tera macro for generating a table from a list of playback history items.
+ I used a macro so I can re-use this later if I want to add time range views.
+ (last month, year, etc.)
+
+
+
+
+ I wrote similar macros for each of the visualizations I wanted to create. Most are
+ easy, but for my top 10 genres I wanted to display a pie chart. I found a pretty decent
+ data visualization crate called charming that's able to render to html, however
+ the output contains javascript so it's a no-go for me. Luckily, it can also render to
+ an SVG which I can embed nicely within the page.
+
+
+ Here's one I generated just now.
+
+
+
+ And that's pretty much all there is to it! The finished thing can be found here.
+
+
+
\ No newline at end of file
diff --git a/content/blog/rockbox_stats/log-setting.bmp b/content/blog/rockbox_stats/log-setting.bmp
new file mode 100644
index 0000000..29789fa
Binary files /dev/null and b/content/blog/rockbox_stats/log-setting.bmp differ
diff --git a/content/blog/rockbox_stats/playback-settings.bmp b/content/blog/rockbox_stats/playback-settings.bmp
new file mode 100644
index 0000000..cee3cfb
Binary files /dev/null and b/content/blog/rockbox_stats/playback-settings.bmp differ
diff --git a/content/blog/rockbox_stats/player.bmp b/content/blog/rockbox_stats/player.bmp
new file mode 100644
index 0000000..452a057
Binary files /dev/null and b/content/blog/rockbox_stats/player.bmp differ
diff --git a/content/blog/terminal_renderer_mkii/cover.png b/content/blog/terminal_renderer_mkii/cover.png
new file mode 100644
index 0000000..b3ddfd9
Binary files /dev/null and b/content/blog/terminal_renderer_mkii/cover.png differ
diff --git a/content/blog/terminal_renderer_mkii/david.png b/content/blog/terminal_renderer_mkii/david.png
new file mode 100644
index 0000000..6cfa884
Binary files /dev/null and b/content/blog/terminal_renderer_mkii/david.png differ
diff --git a/content/blog/terminal_renderer_mkii/davidbayer.png b/content/blog/terminal_renderer_mkii/davidbayer.png
new file mode 100644
index 0000000..af4bfc4
Binary files /dev/null and b/content/blog/terminal_renderer_mkii/davidbayer.png differ
diff --git a/content/blog/terminal_renderer_mkii/davidthreshold.png b/content/blog/terminal_renderer_mkii/davidthreshold.png
new file mode 100644
index 0000000..6c6e014
Binary files /dev/null and b/content/blog/terminal_renderer_mkii/davidthreshold.png differ
diff --git a/content/blog/terminal_renderer_mkii/index.md b/content/blog/terminal_renderer_mkii/index.md
new file mode 100644
index 0000000..1797a4a
--- /dev/null
+++ b/content/blog/terminal_renderer_mkii/index.md
@@ -0,0 +1,167 @@
++++
+title = "Terminal Renderer Mk. II - Rendering to Text with Compute"
+date = "2025-10-02"
++++
+
+
+
This week I brought my terminal renderer to the next level by performing text rendering on the GPU.
+
+
+
+
+ The Stanford Dragon, outlined and rendered as Braille characters in a terminal emulator.
+Full video
+
+
+
+
+
Context
+
Unicode Braille
+
+I first messed around with rendering images to the terminal with Braille characters in like 2022 I
+think? I wrote a simple CLI tool
+that applied a threshold to an input image and output it as Braille characters in the terminal. Here's a recording I took back
+ when I did it.
+
+
+
+
+
+
+
+
+
0
+
3
+
+
+
1
+
4
+
+
+
2
+
5
+
+
+
6
+
7
+
+
+
+
+The corresponding bit position for each braille dot.
+
+This effect is pretty cool, and it was pretty easy to implement as well. The trick lies in how the
+Unicode Braille block
+is laid out. Every 8-dot Braille combination happens to add up to 256 combinations, the perfect amount to
+fit in the range between 0x2800 (⠀) and 0x28FF (⣿). In other words, every
+character
+within the block can be represented by changing the value of a single byte.
+
+
+The lowest 6 bits of the pattern map on to a 6-dot braille pattern. However, due
+to historical reasons the 8-dot values were tacked on after the fact, which adds
+a slightly annoying mapping to the conversion process. Either way, it's a lot easier
+than it could be to just read a pixel value, check its brightness, and then use a
+bitwise operation to set/clear a dot.
+
+
Ordered Dithering
+
+Comparing the brightnes of a pixel against a constant threshold is a fine way to
+display black and white images, but it's far from ideal and often results in the loss
+of a lot of detail from the original image.
+
+
+
+
+
+
+
+From left to right: Original image, threshold, and ordered dither. Wikipedia
+
+
By using ordered dithering,
+we
+can preserve much more of the subtleties of the original image. While not the "truest" version of
+dithering possible,
+ordered dithering (and Bayer dithering in particular) provides a few advantages that make it very
+well suited to realtime computer graphics:
+
+
Each pixel is dithered independent of any other pixel in the image, making it extremely
+ parallelizable and good for shaders.
+
It's visually stable, changes to one part of the image won't disturb other areas.
+
It's dead simple.
+
+Feel free to read up on the specifics of threshold maps and stuff, but for the purposes of this little
+explanation it's
+enough to know that it's basically just a matrix of 𝓃⨉𝓃 values between 0 and 1, and then to determine
+whether a pixel (𝓍,𝓎)
+is white or black, you check the brightness against the threshold value at (𝓍%𝓃,𝓎%𝓃) in the map.
+
+
+
+
The old way™
+
+My first attempt at realtime terminal graphics with ordered dithering
+(I put a video up at the time)
+ran entirely on the CPU. I pre-calculated the threshold map at the beginning of execution and ran each
+frame
+through a sequential function to dither it and convert it to Braille characters.
+
+
+To be honest, I never noticed
+any significant performance issues doing this, as you can imagine the image size required to fill a
+terminal
+screen is signficantly smaller than a normal window. However, I knew I could easily perform the
+dithering on the GPU
+as a post-processing effect, so I eventually wrote a shader to do that. In combination with another
+effect I used to
+add outlines to objects, I was able to significantly improve the visual fidelity of the experience. A
+good example of
+where the renderer was at until like a week ago can be seen in this video.
+
+
+Until now I hadn't really considered moving the text conversion to the GPU. I mean, GPU is for
+graphics,
+right? I just copied the entire framebuffer back onto the CPU after dithering
+and used the same sequential conversion algorithm. Then I had an idea that would drastically reduce the
+amount
+of copying necessary.
+
+
+
+
Compute post-processing
+
+What if, instead of extracting and copying the framebuffer every single frame, we "rendered" the text on
+the GPU
+and read that back instead? Assuming each pixel in a texture is 32 bits (RGBA8), and knowing that
+each braille
+character is a block of 8 pixels, could we not theoretically shave off at least 7/8 of the bytes
+copied?
+
+
+As it turns out, it's remarkably easy to do. I'm using the Bevy engine,
+and hooking in a compute node to my existing post-processing render pipeline worked right out of the
+box.
+I allocated a storage buffer large enough to hold the necessary amount of characters, read it back each
+frame, and dumped
+the contents into the terminal.
+
+
+I used UTF-32 encoding on the storage buffer because I knew I could easily convert a "wide string" into
+UTF-8 before printing it, and
+32 bits provides a consistent space to fill for each workgroup in the shader versus a variable-length
+ encoding like UTF-8. Here's a video of the new renderer working.
+Although now that I think about it, I could probably switch to using UTF-16 since all the Braille
+characters could be represented
+in 2 bytes, and that would be half the size of the UTF-32 text, which is half empty bytes anyways.
+
+
+Okay so I went and tried that but remembered that shaders only accept 32-bit primitive types, so it doesn't matter anyways. This little side quest has been a part of my
+broader efforts to revive a project I
+spent a lot of time on. I'm taking the opportunity to really dig in and rework some of the stuff I'm not
+totally happy with. So there might be quite a few of this kind of post in the near future. Stay tuned.
+
+
diff --git a/content/blog/vscode_buttplug/buttplug-0.0.1.vsix b/content/blog/vscode_buttplug/buttplug-0.0.1.vsix
new file mode 100644
index 0000000..f57f8d3
Binary files /dev/null and b/content/blog/vscode_buttplug/buttplug-0.0.1.vsix differ
diff --git a/content/blog/vscode_buttplug/index.md b/content/blog/vscode_buttplug/index.md
new file mode 100644
index 0000000..6abe64d
--- /dev/null
+++ b/content/blog/vscode_buttplug/index.md
@@ -0,0 +1,63 @@
++++
+title = "Visual Studio Code Buttplug Integration"
+description = "Vibe coding."
+date = "2026-01-29"
++++
+
+[tl;dr: download VSIX here lol](./buttplug-0.0.1.vsix)
+
+This is perhaps one of the most important project ideas I've come up with in a while. I pounded a redbull at like 8pm and then an angel of the Lord appeared to me and said "Man, it would be really funny if you added buttplug support to vscode". So I did. I was inspired by various buttplug mods for random games that probably have no business having buttplug mods, like Ultrakill's [UKButt](https://github.com/PITR-DEV/ukbutt-mod) mod and the pioneering mind who made one for [Webfishing](https://github.com/elliotcubit/WebfishingButtplug).
+
+I've been wanting to dip my toes into VS Code extension development for a while, and something like buttplug integration seemed like an interesting step up from a basic hello world. Plus I get to be the guy who made a buttplug extension for a text editor, and bring that up at networking events, parties, and job interviews.
+
+So you might be wondering what the hell "buttplug integration" actually means. As it turns out, ass hardware is pretty advanced these days, with all kinds of bluetooth doohickeys that irradiate your insides and connect to your Google Home to your prostate and shit. Naturally, open source protocols for interfacing with smart sex toys have also emerged. [Buttplug.io](https://buttplug.io/) seems like a pretty popular choice for this, and it's actually pretty easy to work with.
+
+That still leaves the question of what buttplug integration should look like for a text editor. This is a subject that invites rigorous debate. I was looking at this from a very practical standpoint, so my main goal was to provide developers with an enhanced level of immersion that would boost their coding productivity. When I think of immersion, I think of the main document I'm editing. I want to *feel* the code as I'm writing it... in my ass. So that's where I started:
+
+```ts
+// Vibe on type
+context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(async (e) => {
+ if (config!.get('typingStrength') === 0) { return; }
+ //...
+ const activeEditor = vscode.window.activeTextEditor;
+
+ if (!activeEditor) {
+ return;
+ }
+
+ await selected_device?.vibrate((config!.get('typingStrength') as number) * (config!.get('strength') as number));
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ timeout = setTimeout(async () => await selected_device?.stop(), config!.get('typingDuration') as number * 1000);
+}));
+```
+(The full code for this extension is available [here](https://git.soaos.dev/vscode-buttplug.git/tree/).)
+
+Basically what this snippet does is watches for any edits to the currently open text editor and provides "haptic feedback" for each keystroke.
+I made the strength and duration of these vibrations, along with an overall strength multiplier, configurable by the user.
+
+This on its own would be great, but it isn't enough. This extension needs to be a holistic overhaul of the modern developer experience. And as modern developers, actually writing code takes up such a miniscule amount of our time. Sitting on your ass waiting for your insanely bloated app to build is a much more important activity, and one that is normally very boring. Well, no more:
+
+```ts
+// Vibrate continuously while building
+context.subscriptions.push(vscode.tasks.onDidStartTask(async e => {
+ if (config!.get('buildStrength') === 0) { return; }
+ if (e.execution.task.group === vscode.TaskGroup.Build) {
+ building = true;
+ await selected_device?.vibrate((config!.get('buildStrength') as number) * (config!.get('strength') as number));
+ }
+}));
+
+// Stop vibration once build tasks all finish
+context.subscriptions.push(vscode.tasks.onDidEndTask(async e => {
+ if ((vscode.tasks.taskExecutions).every(t => t.task.group !== vscode.TaskGroup.Build)) {
+ building = false;
+ await selected_device?.stop();
+ }
+}));
+```
+
+The extension obliterates your asshole relentlessly while a build task is in progress (sorry rust devs, although I have a feeling you won't mind). This is extremely useful, since the vibration only stops once all build steps are complete, letting you know it's ok to stop scrolling Instagram reels and get back to work.
+
+That covers the basic functionality of the extension, outside of a few utility commands like a killswitch. If you want to try it out, just download the [intiface central](https://intiface.com/central/) app, install the extension, connect and install your hardware, and godspeed.
\ No newline at end of file
diff --git a/content/heaven/_index.md b/content/heaven/_index.md
new file mode 100644
index 0000000..ce3b970
--- /dev/null
+++ b/content/heaven/_index.md
@@ -0,0 +1,4 @@
++++
+title = "heaven"
+template = "heaven.html"
++++
\ No newline at end of file
diff --git a/content/heaven/angel.gif b/content/heaven/angel.gif
new file mode 100644
index 0000000..1c591e8
Binary files /dev/null and b/content/heaven/angel.gif differ
diff --git a/content/heaven/angel2.gif b/content/heaven/angel2.gif
new file mode 100644
index 0000000..54adc92
Binary files /dev/null and b/content/heaven/angel2.gif differ
diff --git a/content/heaven/angel3.gif b/content/heaven/angel3.gif
new file mode 100644
index 0000000..e6aedcb
Binary files /dev/null and b/content/heaven/angel3.gif differ
diff --git a/content/heaven/bg.jpg b/content/heaven/bg.jpg
new file mode 100644
index 0000000..91a9238
Binary files /dev/null and b/content/heaven/bg.jpg differ
diff --git a/content/heaven/everytime_we_touch_nightcore.ogg b/content/heaven/everytime_we_touch_nightcore.ogg
new file mode 100644
index 0000000..3ac875d
Binary files /dev/null and b/content/heaven/everytime_we_touch_nightcore.ogg differ
diff --git a/content/heaven/heaven.css b/content/heaven/heaven.css
new file mode 100644
index 0000000..5968745
--- /dev/null
+++ b/content/heaven/heaven.css
@@ -0,0 +1,24 @@
+html {
+ background: url("bg.jpg");
+ background-attachment: fixed;
+ background-size: cover;
+ image-rendering: pixelated;
+}
+
+#heavenly-host {
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: -999;
+ background-image: url("angel.gif");
+ background-size: 128px 128px;
+ opacity: 0.25;
+ --pan: 128px -128px;
+ animation: pan linear 3s infinite;
+}
+
+.section {
+ background-color: rgba(from var(--bg-yellow) r g b / 0.5);
+}
diff --git a/content/hell/Flying_Skeleton_Hell.gif b/content/hell/Flying_Skeleton_Hell.gif
new file mode 100644
index 0000000..7cfd429
Binary files /dev/null and b/content/hell/Flying_Skeleton_Hell.gif differ
diff --git a/content/hell/_index.md b/content/hell/_index.md
new file mode 100644
index 0000000..310e63e
--- /dev/null
+++ b/content/hell/_index.md
@@ -0,0 +1,70 @@
++++
+title = "soaos"
+template = "hell.html"
++++
+
+
+
+
+ (please enable autoplay to hear music lol)
+
+
+
+
👿 WELLCOME INTO HELL... YOU SUCKER!!!!! 👿
+
+
+
+
+
+
+
+
+ Hey there pal. It's me haha... the "big" "guy"... AKA satan... I
+ hope you like it here in hell, i worked hard on making it evil :D
+
+
+ idk what you did to wind up here, but now you're stuck here...
+ forever... with me haha ;)
+
+
+ so... Make yourself comfortable... haha if you can lol >:]
+
+
+ AND DON'T EFFING TRY ESCAPING!!! }:[ alright lucifer out
+
diff --git a/content/hell/bg.jpg b/content/hell/bg.jpg
new file mode 100644
index 0000000..8d0fad5
Binary files /dev/null and b/content/hell/bg.jpg differ
diff --git a/content/hell/bigguy.gif b/content/hell/bigguy.gif
new file mode 100644
index 0000000..c3314c7
Binary files /dev/null and b/content/hell/bigguy.gif differ
diff --git a/content/hell/comunismo.gif b/content/hell/comunismo.gif
new file mode 100644
index 0000000..18da593
Binary files /dev/null and b/content/hell/comunismo.gif differ
diff --git a/content/hell/demon.gif b/content/hell/demon.gif
new file mode 100644
index 0000000..a5868d2
Binary files /dev/null and b/content/hell/demon.gif differ
diff --git a/content/hell/demon2.gif b/content/hell/demon2.gif
new file mode 100644
index 0000000..ebbd919
Binary files /dev/null and b/content/hell/demon2.gif differ
diff --git a/content/hell/demon3.gif b/content/hell/demon3.gif
new file mode 100644
index 0000000..fc73814
Binary files /dev/null and b/content/hell/demon3.gif differ
diff --git a/content/hell/demon4.gif b/content/hell/demon4.gif
new file mode 100644
index 0000000..debe626
Binary files /dev/null and b/content/hell/demon4.gif differ
diff --git a/content/hell/demon_face.gif b/content/hell/demon_face.gif
new file mode 100644
index 0000000..5c71e60
Binary files /dev/null and b/content/hell/demon_face.gif differ
diff --git a/content/hell/evilmind.gif b/content/hell/evilmind.gif
new file mode 100644
index 0000000..1b6cb9b
Binary files /dev/null and b/content/hell/evilmind.gif differ
diff --git a/content/hell/evilorb.gif b/content/hell/evilorb.gif
new file mode 100644
index 0000000..003ef97
Binary files /dev/null and b/content/hell/evilorb.gif differ
diff --git a/content/hell/firebreak.gif b/content/hell/firebreak.gif
new file mode 100644
index 0000000..981f1bf
Binary files /dev/null and b/content/hell/firebreak.gif differ
diff --git a/content/hell/gay.gif b/content/hell/gay.gif
new file mode 100644
index 0000000..156bbea
Binary files /dev/null and b/content/hell/gay.gif differ
diff --git a/content/hell/gay2.gif b/content/hell/gay2.gif
new file mode 100644
index 0000000..1a00852
Binary files /dev/null and b/content/hell/gay2.gif differ
diff --git a/content/hell/gaydudes.gif b/content/hell/gaydudes.gif
new file mode 100644
index 0000000..65c4ed3
Binary files /dev/null and b/content/hell/gaydudes.gif differ
diff --git a/content/hell/hell.ogg b/content/hell/hell.ogg
new file mode 100644
index 0000000..0abf641
Binary files /dev/null and b/content/hell/hell.ogg differ
diff --git a/content/hell/hellisreal.gif b/content/hell/hellisreal.gif
new file mode 100644
index 0000000..acbd894
Binary files /dev/null and b/content/hell/hellisreal.gif differ
diff --git a/content/hell/hitler.gif b/content/hell/hitler.gif
new file mode 100644
index 0000000..4edc5d8
Binary files /dev/null and b/content/hell/hitler.gif differ
diff --git a/content/hell/hitler2.gif b/content/hell/hitler2.gif
new file mode 100644
index 0000000..7fd7132
Binary files /dev/null and b/content/hell/hitler2.gif differ
diff --git a/content/hell/hitler3.gif b/content/hell/hitler3.gif
new file mode 100644
index 0000000..8edd36c
Binary files /dev/null and b/content/hell/hitler3.gif differ
diff --git a/content/hell/hot.gif b/content/hell/hot.gif
new file mode 100644
index 0000000..4c1660f
Binary files /dev/null and b/content/hell/hot.gif differ
diff --git a/content/hell/kissing.jpg b/content/hell/kissing.jpg
new file mode 100644
index 0000000..b6190c6
Binary files /dev/null and b/content/hell/kissing.jpg differ
diff --git a/content/hell/obama.gif b/content/hell/obama.gif
new file mode 100644
index 0000000..4f42d27
Binary files /dev/null and b/content/hell/obama.gif differ
diff --git a/content/hell/pitchfork.gif b/content/hell/pitchfork.gif
new file mode 100644
index 0000000..ab880fa
Binary files /dev/null and b/content/hell/pitchfork.gif differ
diff --git a/content/hell/redfire.gif b/content/hell/redfire.gif
new file mode 100644
index 0000000..8f15a7a
Binary files /dev/null and b/content/hell/redfire.gif differ
diff --git a/content/hell/skull.gif b/content/hell/skull.gif
new file mode 100644
index 0000000..89ed718
Binary files /dev/null and b/content/hell/skull.gif differ
diff --git a/content/hell/smallfire.gif b/content/hell/smallfire.gif
new file mode 100644
index 0000000..7b29fdf
Binary files /dev/null and b/content/hell/smallfire.gif differ
diff --git a/content/hell/torch.gif b/content/hell/torch.gif
new file mode 100644
index 0000000..c06066b
Binary files /dev/null and b/content/hell/torch.gif differ
diff --git a/content/projects/bevy_plugins/index.html b/content/projects/bevy_plugins/index.html
new file mode 100644
index 0000000..5f5c427
--- /dev/null
+++ b/content/projects/bevy_plugins/index.html
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/content/projects/games/NIX_AVREA/index.html b/content/projects/games/NIX_AVREA/index.html
new file mode 100644
index 0000000..47c914b
--- /dev/null
+++ b/content/projects/games/NIX_AVREA/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ NIX AVREA
+
+
+
+ Go Home
+ Go Back
+
NIX AVREA
+
This is a project I've been working on since April 2024. It's probably the longest-running personal project I've ever done and has been a monumental undertaking so far.
+
I'm unsure how much I want to reveal about this project while I'm developing it, I want the experience to be as novel as possible once it's out. I think I'll probably stick to posting about it here on my site and the occasional YouTube video until it's closer to ready.
+
About the Project
+
NIX AVREA is the codename for my first game project. The game is highly experimental and features mechanics that (as far as I know) have never been attempted. The game is centered around dynamic content, using steganographic techniques to embed binary payloads inside of asset files in order to construct the game world from a directory on the player's filesystem.
+
There is a ton of stuff that's already implemented for this project and I'll gradually add more to the following directories explaining in-depth some of the components:
+
+
+
\ No newline at end of file
diff --git a/content/projects/piss_daemon/index.html b/content/projects/piss_daemon/index.html
new file mode 100644
index 0000000..5cb9481
--- /dev/null
+++ b/content/projects/piss_daemon/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+ Piss Daemon - soaos
+
+
+
+ Go Home
+ Go Back
+
Piss Daemon
+
About
+
This is a D-Bus daemon (pissd) and client (piss-level) that monitor the international
+ space station's urine tank level.
+
I have it integrated into my status bar (X version):
+
+
+ #...
+
+ function piss {
+ PISS_LEVEL="$(piss-level)";
+ if [ -n "$PISS_LEVEL" ]; then
+ echo " ${PISS_LEVEL}%";
+ fi;
+ }
+
+ #...
+
+ while true; do
+ xsetroot -name "$(piss)$(batt)$(datetime)";
+ sleep 1;
+ done;
+
+
I made this pretty much entirely so that I could call a program "piss daemon".
This page shows a bunch of information about the music I've been listening to on my mp3 player. Think of it kind of like my own personal Spotify wrapped, minus the antichrist.
+
This page is updated wehenever I feel like regenerating it.
+
+
Playback History
+
Total playtime: 7:57:48, 117 tracks
+
+
+
+
+
Timestamp
+
Played Duration
+
Title
+
Artists
+
Album
+
Genre
+
+
+
+
+
2025-09-23 19:41:01
+
3:37
+
The Misty Veil of May
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:37:24
+
2:26
+
An Old Owl Calling
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:34:58
+
3:03
+
Night in a Mossy Hut
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:31:55
+
2:31
+
Crying Wind
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:29:23
+
3:05
+
Dawn
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:26:17
+
3:27
+
Hidden Valley
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:22:50
+
3:32
+
The Gathering of Deer
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:19:17
+
3:49
+
A Wild River to Take You Home
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 19:15:22
+
3:16
+
A Wild River to Take You Home
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-23 16:05:05
+
2:49
+
Twin Fantasy (Those Boys)
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:52:11
+
16:10
+
Famous Prophets (Stars)
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:36:01
+
7:39
+
High to Death
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:28:22
+
5:39
+
Cute Thing
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:22:42
+
6:46
+
Bodys
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:15:55
+
5:25
+
Nervous Young Inhumans
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:10:30
+
5:04
+
Sober to Death
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:05:25
+
1:29
+
Stop Smoking (We Love You)
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 15:03:56
+
13:18
+
Beach Life‐in‐Death
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 14:50:37
+
2:52
+
My Boy (Twin Fantasy)
+
[Car Seat Headrest]
+
Twin Fantasy
+
Alternative
+
+
+
2025-09-23 14:47:44
+
1:32
+
The Light & the Glass
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:46:12
+
3:54
+
A Favor House Atlantic
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:42:18
+
4:15
+
The Camper Velourium III: Al the Killer
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:38:02
+
5:22
+
The Camper Velourium II: Backend of Forever
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:32:40
+
5:21
+
The Camper Velourium I: Faint of Hearts
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:27:18
+
4:05
+
Blood Red Summer
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:23:13
+
6:35
+
The Crowing
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:16:37
+
5:08
+
Three Evils (Embodied in Love and Shadow)
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:11:29
+
5:00
+
Cuts Marked in the March of Men
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 14:06:28
+
8:12
+
In Keeping Secrets of Silent Earth: 3
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 13:49:39
+
2:07
+
The Ring in Return
+
[Coheed and Cambria]
+
In Keeping Secrets of Silent Earth: 3
+
Progressive Rock
+
+
+
2025-09-23 13:45:29
+
5:45
+
Life and Death
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:39:43
+
3:25
+
Father
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:36:17
+
2:16
+
Son
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:34:01
+
3:15
+
Go Get Your Gun
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:30:45
+
4:05
+
This Beautiful Life
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:26:40
+
3:39
+
He Said He Had a Story
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:23:01
+
4:41
+
Saved
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:18:19
+
4:13
+
Mustard Gas
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:14:06
+
5:01
+
The Thief
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:09:05
+
4:51
+
The Poison Woman
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 13:04:13
+
4:39
+
The Tank
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 12:59:34
+
4:49
+
What It Means to Be Alone
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 12:54:44
+
5:29
+
In Cauda Venenum
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 12:49:15
+
1:38
+
Writing on a Wall
+
[The Dear Hunter]
+
Act III: Life and Death
+
Progressive Rock
+
+
+
2025-09-23 12:47:36
+
7:09
+
Vital Vessels Vindicate
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:40:27
+
4:13
+
Black Sandy Beaches
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:36:13
+
4:28
+
Dear Ms. Leading
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:31:45
+
4:29
+
Where the Road Parts
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:27:15
+
6:07
+
Red Hands
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:22:05
+
1:13
+
Red Hands
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:15:59
+
3:48
+
Blood of the Rose
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:12:10
+
3:44
+
Evicted
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:08:26
+
4:45
+
Smiling Swine
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 12:03:40
+
7:46
+
The Bitter Suite III: Embrace
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:55:54
+
6:06
+
The Bitter Suite I & II: Meeting Ms. Leading / Through the Dime
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:49:47
+
4:57
+
The Church & the Dime
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:44:49
+
4:18
+
The Oracles on the Delphi Express
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:40:31
+
9:29
+
The Lake and the River
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:35:12
+
4:25
+
The Lake and the River
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:33:31
+
2:44
+
The Lake and the River
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:30:47
+
4:59
+
The Procession
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:25:57
+
0:38
+
The Death and the Berth
+
[The Dear Hunter]
+
Act II: The Meaning of, & All Things Regarding Ms. Leading
+
Progressive Rock
+
+
+
2025-09-23 11:24:06
+
4:03
+
The River North
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 11:20:03
+
6:00
+
His Hands Matched His Tongue
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 11:14:02
+
6:00
+
The Pimp and the Priest
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 11:08:02
+
7:02
+
1878
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 11:01:00
+
5:56
+
The Inquiry of Ms. Terri
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 10:55:03
+
5:56
+
City Escape
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 10:49:07
+
1:43
+
The Lake South
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 10:47:23
+
1:55
+
Battesimo del fuoco
+
[The Dear Hunter]
+
Act I: The Lake South, the River North
+
Progressive Rock
+
+
+
2025-09-23 10:44:36
+
4:24
+
Chapter X
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:40:12
+
3:32
+
Chapter IX
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:36:39
+
3:39
+
Chapter VIII
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:33:00
+
6:08
+
Chapter VII
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:26:51
+
3:45
+
Chapter VI
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:23:06
+
3:39
+
Chapter V
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:19:27
+
3:24
+
Chapter IV
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:16:02
+
4:24
+
Chapter III
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:11:37
+
2:28
+
Chapter II
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-23 10:09:09
+
1:23
+
Chapter I
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-21 19:50:53
+
12:26
+
Sleep
+
[Godspeed You Black Emperor!]
+
Lift Your Skinny Fists Like Antennas to Heaven
+
Post-Rock
+
+
+
2025-09-21 19:50:18
+
3:27
+
A Wild River to Take You Home
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-21 19:45:18
+
1:28
+
A Wild River to Take You Home
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-21 19:43:49
+
0:28
+
A Wild River to Take You Home
+
[Black Hill & Silent Island]
+
Tales of the Night Forest
+
Post-Rock
+
+
+
2025-09-21 19:40:11
+
0:48
+
Night Ela (Mystic Thing)
+
[Candy Claws]
+
Ceres & Calypso in the Deep Time
+
Shoegaze
+
+
+
2025-09-21 19:28:37
+
1:28
+
Night Ela (Mystic Thing)
+
[Candy Claws]
+
Ceres & Calypso in the Deep Time
+
Shoegaze
+
+
+
2025-09-21 19:26:40
+
0:42
+
The Tragedy
+
[The Pax Cecilia]
+
Blessed Are the Bonds
+
Post-Metal
+
+
+
2025-09-21 19:25:58
+
5:01
+
A Dance With Death
+
[We Lost the Sea]
+
A Single Flower
+
Post-Rock
+
+
+
2025-09-21 19:25:00
+
3:26
+
Homecoming: Denied!
+
[Harakiri for the Sky]
+
Aokigahara MMXXII
+
Post-Metal
+
+
+
2025-09-21 19:21:33
+
1:18
+
Keeping the Blade
+
[Coheed and Cambria]
+
Good Apollo I’m Burning Star IV, Volume One: From Fear Through the Eyes of Madness
+
Progressive Rock
+
+
+
2025-09-21 19:20:14
+
1:47
+
I Existed
+
[Snooze]
+
I Know How You Will Die
+
Progressive Metal
+
+
+
2025-09-21 19:14:22
+
7:40
+
Robinson
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 19:06:42
+
3:35
+
October
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 19:03:07
+
10:21
+
Old George
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:52:45
+
9:34
+
867
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:43:11
+
3:38
+
Two-Headed Calf
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:39:33
+
6:25
+
7Bass / Lorne
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:33:07
+
9:51
+
January
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:23:15
+
3:39
+
Southpaw
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:19:36
+
8:37
+
Before Machinery
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:10:58
+
5:36
+
Streetlight by Streetlight
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 18:05:21
+
0:17
+
Streetlight by Streetlight
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 15:00:22
+
0:02
+
Before Machinery
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 15:00:12
+
5:36
+
Streetlight by Streetlight
+
[This Is The Glasshouse]
+
867
+
Progressive Rock
+
+
+
2025-09-21 02:29:43
+
0:24
+
The Diary of Jane
+
[Breaking Benjamin]
+
Phobia
+
Rock
+
+
+
2025-09-21 02:29:20
+
1:13
+
Intro
+
[Breaking Benjamin]
+
Phobia
+
Rock
+
+
+
2025-09-21 01:23:28
+
2:00
+
The Diary of Jane
+
[Breaking Benjamin]
+
Phobia
+
Rock
+
+
+
2025-09-20 19:51:54
+
0:05
+
Chapter X
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:41
+
0:01
+
Chapter IX
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:39
+
0:01
+
Chapter VIII
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:38
+
0:01
+
Chapter VII
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:36
+
0:01
+
Chapter VI
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:35
+
0:01
+
Chapter V
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:33
+
0:01
+
Chapter IV
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:32
+
0:01
+
Chapter III
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:30
+
0:01
+
Chapter II
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
2025-09-20 19:51:29
+
0:02
+
Chapter I
+
[Sufferer]
+
Sufferer
+
Post-Hardcore
+
+
+
+
+
+
+
+
Top Genres
+
+
+
+
+
+
+
Progressive Rock: 5:09:49 (64.8%)
+
+
Alternative: 1:07:16 (14.1%)
+
+
Post-Rock: 51:41 (10.8%)
+
+
Post-Hardcore: 37:09 (7.8%)
+
+
Post-Metal: 4:09 (0.9%)
+
+
Rock: 3:39 (0.8%)
+
+
Shoegaze: 2:17 (0.5%)
+
+
Progressive Metal: 1:47 (0.4%)
+
+
+
+
+
+
Top Albums
+
+
+
+
+ 🖸 Act II: The Meaning of, & All Things Regarding Ms. Leading
+ 👤 The Dear Hunter
+ ⏱ 1:25:26
+
+
+
+
+
+
+ 🖸 867
+ 🫏 This Is The Glasshouse
+ ⏱ 1:14:56
+
+
+
+
+
+
+ 🖸 Twin Fantasy
+ 👤 Car Seat Headrest
+ ⏱ 1:07:16
+
+
+
+
+
+
+ 🖸 Act III: Life and Death
+ 👤 The Dear Hunter
+ ⏱ 57:51
+
+
+
+
+
+
+ 🖸 In Keeping Secrets of Silent Earth: 3
+ 👤 Coheed and Cambria
+ ⏱ 51:36
+
+
+
+
+
+
+ 🖸 Act I: The Lake South, the River North
+ 👤 The Dear Hunter
+ ⏱ 38:38
+
+
+
+
+
+
+ 🖸 Sufferer
+ 👤 Sufferer
+ ⏱ 37:09
+
+
+
+
+
+
+ 🖸 Tales of the Night Forest
+ 👤 Black Hill & Silent Island
+ ⏱ 34:13
+
+
+
+
+
+
+ 🖸 Lift Your Skinny Fists Like Antennas to Heaven
+ 👤 Godspeed You! Black Emperor
+ ⏱ 12:26
+
+
+
+
+
+
+ 🖸 A Single Flower
+ 👤 We Lost the Sea
+ ⏱ 5:01
+
+ Welcome to my blog! This is where I'll post longer content about stuff I'm
+ working on. I'm working out some channels for posting day-to-day short
+ form shit too so keep an eye out for that.
+
+
Latest Posts
+
+
+ {% for year, posts in section.pages | group_by(attribute="year") %}
+
\ No newline at end of file
diff --git a/templates/shortcodes/title_bar.html b/templates/shortcodes/title_bar.html
new file mode 100644
index 0000000..facc6fb
--- /dev/null
+++ b/templates/shortcodes/title_bar.html
@@ -0,0 +1,8 @@
+
+
{{ body | safe }}
+
+ {% if close %}
+
+ {% endif %}
+
+
diff --git a/templates/shortcodes/tree_view.html b/templates/shortcodes/tree_view.html
new file mode 100644
index 0000000..e8de782
--- /dev/null
+++ b/templates/shortcodes/tree_view.html
@@ -0,0 +1,5 @@
+
+
+ {{ body | markdown | safe }}
+
+
diff --git a/templates/shortcodes/treelink.html b/templates/shortcodes/treelink.html
new file mode 100644
index 0000000..ff80fdc
--- /dev/null
+++ b/templates/shortcodes/treelink.html
@@ -0,0 +1,8 @@
+
+ {{ text }}
+ {% if wip %}
+
+ ⚠
+
+ {% endif %}
+
\ No newline at end of file
diff --git a/templates/shortcodes/window.html b/templates/shortcodes/window.html
new file mode 100644
index 0000000..8abddbe
--- /dev/null
+++ b/templates/shortcodes/window.html
@@ -0,0 +1,3 @@
+
+{{ body | safe }}
+
diff --git a/templates/shortcodes/window_body.html b/templates/shortcodes/window_body.html
new file mode 100644
index 0000000..f7c84a7
--- /dev/null
+++ b/templates/shortcodes/window_body.html
@@ -0,0 +1 @@
+