Can ChatGPT Give Good Recommendations?

I listen to a lot of music, and I listen to a lot of types of music. About once per year I go on a mission to find new music to add to my regular rotation. I don’t want to listen to the same albums forever, or the same genres; there’s a vast ocean of music out there and it would be criminal to just get comfortable and never explore its depths.

There’s usually two ways to go about this: active search and passive listening.

You can find music blogs, critics, etc., and listen to what’s popular. The problem here, I’ve found, is that no matter the genre music critics tend to gravitate toward “music critic music”. This is music that tends to be less listenable and more interesting. It’s stuff you can appreciate, like a good scotch or wine, but not something you’d like every day.

Then there’s the Algorithm, which is invariably awful. Spotify’s Discover Weekly long ago gave up on trying to be useful and instead regularly recommends artists I whose songs are already in my playlists and regular rotation, or genre classics whose names are so well-known if you were to try recommending them to a person in real life, that person would no longer take you seriously. For example, last week it pushed Fleetwood Mac, and this week it’s pushing Nine Inch Nails.1

My tastes are not particularly esoteric — and I have the data to prove it. Since 2006, I’ve scrobbled over 330,000 tracks from over 16,000 artists. And an embarrassing percentage of those are just Pink Floyd, Vangelis, and Nobuo Uematsu.

A screenshot of my top artists at Last.fm, including Pink Floyd, Vangelis, Nobuo Uematsu, Sting, and Queensryche.

I mean, does this look hard to quantify?

The Problem is… It’s Hard

Someone once said, “Writing about music is like dancing about architecture.” And it turns out, almost every other way to describe or quantify music is also ridiculously hard. This is another thing that makes music publications difficult to use as sources for new music. It’s already difficult to put into words why you like a thing, and when it comes to music, it’s easier to just describe how it makes you feel more than what it sounds like. So you’re left hunting down critics whose taste is identifiably similar to yours, or magazines that cover genres you like. Something I have neither the time or energy to do.

I thought software could have been better at this. Even Spotify’s alleged approach to recommendations, which is to find adjacent users and playlists, sounds like it should work well! Even without or before their perverse incentives reared their ugly heads2, this never worked as well as it could have. It’s hard for an algorithm to reliably learn that “I like this artist’s late work more than their early work,” for example.3 The “dream” of some omniscient Service adjusting to your habits and feeding you new things to love has rotted away thanks to adtech infesting every corner of our modern world.

The only software-focused approach I’ve ever seen that worked even remotely well was the Music Genome Project. Pandora knocked this so far out of the park no one ever hoped to come close, and they continually rule when it comes to putting together radio stations that adapt to your listening habits over time. It does seem like it’s gotten a little worse over the years, but I don’t have any data to back that up, just vibes. In any case, it’s maybe-deteriorated quality is still leagues ahead of any other streaming service.

Enter ChatGPT

Let me get this out of the way: LLMs are not for the production of anything of value. Even as dumb tools they tend to be about as useful as autocomplete. If I’m on a company website and see that they use AI “art” even for splash images, I make a note not to interact with or give money in any way to those companies. What’s more, the techbro inclination to disregard or belittle the arts so much as to try and automate them away with fancy Markov chains shows only how bereft these people are in imagination, in spirit, and in character.

That said, LLMs do have a use. And what better use, as a souped-up autocomplete, than a recommendation engine?

As it turns out… not very useful.

The Process

Using ChatGPT 4o, I uploaded a CSV containing all 330,000+ scrobbles from my Last.fm history along with a prompt to give me some recommendations based on that history.

Naturally, it also took many steps to refine the output.

The Bad

We all know LLMs are prone to hallucinations. Even after repeatedly correcting them, they will confidently proclaim some bullshit as truth. This is no less true here. Despite clear instructions in the prompt, the very first round of recommendations consisted only of music from the input data. The second round of recommendations was 75% artists that appeared in the input data.

I thought perhaps my approach was too wide — asking it to categorize 18 years of listening history might have been too much. So I tried to hone in on specific genres instead. Of course, ChatGPT failed this, too. It continued insisting that Vangelis was a Synthwave artist, for example.

In fact, it repeatedly failed basic statistical analysis. When asked about my most recent 12 months of listening history, it made up numbers and statistics, easily verified by just looking at my Last.fm account.

Despite continuous fiddling, multiple passes at trying to iron down a good prompt, and troves of data, ChatGPT could do no better than tell me things I already knew.

The Good

I decided to get more specific. Instead of trying to base recommendations on hard numbers, I went back to the vibes approach.

Thinking back on how Spotify described its recommendation engine, I decided to tell ChatGPT about groups of artists and specific playlists, describing what I like about a particular grouping. Then it would respond with a handful of new recommendations based on that input, which I put into a table where I could mark down my progress working through the list, along with my thoughts.

Out of ~40 albums recommended from these responses, I’ve listened now to about 20. Of those 20, I ended up rating 6 at 7/10 or above on first pass. That’s really not bad at all! A much higher percentage of hits compared to, say, perusing Pitchfork or Sputnik Music’s recent top lists.

Of course, for a handful of recommendations I could not tell if the albums suggested actually exist. If they do, they’re not on the streaming services I can use.

It sounds nice and easy when I describe it like this. But for the amount of time it took to get these responses, I could probably have gotten the same results myself by looking at the Similar Artists tab in Last.fm or any other streaming service. The output, while generally decent, is not novel, and in fact produced quite a few names I’ve already seen but just never got around to listening to.

Final Thoughts

What a wild and wonderful time to be alive. Out of the ether I pulled over 40 album recommendations and they are all immediately available at my fingertips for next to nothing. There is more to see and hear and experience than can ever be seen or heard or done in a hundred lifetimes. And it’s all so good. There’s so many specific subgenres of music that you can sink into any one and only come up for air a year later. You like pirate metal? You like new retro wave that pretends to be what 80s pop would be if it had kept on going for 30 years? You like broken hard drive techno? It’s out there!

At the same time, the flagship product of the company behind the biggest bubble in the history of any economy fails such basic tasks as “count how many times I listened to a specific artist in the past year, based on the data in this CSV.” This is supposed to be the thing that drives decision-making, summarizing, and producing “art”? This is the thing that movie studios are using to screen and write screenplays? This is the thing that our tech industry is scrabbling over itself to inject into every open orifice of their already over-bloated product offerings? Absolutely embarrassing, for everyone involved.

At the end of the day nothing beats a good recommendation from someone you know. Whether it’s a critic you follow and trust, a friend, or a barista at your local coffee shop, these people understand and at least grasp at the intangible qualities of music and what makes it grab a hold of you. There are ways in which two artists, albums, or songs are similar that no computer could hope to quantify.

Winamp Source Code is Now “Open”

Source is available on GitHub, with some atrocious terms and conditions:

You waive any rights to claim authorship of the contributions or to object to any distortion, mutilation, or other modifications of the contributions.

You may not create, maintain, or distribute a forked version of the software.

But they “encourage” contributions!

When I heard about this I was, momentarily, excited. But of course it seems the company that got its hands on the product either don’t understand what they have or are incapable of properly handling it.

I’ve been using Winamp for decades now, which is a weird thing to say because I don’t consider myself old (yet). I still have Winamp 2.95 installed on my current PC and use it pretty much daily because nothing else, even today, comes close to the user experience.1 That’s not to say it’s perfect, but it fits my needs.

For reasons, today’s news inspired me to finally try Wacup. A fan project inspired by Winamp, built around a plugin system, designed to essentially take the best of Winamp and bring it fully into the 21st Century. With proper scaling and high-DPI support, built-in FLAC support, and more, it brings in lots of quality-of-life features without sacrificing any of the things that made Winamp special.

They can even look the same! Top: Wacup. Bottom: Winamp.

Wacup even comes with a faithfully-recreated Classic skin for codgers like me who like that aesthetic. I’m still tinkering with some of the font settings and might go for a different skin in the end, but I think as long as it stays stable and light on the memory footprint, it’s going to be here to stay. 10/10, highly recommend.

Writing Advice Sucks, Here’s Some Writing Advice

The internet is full of bad advice. Probably the only place more full of it than the get-rich-quick corner is the writers’ corner.

For a long, long time I struggled when it came to coming up with good, believable characters. I thought I had a handle on things other than that, having spent unbelievable amounts of time on things like world building and outlining. But when I finally put pen to paper and charged forward I inevitably ground to a halt ten, twenty, even forty thousand words later.

Why? Because I did not understand what purpose my characters played in the story, my narratives became aimless, airless. I did not grasp the interconnectedness of character and plot, how one drives the other. How one fashions the other.

But it wasn’t a long time until I understood how, exactly, to construct a character. How to weave a narrative from a character’s flaws, drive the plot based on questions and answers, or thesis/antithesis/synthesis. Sure, you can craft a gripping two-dimensional plot based purely on external motivations, but the impactful drama is derived from character and idea, and how the character embodies or probes that idea.

I’m not going to add my own to the ocean of bad advice out there. I come citing sources. But first, what doesn’t work.

Ditch the Questionnaires

Questionnaires are a waste of time. Your story will not be richer for you knowing a character’s favorite color, or what’s in their fridge. You will know when it’s important because it will have a direct, tangible impact on plot. Otherwise, a questionnaire only helps you procrastinate even more.

Don’t interview your character. Don’t answer 150 questions about family history, favorites, least favorites. Leave everything until the last second, because when it matters, you will know.

There should only ever be one question you ask: What is your character’s primary definition of herself? Or, if you’re asking them: “Who are you?” The answer to that question is going to be however they identify most strongly, the thing to which they have attached most value.

Before we Continue…

If you don’t want to read the random thoughts of a stranger on the internet, just read these instead and then close this tab:

If a book on craft starts to get prescriptive (as in, add the Inciting Incident by Page xx, and the Turning Point by Page yy), then politely close the book, find the nearest recycling bin, keep walking, and toss the book in the nearest fire instead.

The Character is a Robot

Ursula K. Le Guin wrote, “The machine doesn’t work unless the parts do.”

Robert J. Sawyer writes:

Real people are quite accidental, the result of a random jumbling of genes and a chaotic life. But story people are made to order to do a specific job. In other words, robots!

I can hear some of you pooh-poohing this notion, but it’s not my idea. It goes back twenty-five hundred years to the classical playwrights. In Greek tragedy, the main character was always specifically designed to fit the particular plot. Indeed, each protagonist was constructed with an intrinsic hamartia, or tragic flaw, keyed directly to the story’s theme.

(Read the rest of the article; it’s very good!)

In a well-fashioned story, the character and plot are so closely intertwined that one cannot exist without the other. The character exists for the plot, and vice versa. The best way to accomplish this is to start with one and then reverse-engineer based on the needs of the other. Got a cool theme, setting, or idea? Great! Make a character who suits it, whose virtues and flaws are complemented by it, who will grow because of it. Or, got a cool character? Great! What can we do to really put this person through the ringer, upset their worldview, help them become a more fully-realized and integrated person?

Build a plot that challenges the character, one which may be triggered by an extrinsic motivation. Your character sets out into the world to achieve a thing they want. But the world should not affirm their prejudices or reinforce their worldviews. It should surprise them, it should confront them with that thing they fear most, that one thing that is stopping them from being whole.

How the character reacts to this, and the events that unfold, are what can make a journey heroic or tragic. A character’s virtues can become darkly inverted and lead to their downfall. Or, they overcome their flaws and rise to the occasion, triumphing over the thing that had always held them back.

That’s all easier said than done, of course.

Questions and Answers

If a character is wary of commitment, then the crisis will force them to face losing someone they love (Casablanca); if a character is selfish, they are brought face to face with what they might lose by being so (Toy Story); if a character is timid then they will have to face up to what timidity might cost

John Yorke, Into the Woods: A Five-Act Journey Into Story

When you have a character but struggle with plot, it’s time to fight dirty. John Yorke in Into the Woods discusses the fractal quality that narratives have. Each part of the story should contain all the necessary elements of the whole story: protagonist, antagonist, inciting incident, journey, crisis, climax, and occasionally resolution.

To put it simpler, in each chapter or even each scene, ask: what are the worst possible consequences of this decision? What happens if the character doesn’t want to change? Then, make that happen, over and over. And this works everywhere!

(It’s at this point that knowing trivia about your character might be useful. But only insofar as it can be used to drive the character to a crisis point. Otherwise, it remains trivia and is to be discarded accordingly.)

Thesis / Antithesis / Synthesis

The dialectic pattern — thesis / antithesis / synthesis — is at the heart of the way we perceive the world; and it’s a really useful way to look at structure.

A character is flawed, an inciting incident throws them into a world that represents everything they are not, and in the darkness of that forest, old and new integrate to achieve a balance.

John Yorke, Into the Woods: A Five-Act Journey Into Story

Sounds a little Jungian, doesn’t it? Assimilate the shadow to achieve an integrated self. If we want to keep playing fast and loose with definitions it can also be likened to the id / ego / superego.

The point is that good characters tend to be defined by their flaws more than their virtues. Because the conflict is driven by these flaws. Although they might not set out to do so at first, characters inevitably fight more against their weaknesses than any external foe. In lots of stories today, this tends to get masked by the fact that the antagonist tends to be the embodiment of that flaw, weakness, or fear.

Often, what a character initially believes to be a quality becomes the very obstacle they need to overcome in order to achieve their ultimate goal. They’ll need to turn to something they initially perceive to be a weakness in order to obtain whatever it is they need.

In a three-act structure this might look like this:2

  • Introduce a flawed character
  • Confront them with their opposite
  • Integrate the two to achieve balance

Why Any of This Matters

Wherever the poetry of myth is interpreted as biography, history, or science, it is killed.

Through the wonder tales, symbolic expression is given to the unconscious desires, fears, and tensions that underlie the conscious patterns of human behavior.

Joseph Campbell, The Hero with a Thousand Faces

It is absolutely possible to write a story without any of this. The story can even be entertaining, enjoyable, make tons of money.

Nothing lasts that does not have these qualities. One- and two-dimensional stories have their place as popcorn, but they do not nourish us. They do not make us feel less alone, make us ask or ask us, “You, too?” They tell us nothing about ourselves that we do not already know. And since we are not rocks, we need sustenance. Substance.

Otherwise, why are we here?

Alien: Romulus

I’ve written before about the creative bankruptcy that fuels the Disney engine. Whether driven by cynicism or fear, it’s become clear the Disney won’t let any of its properties stand on their own legs. Instead, they need to be propped up by references, homages, allusions, self-awareness, or multiverses.

I grew up watching and loving the Alien movies, and have always enjoyed the installments that tried something new. A franchise doesn’t need to be a formula. It can be a framework. I was really looking forward to Alien: Romulus, despite all my instincts warning me to temper my expectations instincts I should have listened to.

Spoilers ahead1, so reader beware.

Continue reading

Recent Movies, TV, and Other Media

A non-exhaustive list of notable media (movies, TV, books, music, etc.) that I’ve watched, read, listened to, or otherwise ingested.

Movies

  • Longlegs (2024) – Dripping with dread, this movie lingered with me on the drive home. Bleak, slow, with some delightful spooks, but ultimately empty and lacking substance. I really liked this leaving the theater, but it soured over time still, there are some stretches in here that are top-notch compared to its contemporaries.
  • Late Night With the Devil (2023) – Overall a decent descent into madness. A late night talk show host on the outs accidentally brings the devil on air. What’s not to like about that premise? Unfortunately, the production team decided to use AI for a few interstitial images instead of, you know, paying a real artist to make real pictures. Especially insulting after sitting through what felt like 10 entire minutes of production logos at the movie’s opening.
  • The Player (1992) – Very noirish. A man, fearing his own demise, sets out to escape his fate meanwhile blundering right into that very same fate. The ending is so cynical, so biting, it retroactively made what was still a very enjoyable movie into something else entirely. It was fun to watch a movie about people who make movies, and feeling their love for The Movies bleeding through every frame.
  • Nowhere (1997) – I can’t really describe this, except for stealing the byline: 90210 on acid. Wild, queer, colorful, anarchic, angsty, surreal. It took a second to click, but once it did, I was locked in for every minute.

TV

  • Preacher (2016) – Based on a comic book series, a criminal-turned-preacher gets an extraordinary power and stumbles onto a world of vampires, crypto-fascist organizations, angels, the Saint of Killers, and a Hitler escaped from Hell. Among other things. I really liked the first season, which was all about people fighting with themselves to be better people. Can you change your nature? Is it even worth the struggle? In subsequent seasons this fell to the wayside in favor of plot-heavy storytelling, which was still fun, just less so.

Books

  • Night Work (by Thomas Glavinic) – A man wakes up one morning and finds he’s the last person on earth. Scratch that, last living animal. No birds, no dogs, not even any insects. There’s a dread that suffuses the first hundred or so pages that I won’t forget. While I appreciate the direction the rest of the book took, it wasn’t entirely for me, but I understand it’s partially my own expectations dragging me down. I wanted a little more of the surreal, weird, spookiness that was promised and hinted at in the beginning.
  • Unconditional Parenting (by Alfie Kohn) – While I am generally not entirely supportive of “gentle parenting” for nebulous reasons I won’t get into here, I still found a lot of wisdom in this book. It communicates clearly how to get across to a person (not just your children!) that your love for them is unconditional, and how to make a relationship feel less transactional in the process. And I’m all for any modern book that pushes parents to improve (as people and as parents), be more self-reflective, and foster healthy attachment with their offspring.
  • Worm (by Wildbow) – I’m not even remotely finished with this. It’s long. 7,000 pages long. That’s 1.6 million words long. But the chapters are in neat, popcorn-sized bites, easy to chew through in those random stretches of day when I don’t want to watch something but still have some time to kill.

Music

  • The Menzingers – On the Impossible Past (2012) – This has slowly transformed into a no-skip album for me. Nostalgic, but not pining. It’s not just about who we were, but who we could have been.
  • The DSM IV – New Age Paranoia (2024) – Retro sound, new age angst. Synthy, sometimes operatic, gloomy and gothy. Definitely not for every mood but still a good listen.

WebP Rules

This is a PNG.

This is a WebP.

One of these images is a PNG, and one is a WebP. The PNG is 12KB, and the WebP is 5KB. Do you see a difference between the two?

Me, neither.

I’ve been a steadfast PNG supporter since time immemorial. Cringing at any sight of JPEG compression. Way back in the way when forums were still big, and users spent inordinate amounts of time creating cool-looking signature images, I was big into PNGs. I prided myself on every aspect of my little 300×100 pixel PNG box. But mostly the crisp lines and vibrant colors.

When creating images for a site, I’d typically use (old-school) Photoshops ‘optimize for web’ feature for PNGs. This did a pretty decent job at compressing my PNGs to reasonable sizes.

But, nothing ever gave me such a boost as a WebP. Even for large images full of color, I can still drop a picture from 1.2MB to 680KB, while maintaining the same visible quality! That’s insane!

One of these days when I have more time and energy I’m going to read some more specs on how this works, but until then, I’m just going to go on living like it’s pure magic and my days will be a little brighter for it.

On Writing Imperfectly

For a very long time I was a perfectionist, obsessed with doing things the Right Way. Whenever I would undertake some new task, I would frontload all my work with research. How do smarter people do this? What is the generally-agreed-upon best practice for this sort of thing? How do I make sure in some mythical future state of this project, I won’t hate my Present Day Self for laying shoddy groundwork?

In a professional context, this is not really a bad way to approach things. I’ve saved myself a lot of headaches by learning from really smart people and doing lots of long, hard Thinking before I set about big projects.

One thing that took me too long to learn, though, is that this is a wonderful way to kill hobbies.

The Tyranny of the Right Way

I have a graveyard of drafts for stories, novels, and blog posts. Some of them are impeccably outlined and structured; most are pretty much empty, forsaken for the absurdly long notepad where all the “research” went. All lie dead, unposted, unpublished.

Sometimes I would fizzle out and lose motivation halfway through. Other times, I would make good progress, then stop and think, “Does this really need to be said? Am I the right person to say this? Is it worth writing at all?” Usually, the answer to one of those questions would be a resounding No, and I’d move on.

Most of the time, however, I got lost in trying to perfect what I was doing. Outlining, structuring, plotting and planning. There would be times I’d sit at my screen for tens of minutes, trying to think of the right word when Good Enough would have done.

That’s the thing with writing. You read it often enough, but sometimes it takes multiple failures and years of writer’s block before you can actually internalize it.

It doesn’t have to be good, it just has to be done.

Let it be shit. Let it flow, use placeholders, skip sentences or sections or entire chapters. Whatever it takes to keep writing.

Once I managed to keep this mindset front and center, I was able to really get stuff done. I went from two whole years of minimal writing to… checking notes… 66,599 words written so far this year. Sure it’s not a ton compared to others, but I’m running laps around my Last Year’s Self.1

That brings up another issue I struggled with…

The Tyranny of Statistics

A line chart showing a rising wordcount throughout the year, with a plateau in the middle of the year.

A chart showing my writing progress for the year.

For six years now, I’ve kept track of how many words I’ve written every single day. Each entry is assigned a project, which is the novel, story, or other thing (like a blog) I wrote for. Each entry also has a target word count, which I typically set at the beginning of the year or project, which I aim to hit each time I write. For some years, I even kept notes on reasons behind long gaps, but I long ago dropped this practice.

This was inspired by something I read about someone who kept a desktop calendar and crossed out each day he worked on his big thing. It was his major motivation: he didn’t want to lose that streak. I thought, “Wow, that’s a great idea! I’m doing that right now.”

But I didn’t think it entirely through. Like any big lifestyle change — diet, exercise, a new sleep schedule — I didn’t realize that jumping right in would inevitably lead to failure. It’s all about increments. Instantly, I’d internalized that if Line Go Up means Success, then a missed day was an automatic Failure. And that was more demotivating than the motivation I got from Line Go Up.

This semi-unhealthy obsession with metrics eventually invaded a lot of other parts of my life. From tracking the movies I watched to the music I listened to, to all sorts of other things, I wasted so much time and effort in an attempt to quantify my life without thinking about the reasons why. But that’s another blog post.

It took burnout to give up really caring about Line Go Up. In between starting this and burning out, I even wrote not one, not two, but three different applications using three different tech stacks in order to do this “novel project management.” Talk about procrastination.

I ended up wanting to see more and more words written without caring about the quality of the words. Until I missed too many days in a row and just quit. I attributed my lack of motivation to a lot of things, but this obsession with metrics was one of the larger factors.

Eventually I came back to it. I started writing again, and yes, I still tracked my word count. My reasoning is different now, though: I just think it’s neat. If I miss a day, it’s no big deal. If I miss my target, whatever. There’s always tomorrow. And a lot of my writing doesn’t go in the spreadsheet.

What matters more than words written is forward momentum. I can sit an stare at my screen without moving for an hour and make progress.2 After all, you need to know where to go before you can plan how to get there.

This Blog

That all brings it back to the blog. This site has laid fallow for years, untouched and filled with drafts. As a professional procrastinator, I’ve spent time instead swapping between various CMSs, static site generators, themes, etc., while only actually publishing a rare post as an afterthought.

I’m not going back to edit or review the draft graveyard; they’re dead and gone. RIP. But I do aim to start posting more. Posts may be semi-unstructured, a little ranty, maybe short or long. I won’t hold myself to any set schedule, post count, or word count. Posts will come when they, or I, please.

For too long I’ve let my head get all stuffy with thoughts or ideas and never released that pressure in the form of writing. That’s what this place will be for.

Mang JS

A long time ago I built a tool I called mang: Markov Name Generator. It went through a number of iterations, from a .Net class library, to WPF app, to a Vue app, even as part of a gamedev toolkit for a long abandoned roguelike. Most recently, it’s been a desktop app built with Avalonia so I could use it on Linux. Over the years it’s become my “default” project when learning a new language or framework.

Well, now I have one of those new-fangled MacBook Pros. Anyone familiar with MacOS development knows how much of a hassle it is to build anything for it, even if you just want to run locally, and I do not want to pull over all my code and an IDE just to run in debug mode to use the app.

What I did, instead, was port the whole thing over to a single static webpage.

I put off doing this for a long time because I’m not a huge fan of JavaScript. Also just as important to note is my tendency to over-complicate, and I kept finding myself wanting to build a full API and web app, which is just completely unnecessary for a tool like this. But I do use mang quite a bit, and there’s nothing so complicated that it can’t be done in vanilla JS. So I bit the bullet and ported the name generation to start.

It’s more of a transliteration than a “true” port or rewrite. The code is almost exactly the same, line by line and function by function, as it is in C#. But the end result is pretty compact: the CSS itself, which is just a very-slightly-modified fork of simple.css, is almost larger than the entire index.html file. While there is plenty to whine about when it comes to JavaScript, it is nice to have everything in such a plain and accessible format.

The entire tool is unminimized and all of the assets are free to browse.

And all in all, this whole thing went much smoother than I expected for less than an hour of work.

What Changed

As part of this process I removed some of the name types that can be generated. Most of the types available in mang are historical or fictional, and it felt odd to have some name types with contemporary sources. As such, all of the East Asia, Pacific Island, and Middle-East Sources have been removed.

What’s Coming

I have not ported the admittedly barebones character generation stuff yet. I have some better plans for that and will be spending some time fleshing that feature out.

The character generation so far has been “trait” flags, randomly selecting between things like “carefree” and “worried”, or picking a random MBTI type. It’s generally enough for rough sketched of an on-the-fly NPC or something, but could use some more work to be truly useful as a starting point for anyone requiring more detail.


Helion, a Theme

A Brief Rant About Color

I have a lot of opinions on colors and color schemes. For example, if you are implementing a dark mode on your app / site / utility and decide to go with white text on a black background (or close-to-white on close-to-black), you should be charged with a criminal offense.

High contrast is a good thing! Don’t get me wrong! But that type of dark mode is offensive to my eyes and if I find myself using something with that color scheme I will switch to light mode, if possible, or simply leave and never come back. It’s physically painful for me, leaving haloes in my vision and causing pretty harsh discomfort if I try to read for more than a few seconds. And though this may be contentious, I find it a mark of laziness: you’re telling me you couldn’t be bothered to put in even a little effort in finding a better way to do dark mode?

So it may come as no surprise that I am a long-time Solarized user. From my IDEs, to my Scrivener theme, to my Firefox theme, to anything I can theme — if it’s got a Solarized option, I’m using it. For a long time, even this blog used some Solarized colors. (Dracula is a close second in popularity for me.)

Helion: A VS Code Theme

I’ve long experimented with my own color schemes. It’s a perfect channel for procrastination, and a procrastinator’s work is never done. Today, I think I’ve settled on a good custom dark theme which I want to release, on which I’d like to iterate as I continue to use and tweak.

Helion, inspired by Solarized and colors that faded away, is my contribution to the dark theme world. It’s not perfect — few things are — but my hope is that it becomes a worthy entry to this world.

Right now it is only a Visual Studio Code theme. As I continue to use and tweak it, I plan to standardize the template into something I can export and use for other tools.

Here is a screenshot:

A screenshot of the Helion theme in use in Visual Studio Code, viewing two JSON files side by side.

Just comparing some json files

Now, I am not a usability expert. The colors here are in no way based on any scientific study and I do not assert that they are empirically perfect or better than any other dark mode theme. This is simply a theme which I’ve customized for my own tastes, according to colors and contrasts that are appealing to my own eyes

That said, any feedback is greatly appreciated. If anyone ever does choose to use the theme, I would be delighted to hear from you, whether it’s good or bad (or anywhere in between).

Enjoy!

The Querynomicon

I always felt that every well-rounded developer needs to build a strong working knowledge of SQL.

You don’t need to know the internals of the query engine of your chosen DBMS.1 You don’t need to master the arcane depths of proprietary SQL syntax. However, you should know the types of joins, how NULLs are dealth with, what a SARGable2 condition is and how to write it, and most importantly, how to think about your data in sets.

A long time ago I wrote about some of the tools and resources I used to learn SQL. I was also blessed to work at a company which put data first, where one developer had forgotten more about SQL and Windows internals than most people will ever learn. So I had access to a lot of tools and immersion in an environment that would be difficult for some to find. My unstructured approach to learning was not so different from total immersion plus comprehensive input, in the world of second language acquisition; that is, I would have had to try in order to not learn SQL.

Today I came across a new resource for learning SQL that would have been incredible back when I was still learning the ropes: The Querynomicon.

This site is not only a great resource, it is built wonderfully. Starting with a quick overview, then onto scope (intended audience, prerequisites, and learning outcomes), then straight onto learning peppered with practice exercises, then wrapping up with a concise yet comprehensive glossary, I’m just impressed by the level of quality here. From the structure to the presentation, it’s impeccably laid out, almost like a condensed textbook turned hypertext.3 You could turn this site into a class! . Even the flowcharts, explaining high-level concepts, are masterfully done and read like natural language. I love it.

If you’re slightly familiar with SQL, this really is a great site to check out. If you’re brand-new and want to begin learning, maybe start with SQL Server Central’s Stairway to Data (or DML) series, and then the Querynomicon to reinforce what you’ve learned.