About Me
Software Engineer. New father. Old gamer.
You can find me as
  • zkhr on board game arena
  • zkhr on discord
  • zakhar iceteno in ffxiv (on Famfrit)
  • zkhr on github
  • zakhar on hacker news
  • zkhr on spotify
  • zkhr on stack overflow
  • zkhr on steam
  • zakhar on tildes
You can see what I've read recently in my reading log and blogroll, and what board games I'm playing over in my board game inventory. Want to reach out? Message me at blog@ariblumenthal.com
Home
hello world.
2022-11-25
A few days ago, ooh.directory showed up on Hacker News with collections of blogs on all sorts of topics. This reminded me how fun the internet was in the early 2000s and provided me the encouragement I needed to start a blog of my own. I'm not sure entirely what content will show up here, but probably a mix of old and new side projects, being a new father, games I'm playing, and other similar sorts of things.
If you're reading this and want to talk more about anything I've written, feel free to reach out at blog@ariblumenthal.com.
Home Journal Next
booggle.
2022-11-29
Several years ago, I created the side project I still use the most.
booggle is a fictional ghost inspired web implementation of a popular word game involving a 4x4 grid of letters. Designed to be played by me and my then girlfriend (now wife), it helps kill a few minutes pretty much whenever we need.
The application was built using a minimal nodejs server (with express) that tracks users coming and going, handles state for games that are in progress, checks words against a dictionary as users are playing, and provides scoring at the end.
On the client, I used mostly vanilla javascript with handlebars. Simple json messages are passed between the client and server via a websocket.
Want to try it out? It runs over at ari.blumenthal.dev/booggle. It's a little buggy, only one game can be played at a time, the dictionary isn't perfect, but hey, anyone can play.
Source for booggle is now available over on my github at github.com/zkhr/booggle.
Home Journal Prev Next
new site, who dis.
2022-12-01
When I set out on creating this new blog, I knew I wanted it to have a novel aspect. While the high level content is pretty familiar across personal websites on the web (about me, blog, projects, etc), the structure puts a fun spin on the "single page application" concept.
As you may have seen by the time you got to this blog post, the site is an infinite grid. Each page on this site is a panel in that grid.
The prototype for this is relatively straightforward, but it required a couple interesting pieces across my nginx config, CSS, and JS.
nginx config
For the prototype implementation, I load the entire website, no matter which page you hit. This allows exploring without having to load anything additional from the server. Since this site is all text, it loads quickly (and will for the foreseeable future).
To support this in my nginx configuration, I do two important things:
1. I enable Server Side Includes with ssi on. This allows me to create a new file per panel and then include them individually in the main index.html.
2. I use the rewrite directive so that all paths that start with /! will get sent to that index.html file.
location /! {
  rewrite ^.*$ /;
}
This allows me to track the current position of the user in the grid in the URL. For example, this page's path starts with /!/1/-3, which defines the x and y coordinates of 1 and -3 respectively. When the user refreshes the page, we correctly load the index.html file (instead of throwing a 404 not found error).
CSS
The grid is a position: relative element that holds all of the panels. To move from panel to panel, we change the grid's left and top properties.
As an analogy, you can think of your monitor as a microscope and the grid as a slide under the lens. To move around, we move around the slide, while the scope remains stationary.
Within the grid are several position: absolute panels. Each panel has distinct x and y coordinates, which are used to set appropriate left and top properties when initializing the page. Because of the relative position attribute on the grid, these are absolute positions relative to the grid.
JS
For the prototype, the JS code does three main things:
1. Placement of the grid panels at their appropriate locations in the grid.
2. Enabling the grid links so that we can easily navigate between panels.
3. Supporting keyboard navigation (asdf, hjkl, arrow keys) as well as touchscreen navigation as alternative mechanisms to move between panels.
And that's pretty much it. As mentioned, I load the whole site on every page load which isn't ideal. If I stick at this blogging thing for a while, I will probably write a small server to better handle loading panels as needed.
Home Journal Prev Next
puzzle hunts.
2022-12-02
Early on in the pandemic, I left my job at Verily which was hitting some growing pains while at the same time expecting everyone to work long hours on its new covid testing program. At my new job, a coworker asked what I did for fun. Since my wife and I had been doing a lot of jigsaw puzzles I mentioned, "Puzzles?" and they said something like, "oh you mean like puzzle hunts?".
And with that, I was nerd sniped! The rest is history.
What is a puzzle hunt?
A puzzle hunt is a collection of puzzles, often with certain shared characteristics like metapuzzles (that require the answers to previous puzzles to solve) and answers that are short phrases or words.
Brian Chen's Introduction to Puzzlehunts provides an excellent background.
Which hunts have I participated in?
I've done several hunts so far with my wife and friends, typically under the caffiends alias. I would consider myself to be squarely in the "novice" category. I can do the intro puzzles and maybe get a meta, but I still have a ways to go.
  • 2022-08-26 - Galactic Puzzle Hunt 2022 (solves)
  • 2022-07-02 - 2022 Truzzle Hunt
  • 2022-06-18 - Huntinality 2.0 (solves)
  • 2022-03-11 - glyph 2
  • 2022-01-14 - MIT Mystery Hunt 2022
  • 2021-12-11 - Silph Puzzle Hunt (solves)
  • 2021-10-01 - Teammate Hunt 2021 (solves)
  • 2021-08-21 - Puzzle Potluck 4 (solves)
  • 2021-07-23 - Galactic Puzzle Hunt 20/20 Vision (solves)
  • 2021-01-30 - Inexact Puzzle Hunt
  • 2021-01-15 - MIT Mystery Hunt 2021
Where can I find upcoming hunts?
puzzlehuntcalendar.com is the definitive place to find upcoming puzzle hunts.
Puzzled Pint also has a monthly release of themed puzzles.
Any tips or tricks?
The Puzzle Hunt Toolkit is a collection of tools I've found useful while solving hunts.
Home Journal Prev Next
pokémon scarlet.
2022-12-08
The last year or so has been great for the pokémon franchise with several games hitting that nostalgic itch and innovating in interesting directions.
In April 2021, New Pokémon Snap revisited the best N64 rails shooter and in Jan 2022, Pokémon Legends: Arceus took a spin on the standard formula.
Pokémon Scarlet and Violet continue this with another solid entry in the franchise. While many reviews rightfully criticize the performance and graphical issues, having grown up with the graphics of n64 and gamecube games, that didn't really bother me too much. Instead, I could enjoy a really engaging gameplay loop of just wandering around an open world, catching pokémon, and taking down gyms.
my squad
This time around, I tried to have a balance of pokémon from different generations with good type coverage. Here is the lineup:
Scizor #212 gen ii
bug steel
Gardevoir #282 gen iii
psychic fairy
Garchomp #445 gen iv
dragon ground
Drednaw #834 gen viii
water rock
Skeledirge #911 gen ix
fire ghost
Pawmot #923 gen ix
electric fighting
I started with the fire croc Fuecoco, so its evolution Skeledirge was the first pick. Running into Pawmi early on meant that of course Pawmmot would take spot #2. I have a soft spot for any mon that can learn false swipe, so Scizor, Drednaw, and Garchomp all made the cut. Finally, to round out the team with some fairy and psychic coverage, Gardevoir took spot #6.
Home Journal Prev Next
hilbert curve.
2022-12-11
As mentioned in the new site, who dis. blog post, this site is an infinite grid, with each page on the site being a panel on that grid. This raises the question, how do I decide where on the grid to place new pages?
Being an infinite grid, there are an infinite number of options! For example, we could just go off in an arbitrary direction:
··············
··█───────────
··············
But that doesn't really take advantage of the dimensionality of the grid. Instead, we could spiral around a point:
┌─────┐
│┌───┐│
││┌─┐││
│││█│││
│││└┘││
││└──┘│
│└────┘
Or we could use the Cantor Pairing Function or even pick randomly!
So, what did I go with? Well, for blog posts, I decided to use the Hilbert curve, a space filling fractal, since it has some nice properties:
█·······
│┌─x┌─┐┌
└┘┌┘└┐└┘
┌┐└┐┌┘┌┐
│└─┘└─┘│
└┐┌──┐┌┘
┌┘└┐┌┘└┐
│┌┐││┌┐│
└┘└┘└┘└┘
This blog post is at 'x' on the curve.
If you get lost navigating the grid, you can always grab a map to check your position.
Home Journal Prev Next
fusion.
2022-12-14
Our ancestors harnessed the power of a sun, and so again shall we.
-- Commissioner Pravin Lal
"The Science of Our Fathers"
Congratulations to the folks over at LLNL for their news yesterday on achieving fusion ignition. From the linked announcement:
LLNL’s experiment surpassed the fusion threshold by delivering 2.05 megajoules (MJ) of energy to the target, resulting in 3.15 MJ of fusion energy output, demonstrating for the first time a most fundamental science basis for inertial fusion energy (IFE).
So, why is this milestone exciting? Let's dive in.
Why pursue fusion energy?
Looking at the U.S. Energy Information Administration's electricity generation by energy source in the United States for 2021, roughly 4.11 petawatt hours were generated with ~60% coming from fossil fuels, ~20% from nuclear energy, and ~20% from renewables.
Fusion energy, often relegated to the realm of science fiction, has significant advantages over the nuclear and fossil fuel categories.
In comparison to nuclear energy, there is no risk of catastrophic meltdown, the raw materials are abundant, and the nuclear waste is minimal and decays relatively quickly.
When considering the looming effects of climate change, traditional fossil fuels like oil, natural gas, and coal become a lot less attractive.
So fusion energy, when available, could easily fit inside a portfolio of cleaner energy solutions like wind, hydropower, solar, biomass, and geothermal.
What are the ongoing fusion efforts?
One of the more popular approaches (with a few dozen around the world), tokamak devices work to study fusion by generating a powerful magnetic field to confine the fusion fuel.
On the other hand, LLNL's National Ignition Facility (NIF) pursues fusion by means of inertial confinement (i.e. using energy from lasers instead). I'm not a nuclear physicist, so I won't go into more details than magnets vs lasers, but check out LLNL's article on How NIF Works for some interesting background.
Yesterday's announcement and what's next
In the announcement yesterday, NIF successfully created 3.15 MJ of energy by delivering only 2.05 MJ to the target. This is an awesome milestone, with the big caveat that in order to deliver 2.05 MJ of energy, the laser system needed ~300 MJ from the grid.
So, what's next? Like a tech tree in a video game, achieving fusion energy as a long-term power source requires prerequisite research advances in many areas. How do we fire shots at a higher frequency? How can we increase the yield from the lasers to require less energy from the grid? How do we further increase the energy yield? And so on.
The joke has been that fusion energy is always a couple decades away, but yesterday's milestone truly feels like we've moved one step closer. Who knows... ask me again in 2040.
Home Journal Prev Next
board game roundup.
2022-12-20
The last few decades have seen a board game renaissance, with a tremendous number of amazing games coming out. Even better, they have made their way online where you can play against folks from around the world.
When I was younger, there wasn't the same variety of board games we have today, especially in digital form. I remember learning a bunch of Risk strategy by playing TurboRisk bots and then using that later to work my way up through the ranks of conquerclub.com.
Now, with sites like board game arena, there are all sorts of games available to play! I'm currently playing seven different games at seven virtual tables.
In the order of when the games were released, here they are:
2004 -
EKONOS.
A simple game with three parts: (A) a stock market where you can buy and sell shares in stocks, (B) a Risk-style map where you can expand and take over other companies, and (C) a deck of cards that determines which companies you can expand each round.
2010 -
7 Wonders
. A card drafting game where you build up your civilization. While taking simultaneous turns to draft (great for online games), you get points based on your military, science, and more. Cards can only be drafted if you have the right resources or have drafted prerequisite cards.
2013 -
Sushi Go!
Another drafting game with a similar playstyle to 7 Wonders. Instead of building a civilization (and needing to buy drafted cards), you instead earn points based on the types and combinations of sushi you draft.
2015 -
Letter Tycoon.
What if you could buy patents for the letters of the alphabet? In this game, you draw letters from a deck of cards to make words and get bonuses based on the letter patents that you've bought.
2016 -
Kingdomino.
This is a game of drafting dominoes to build up a 5x5 grid. Points are earned based on contiguous types of land (lakes, forests, etc) and the number of crowns contained on those tiles.
2017 -
Azul.
This is a game of drafting patterned ceramic tiles and using them to build a wall, scoring points based on matching colors and building rows/columns.
2019 -
Wingspan.
Tableau building game with birds. Probably my favorite new board game of 2022.
Home Journal Prev Next
fonts.
2022-12-22
Learning about typography can lead you to noticing things that you might have otherwise missed before. This can suck, like seeing bad kerning everywhere, but it can also be fun to see the patterns in fonts used by restaurants, websites, movies, and more.
I'm not an expert on this topic, but I love seeing new and interesting fonts and wish more sites on the internet took advantage of the variety out there. So to that end, I've gone ahead and updated this site to use a few that I like.
Most text content is written using a font based on Edsger W. Dijkstra's handwriting that I grabbed from Luca Cardelli.
For titles, section headers, and links around the blog, I use Carl Krull's Traveling Typewriter font.
For code, I use Ubuntu Mono, which is my favorite monospace font and the one I've used for my terminal for many years (even though Ubuntu is no longer my linux distro of choice). Canonical funded Dalton Maag to create this font family for the Maverick Meerkat release in 2010.
NOTE(2024-02-23):
I've updated the fonts since this was originally written. Check out the _fonts.scss history on github for the latest and greatest.
Home Journal Prev Next
monster sanctuary.
2022-12-23
After beating the main story in pokémon scarlet a few weeks ago, I decided to keep the creature catching going with monster sanctuary on switch.
This game is a cross between a typical monster taming adventure and a side-scrolling metroidvania. Combat in the game is in the form of 3v3 turn-based monster battles with your typical elemental resistances, buffs, debuffs, etc, but there is enough variance between the different monsters and some interesting combat mechanics which keep things interesting and engaging.
For my first playthrough, I started with the
#4 Spectral Lion
and ended up keeping my same team of early monsters throughout:
#12 Monk, #20 G'rulu, #34 Ice Blob, #51 Tanuki
and
#61 Manticorb.
That said, all the other monsters I caught for their abilities and to fill out the journal seemed pretty viable and had interesting skill combinations of their own.
I think this is one of the games where you kind of know ahead of time if you'll like it or not. If a monster catching side-scrolling metroidvania sounds fun to you, give it a whirl. The combat mechanics are a lot of fun and it won't disappoint.
Home Journal Prev Next
2022 epilogue.
2023-01-06
2022 saw many issues, what with the ongoing covid pandemic, tech layoffs, the conflict in Ukraine, and more. But for me personally, it has ended on a high being able to spend the last couple months on paternity leave with my first kid.
The internet loves lists of things, so here are three lists of random categories for the year.
Video Games
In 2022, I played plenty of games from past years, whether that was trying out Seablock in Factorio, thinking I could replay FFXV before my son was born (spoiler, he got here 2 weeks early), playing the 6.1 and 6.2 FFXIV patches, continuing a very-long-running Gloomhaven campaign with my friends, or trying another run of Don't Starve Together with my wife.
But, for this category we'll look specifically at my top five games that were released in 2022.
First, in no particular order, are some runner ups. Games I still enjoyed, but didn't make the cut: pokémon scarlet the latest entry in the long-running pokémon franchise, the tactical rpg Triangle Strategy with the Octopath-like HD-2D visual style, the short innovative solitaire village builder Stacklands, and the donut-based puzzle game Freshly Frosted.
Starting at #5 is APICO, the indie beekeeping simulator. It was simultaneously super relaxing, while remaining engaging collecting bees and mastering the mechanics of breeding and gathering resources. Not to mention an awesome soundtrack by Mothense.
At #4, described by Yahtzee in Zero Punctuation as a "post-dad game", Hardspace: Shipbreaker has you dismantling spaceships for parts in a dystopian capitalist scifi future. Like APICO, both relaxing and engaging, but rather than breeding bees, the joy came in learning the most efficient way to scrap ships and score those sweet credits to slowly chip away at your crippling debt.
Coming in at #3 is Strange Horticulture, an occult puzzle game of identifying plants and uncovering plots. I loved the user interface of this game that left it to the player to decide how to organize their stuff, the overall aesthetic that oozed with charm, and the thought that clearly went into designing the different plants and their associated puzzles.
At #2 is a game that actually came out in South Korea in 2019, but made its global debut in 2022. Lost Ark is an Action MMORPG with super fun combat, gorgeous locales, interesting characters, and plenty of end-game content. It had different modes that were reminiscent of playing Diablo, Monster Hunter, and FF14 all with the right mix of challenge and rewards. And not to mention all the mokoko seeds and island souls to collect!
Last at #1 is Pokémon Legends: Arceus which took a spin on the standard formula of catching pokemon. Running around an open world and throwing pokemon balls at unsuspecting monsters never got old. Here is the squad that I went with:
Vaporeon #134 gen i
water
Typhlosion #157 gen ii
fire
Scizor #212 gen ii
bug steel
Luxray #405 gen iv
electric
Rhyperior #464 gen iv
ground rock
Gallade #475 gen iv
psychic fighting
And that's it for games! Up next is TV shows!
TV Shows
For this category, rather than shows that debuted in 2022, I'll consider any show that released a new season in 2022. This is purely out of convenience, since I didn't watch that many new shows this year.
In 2022, I watched a
lot
of panel shows, quiz shows, and the like, including the newcomer The 1% Club, as well as classics like Jeopardy, Only Connect, QI, 8 out of 10 Cats Does Countdown, Would I Lie To You, and more. But in honor of Jeremy Paxman's last season of hosting, my #5 slot goes to University Challenge.
At #4, I honor a relative newcomer to the online streaming scene with College Humor's Game Changer. With a recurring cast of amazing comedians and incredibly clever games, this show never disappoints. Close runners up are their game shows
Um Actually
and
Dirty Laundry
Another dropout show, Dimension 20 takes the #3 slot, with their 2022 release of
A Court of Fey and Flowers
with Aabria Iyengar as GM. I was introduced to this show with
Escape from Bloodkeep,
but between
Fantasy High
and
Misfits and Magic,
this show has hit after hit.
At #2 is Netflix's comedy murder mystery Murderville, hosted by Will Arnett. Each episode sees a different celebrity try and solve a case, having to improvise as they go along. With guests like Conan and Kumail Nanjiani, it was a joy to watch. It also introduced me to Murder in Successville, which this show was based on.
Last but not least, is my #1 pick, the new comedy action anime SPYxFAMILY, which sees a spy, an assassin, a telepath, and a dog who can see the future try and avert war. Hilarious, well animated, interesting characters. Definitely a fun new show, and with music by
(K)now_Name
(who also did the amazing tracks for Dorohedoro), I can't wait to see where it goes next.
And that's it for TV. Last list is food!
Food
Speed round! With a kid on the way in 2022, we moved to have a little more space after 3.5 years in San Mateo, CA. In honor of the town's amazing food scene, here's a quick list of our top 10 places to grab a bite.
To leave room for the amazing places unique to San Mateo, I've left out larger chains like Bonchon, Teaspoon, Mochinut, Curry Up Now, and more amazing spots that are more broadly available. Also special shout out to Suruki Supermarket, which could steal the #1 spot, but I'll keep this list to restaurants.
  1. Jeffrey's Hamburgers
  2. Apple Fritter
  3. Ramen Dojo / Ramen Parlor
  4. Pancho Villa Taqueria
  5. Izakaya Ginji
  6. Wursthall
  7. Sichuan Chong Qing Cuisine
  8. Avenida Restaurant
  9. Pausa Bar & Cookery
  10. Backhaus
Anyways, here's to a healthy and happy 2023!
Home Journal Prev Next
roze.
2023-01-10
By creating a planetary network, mankind on Planet now has the ability to share information at light-speed. But by creating a single such network, each faction has brought themselves closer to discovery as well. At the speed of light, we will catch your information, tag it like an animal in the wild, and release it unharmed-if such should serve our purposes.
-- Datatech Sinder Roze
"The Alpha Codex"
Over the pandemic, I've played a few asynchronous games of Civ 6 with friends, using discord to keep track of whose turn it is. We wanted a way to automate @mention'ing the next player, so we looked around.
There are a few github repos that have this functionality that you can clone and run with, and there is an often cited reddit post that explains how to set up IFTTT for this, but there wasn't an easy way to add a bot to your server and have it "just work".
Until now!
Introducing, roze.run, the self-proclaimed "premier way to get turn notifications in Discord for Sid Meier's Civilization VI". This was a fun weekend project, in that there are only a few moving parts, but it gets the job done! Well mostly, Civ's webhook system has a bunch of issues that can actually make it kinda flaky, but under certain circumstances it works well.
This project is named after Datatech Sinder Roze from the Alien Crossfire expansion of one of my favorite games of all time: Sid Meier's Alpha Centauri. As an aside, if you like 4x games and haven't played it, do yourself a favor, close this blog, and buy it now. It is often on sale on gog and at time of writing it is only $1.49. I've easily spent hundreds of hours over the last two decades on this one game.
roze's site above has more details and her source is available on github in the zkhr/roze repo.
Home Journal Prev Next
deck.
2023-01-19
With a nearly 3 month old at home, portable pausable gaming has allowed me to relax during my downtime when the little guy naps or feeds, but still lets me jump in on a moment's notice. After a couple of months doing this on the switch (with games like pokemon scarlet and monster sanctuary) or on my phone with board game arena, I decided to unlock my steam library and pick up a deck.
And I enjoy using it immensely! The biggest technical issue I've encountered involves the screen not turning back on after sleeping, but with its short boot times, that issue hasn't bothered me too much.
So far, I've played a few games on it. I tried out Desk Job, replayed some Hades and Cozy Grove, delved into the newer acclaimed Vampire Survivors, and took my Civ VI turns in my play by cloud games with friends.
I even got ff14 working on it to catch up on the 6.3 main story! While reluctant to move from M+KB to controller gaming for an MMO, I've picked it up quicker than I thought I would, and actually prefer it for a few things already. Maybe not for extreme trials, but I'm mostly doing solo content anyway right now (so I can pause whenever I need to).
Not sure what I'll play next, but studios have packed February with new games up my alley. Hogwarts Legacy comes out on Feb 10, Theatrhythm Final Bar Line on Feb 16, and Octopath Traveler 2 on Feb 24. And in the latest Friday Facts, Twinsen announced controller support for Factorio is on its way, so I've got that to look forward to at some point, as well.
Home Journal Prev Next
css: color.
2023-01-28
Suppose we wanted a blue block:
How would you specify its color in CSS? Well, let's start by rolling the clock back to 1996. Independence Day started airing in theaters, Game Freak launched Pokemon Red and Blue, Sid Meier released Civ II, and W3C published the first specification for CSS.
Cascading Style Sheets, Level 1
Per the CSS1 specs, we could write this using a color name, such as background: blue. The 16 original named colors are black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, yellow, navy, blue, teal, and aqua.
But folks typically want to use more than a few predefined colors. Well, you can also specify one of the ~16.7 million colors in the sRGB color space, which allows defining a color by its red, green, and blue channels. Instead of using the named color, you can use one of the following:
  • background: #00f - a 3-digit hex code
  • background: #0000ff - a 6-digit hex code
  • background: rgb(0, 0, 255) - an integer rgb() value (from 0 to 255)
  • background: rgb(0%, 0%, 100%) - a float rgb() from 0.0% to 100.0%
Cascading Style Sheets, Level 2
The CSS2 and CSS2.1 standards didn't change too much in the way that developers could specify colors, except the addition of orange as a new named color. So let's move on.
CSS Color Module Level 3
After CSS2 (which was one large spec for all of CSS), W3C switched to using smaller documents for different modules. The CSS Color Module Level 3 introduced a few things.
130 new named colors were added (with some overlaps like dimgray and dimgrey).
To specify an opacity for an element, rgba() was added. It takes a 4th parameter for an alpha channel: background: rgba(0, 0, 255, 0.5).
CSS Color 3 also added hsl() and hsla(), which use hue, saturation, and lightness. If you haven't seen this before, let's take a look at how this works.
Without invoking physics or just shouting the word color over and over,
hue
is pretty hard to define, but really easy to understand. It's where in that ROYGBIV wheel the color lands:
saturation
tells how vibrant the color is:
lightness
tells how light or dark the shade of the color is:
Putting these together, we get something like the following grid, with saturation on the x-axis and lightness on the y-axis (if we pick a single hue, like blue):
CSS Color Module Level 4
CSS Color Module Level 4 introduces several new and interesting things.
For starters, rgb() and hsl() syntax has been updated so that they no longer use commas and can optionally provide an alpha value after a forward slash: background: rgb(0 0 255 / 50%).
Hex codes also support alpha channels with 4 digit and 8 digit hex codes: #0000ff80.
As an alternative to specifying color via rgb() or hsl(), there are 5 additional color functions introduced: hwb(), lab(), lch(), oklab(), oklch().
The
hwb()
functional notation expresses a given color according to its hue, whiteness, and blackness. Hue is the same as the hue used in hsl(). The whiteness and blackness refer to how much white or black get mixed in.
For example, we can look at the square below and see how adding whiteness or blackness changes the color, with blackness on the x-axis and whiteness on the y-axis (again picking a single hue).
The last 4 (
lab(), lch(), oklab(),
and
oklch()
) are similar to hsl(), but better map to human perception of lightness (versus using the same scales for all hues like in hsl()). These aren't available in all browsers yet, but will be worth checking out (especially when CSS Color Module Level 5 brings native relative colors to CSS).
Home Journal Prev Next
three body problem.
2023-02-24
I finished reading The Three-Body Problem earlier today, and decided to throw together a quick simulation over at three body simulation.
It kinda works, but mostly it just let me know how rusty my math and physics knowledge has gotten after not using it for 10+ years.
Home Journal Prev Next
euchre.
2023-06-24
Busy couple of months. Went back to work, moved near family, and the kid is almost 8 months old.
In honor of returning to the Midwest, here are the rules I documented a few years ago for three-handed euchre:
3 handed Euchre Rules aka cutthroat euchre
The game starts with all 3 players at 20 points and is played over a sequence of rounds using a deck with 10,J,Q,K,A of every suit and the 9 of clubs. The goal of the game is to be the first to get to 0 points.
Each round is played as follows. The dealer deals 4 hands of 5 cards (1 to each player and 1 face down) and flips the remaining card face up. Starting left of the dealer and moving clockwise, players will decide if they want
the dealer
to pick it up and move the card into their hand and discard back down to 5 cards.
If a player chooses for the dealer to draw that card, that is now the trump suit for the hand. If no player calls it up, the card is flipped over and you go around the table in the same order picking one of the remaining 3 suits. The dealer will be the last to pick and is required to pick a suit (this is the screw the dealer variation in the original Euchre, that I've always played with in cutthroat).
Starting with the dealer and going clockwise, each player can decide if they want to
stay
,
drop
, or
take the other hand
(if the dealer did not take the extra hand). If they stay, they will play with their current hand. If they drop, they will not take part in the round. If they take the other hand, they must play the current round with the hand that was face down. Note that they are playing with that hand sight unseen; they can't look ahead of time.
All remaining players will play the hand with standard Euchre rules (Jack of the chosen trump suit is highest, Jack of the opposite suit but same color is second highest, trump beats nontrump, high beats low, etc). Each trick taken is worth -1 point to your score. Taking 0 tricks is worth +5 points. If you called a suit (or told the dealer to pick the card up) you must take at least 3 tricks, or the hand is worth +5 points (and you get no points for the tricks you took).
Scoring Example 1:
3 players are playing in the first round; Ari dealt the hand and Chad had Ari pick the 10 of clubs up. Ari and Greg both stayed and ended up taking 1 trick each, Chad took 3 tricks. So Ari and Greg are both at 19 and Chad is at 17
Scoring Example 2:
1 player is playing in the first round. Ari and Chad both dropped and Greg was the only one who stayed in. Greg takes all 5 tricks and is at 15.
Scoring Example 3:
2 players are playing in the first round. Ari called a suit, Chad stayed in, and Greg dropped. Ari only took 2 tricks, and Chad took the remaining 3, so Ari is now at 25 and Chad is at 17.
There are 3 remaining special rules:
9 of clubs round:
When the 9 of clubs is the face up card on the table, the bidding is skipped. Nobody draws the 9 of clubs, nobody can switch hands, clubs are immediately the trump suit, everybody must play, and everybody needs to take 1 trick to avoid getting 5 points (nobody is required to take 3 tricks)
9 of clubs trump:
9 of clubs is always the lowest trump card, no matter which suit is trump.
5 points rule:
At the start of the hand, if you're at 5 points or less, you may no longer drop.
Home Journal Prev Next
project ideas i.
2023-07-30
I've got a bunch of random ideas for projects in my notes. Here are a few of the more interesting ones.
Cookbookbook
Cookbookbook would be a "social" website for recipes. I know there are millions of cooking websites out there already (I even briefly had a food blog ~10 years ago).
But searching, collecting, and sharing recipes is an awful user experience today. Really, I want something web-based and text-focused like HN or Tildes but for recipes.
Cracking the coding interview for kids.
As a new dad, I've gotten to read a lot of really fun kids books. I thought it might be cool to try and make one which takes concepts from coding interview prep like leetcode or cracking the coding interview, and turns it into bite-size books that kids can still enjoy while parents learn something new! Not sure if this is an amazing idea or some sort of SF tech bro dystopian one.
TypeWriterScript
It took my longer than I care to admit to remember what I meant by TypeWriterScript in my notes.
I think that the idea here was writing a language that could compile to TS that looks like this:
# Hello World

This is an example of a hello world in TypeWriterScript.

  console.log("Hello World!");
    
The idea here is that the documentation (either in plaintext or markdown maybe) and the code are one in the same, but written with the docs being any unindented lines. The indented lines would be valid TS.
Essentially, I could write a blog post that is perfectly valid TypeWriterScript.
Sherwalk Holmes
Credit for the name on this one goes to my amazing wife.
This would be a mobile game that uses your daily step count to solve Sherlock Holmes mysteries. Your step count would be used to power Holmes traveling around London getting clues to solve the crimes (so you can play at home or wherever).
Anyways, that's it for ideas for now.
Home Journal Prev Next
birds.
2023-09-23
With the addition of the 🐦‍🔥 emoji in Unicode v15.1, it occurred to me that Unicode has a lot of birds.
This post contains a history of every bird added to the unicode spec. And to answer the age old question, which came first the 🐔 or the 🥚, the chicken was added in Unicode v6.0, but the egg wasn't added until v9.0.
Standard Bird Emoji
  • [1F413] 🐓 - Rooster (v6.0)
  • [1F414] 🐔 - Chicken (v6.0)
  • [1F423] 🐣 - Hatching chick (v6.0)
  • [1F424] 🐤 - Baby chick (v6.0)
  • [1F425] 🐥 - Front-facing baby chick (v6.0)
  • [1F426] 🐦 - Bird (v6.0)
  • [1F427] 🐧 - Penguin (v6.0)
  • [1F54A] 🕊️ - Dove of peace (v7.0)
  • [1F983] 🦃 - Turkey (v8.0)
  • [1F985] 🦅 - Eagle (v9.0)
  • [1F986] 🦆 - Duck (v9.0)
  • [1F989] 🦉 - Owl (v9.0)
  • [1F99A] 🦚 - Peacock (v11.0)
  • [1F99C] 🦜 - Parrot (v11.0)
  • [1F9A2] 🦢 - Swan (v11.0)
  • [1F9A4] 🦤 - Dodo (v13.0)
  • [1F9A9] 🦩 - Flamingo (v12.0)
  • [1FABF] 🪿 - Goose (v15.0)
Modified Bird Emoji
This list has customizations of bird emoji that can be done using the 200D Zero Width Joiner.
  • [1F426 200D 2B1B] 🐦‍⬛ - Black bird (v15.0)
  • [1F426 200D 1F525] 🐦‍🔥 - Phoenix (v15.1)
Bird Adjacent Emoji
  • [1F357] 🍗 - Poultry leg (v6.0)
  • [1F595] 🖕 - Middle finger (v7.0)
  • [1F3F8] 🏸 - Badminton (v8.0)
  • [1F95A] 🥚 - Egg (v9.0)
  • [1FAB6] 🪶 - Feather (v13.0)
  • [1FAB9] 🪹 - Empty nest (v14.0)
  • [1FABA] 🪺 - Nest with eggs (v14.0)
  • [1FABD] 🪽 - Wing (v15.0)
Bird Flag Emoji
  • 🇦🇱 - [AL] Albania (Eagle)
  • 🇦🇸 - [AS] American Samoa (Eagle)
  • 🇧🇱 - [BL] St. Barthélemy (Pelican)
  • 🇨🇽 - [CX] Christmas Island (Tropicbird)
  • 🇩🇲 - [DM] Dominica (Parrot)
  • 🇪🇨 - [EC] Ecuador (Condor)
  • 🇪🇬 - [EG] Egypt (Eagle)
  • 🇫🇯 - [FJ] Fiji (Dove)
  • 🇬🇸 - [GS] South Georgia & South Sandwich Islands (Penguin)
  • 🇬🇹 - [GT] Guatemala (Quetzal)
  • 🇰🇮 - [KI] Kiribati (Frigatebird)
  • 🇰🇿 - [KZ] Kazakhstan (Eagle)
  • 🇲🇩 - [MD] Moldova (Eagle)
  • 🇲🇪 - [ME] Montenegro (Eagle)
  • 🇲🇽 - [MX] Mexico (Eagle)
  • 🇵🇬 - [PG] Papua New Guinea (Bird of paradise)
  • 🇷🇸 - [RS] Serbia (Eagle)
  • 🇸🇭 - [SH] St. Helena (Plover)
  • 🇸🇽 - [SX] Sint Maarten (Pelican)
  • 🇹🇦 - [TA] Tristan da Cunha (Albatross)
  • 🇺🇬 - [UG] Uganda (Crane)
  • 🇻🇮 - [VI] U.S. Virgin Islands (Eagle)
  • 🇿🇲 - [ZM] Zambia (Eagle)
  • 🇿🇼 - [ZW] Zimbabwe (Bateleur)
Egyptian Bird Hieroglyphs
𓁛𓁜𓁝𓁞𓁟𓁮𓄿𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈𓅉𓅊𓅋𓅌𓅍𓅎𓅏𓅐𓅑𓅒𓅓𓅔𓅕𓅖𓅗𓅘𓅙𓅚𓅛𓅜𓅝𓅞𓅟𓅠𓅡𓅢𓅣𓅤𓅥𓅦𓅧𓅨𓅩𓅪𓅫𓅬𓅭𓅮𓅯𓅰𓅱𓅲𓅳𓅴𓅵𓅶𓅷𓅸𓅹𓅺𓅻𓅼𓅽𓅾𓅿𓆀𓆁𓆂𓆃𓆄𓆅𓆆𓆇𓈢𓈯𓈵𓈷𓈺𓉉𓉊𓉡𓊿
NOTE(2024-03-03):
Looks like Unicode 16 is adding nearly ~4000 more Egyptian Hieroglyphs including hundreds more birds. Awesome.
Other Unicode Birds
𐇮 [101EE] Phaistos Disc Eagle
𐇯 [101EF] Phaistos Disc Dove
𐦉 [10989] Meroitic Hieroglyphic Letter MA
𐦖 [10996] Meroitic Hieroglyphic Letter KA
𔒚 [1449A] Anatolian Hieroglyph A128
𔒛 [1449B] Anatolian Hieroglyph A129
𔒜 [1449C] Anatolian Hieroglyph A130
𔒝 [1449D] Anatolian Hieroglyph A131
𔒞 [1449E] Anatolian Hieroglyph A132
𔒟 [1449F] Anatolian Hieroglyph A133
🀐 [1F010] Mahjong Tile One of Bamboos
Home Journal Prev Next
cookbook.lol.
2024-02-12
I put together a minimal website over at cookbook.lol to start storing my recipes. This is the start of the cookbookbook idea from project ideas i.
It does a couple cool things:
  • You can track when recipes are variations of other recipes (either on the site or from a blog or cookbook)
  • It has some basic organization (tracking saved/tried recipes)
  • It has support for basic comment threads.
It is definitely missing a lot of features and there’s tons more I want to do here, but the core functionality is there.
If you're reading this and you want an invite, just shoot me an email.
Design Overview
There is an existing nginx instance running for this blog which routes traffic to new local frontend and backend servers. In the future, we can split one or both of these out into their own instances.
The frontend serves all requests to cookbook.lol. These requests are served by a nodejs server that renders a bunch of closure (aka soy) templates.
The backend server is a minimal (mostly aip.dev style resource-oriented) API implemented in nodejs with postgresql for storage.
Home Journal Prev Next
chromostereopsis.
2024-03-05
I ran into this by accident when playing around with styles for my site awhile back. Turns out this specific optical illusion is more pronounced for near-sighted individuals when wearing glasses. An oddly specific super-power.
Here's an example:
If you don't see the illusion, the red parts seemingly jump out of the screen, and the blue parts are sunken further back. If you search around on the internet, there are tons of cool examples that people have made running with this technique.
Home Journal Prev Next
dst.
2024-03-15
Some thoughts on daylight savings time.
I
A few weeks ago, my one year old and I dug through a storage bin in the basement and found my old lime green gameboy color, with batteries that were decades old and just a little juice left. Contained within, a cartridge of pokémon gold ready to play.
Starting a new game and listening to some 8-bit music, we pretty quickly got to the question: "Is it Daylight Saving Time now?"
I didn't know the answer back when I first loaded up the game as a kid and nearly 25 years later, honestly? I can still never remember which half of the year is DST.
II
So fun new thing as a dad of a 1yo: this is the first year where spring forward was the good one.
Usually fall back gives the extra hour of sleep, but the clock isn’t the deciding factor of when I wake up anymore. My kid is. So spring forward gave me the extra hour of sleep.
More or less.
III
Consider pitching the concept of DST today if it didn't already exist. Everyone once a year decides to move the clock one hour forward, and then six months later, we reverse it and move the clock one hour back. It's unimaginable.
Nobody would agree to it. So how did we get here?
Well in the US, it started in March of 1918 with the Standard Time Act which followed similar changes in Europe during WWI. The library of congress has some fun newspaper articles available online from the time.
IV
In 2018, Prop 7 passed when I was in California, showing a positive sentiment towards getting rid of this twice-a-year nonsense. But, that prop didn't actually implement the change, just the ability for a change to happen in the future.
So is there any hope of change? Right now, with the Uniform Time Act of 1966, states can decide to have permanent standard time (an hour back), but cannot have permanent DST (an hour forward). The only states with year-round standard time today are Hawaii and Arizona.
In 2022, the Sunshine Protection Act proposed permanent DST at a federal level, but after passing in the Senate, it never made it to the House. Newer iterations of this bill have been suggested, but nothing has come of it yet. There is also the open question of whether year-round standard time or DST time is better, for some definition of better.
V
I don't have a specific story I can think of offhand, but I agree with xkcd/2867 so very much.
Leap second bugs, timezone bugs, dst bugs, browser time vs server time, on and on.
Any part of a software project dealing with datetimes makes me a little extra cautious.
Home Journal Prev Next
kotlin.
2024-03-21
I started coding in Kotlin for a project recently and have mostly enjoyed its philosophy and syntax. But I wanted to try and articulate my thoughts on extension functions because I'm not sure yet if I like them or hate them.
Other languages have supported extension methods for years, but most projects I've worked on have been in languages without support (or at least without idiomatic usage).
The super quick overview is that they let you add methods directly on classes that can be imported independently of the original code. Read the docs linked above for a better description.
I think I instinctively hated them, because coming from something like javascript where this would be done via modifying the prototype, you have no guarantees that you aren't clobbering some other code on the page. Or with something like dependency injection where your framework makes data available for you, but it isn't always easy to know where things are coming from without decent tooling or prior knowledge of the codebase.
But neither of these are concerns in Kotlin. Handling for extension functions occurs at compile time, so you don't have the same concerns around breaking other parts of the codebase. And extensions are imported so its easy to find where they source from.
I guess there is a worry that a poorly organized codebase could become even more cumbersome to work with if past authors scattered different parts of an object around incomprehensibly. But this seems like it would be easy enough to reconcile and reason through.
On the flip side, I like the syntactic sugar it brings and the simplicity of adding utility functions on top of core functionality that I don't own.
So I guess it's just the change aversion that comes with learning something new. They'll probably grow on me as I learn all the shiny new best practices that make use of them.
Home Journal Prev Next
godot.
2024-04-10
I
I started to play around with the Godot game engine a few days ago, since I have some ideas for games I'd like to make. Whether or not any of them come to fruition is still tbd, but I decided to give it a go to see what comes of it.
I searched a little bit about each of the major engines these days (godot, unity, unreal, etc) and for the sort of 2D games I'd be working on (and the positive feedback from developers that use it), Godot 4.2 with GDScript seemed like a pretty good fit to try out.
To learn the basics, I did the intro "dodge the creeps" game in their docs and then tasked myself with implementing solitaire. Not trivial, but not super complex either.
II
This isn't my first foray into game development. Twice before I've made a few simple games.
As a kid, I learned Visual Basic and used that for assorted projects. One was a game where a box would jump around the screen and you had to click it to progress.
Later in high school, I took an intro class that I vaguely recall had me make some game in Java to learn OOP, but I can't recall offhand anymore what it entailed.
III
So I got the solitaire game working.
And then I remembered, I don't really like solitaire.
I prefer freecell.
IV
Most of the programming was pretty straightforward and provided a good opportunity to learn the Godot UI, GDScript syntax and all that.
There was an interesting issue I ran into around handling a click event that overlapped with multiple Area2D nodes (e.g. when dragging a card that was on top of another draggable card). I originally used the input event signals, but I had no way of figuring out which one should handle the event (no deterministic order I could figure out as to which node triggered first or to prevent propagation).
I eventually stumbled upon the intersect_point function I could use to get a list of everything that overlapped with the click and filter that by z-index to get the node I wanted.
Home Journal Prev Next
feed.
2024-05-05
I've added an rss feed to the site. Well, not actually. Everyone calls it an rss feed, but when digging into it, the recommended choice in 2024 for the fast-moving technical domain of metadata syndication is Atom, defined in rfc 4287.
It's auto-generated using the same scripts I use for generating this hilbert curve journal itself, so it should stay up to date with the latest 20 entries.
And at least at time of writing this entry, it is a valid Atom 1.0 feed.
Home Journal Prev Next
zoom.
2024-06-02
If you're on desktop, you can now zoom in and out on the grid with the [ and ] keys.
I'd previously toyed with animations that would zoom in and out when navigating far distances on the grid, but never settled on one that I liked. This feature takes inspiration from that, letting you just zoom in and out as you please.
At 3 levels of zoom, the performance of the page is a little janky, but not so bad that I want to do further rendering improvements (above and beyond the switch from position offsets to css transforms in this commit).
Home Journal Prev Next
looking forward.
2024-06-07
I
The fifth ffxiv expansion, Dawntrail, releases in exactly three weeks on June 28 and I'm excited to continue the adventure. It will be interesting to see how the dynamics between the Scions plays out on opposite sides of the political struggle over in Tural and Wuk Lamat seems like a great addition to the cast.
If there isn't a battle on that big bridge between the northern and southern regions, I will be sorely disappointed.
II
I have one book left in The Murderbot Diaries series by Martha Wells after which I'll be caught up (until the next three come out). The titular character's relatable perspective on this dystopian universe has been entertaining to read, what with Murderbot's growth as a person, their relationships with ART, Ratthi, Mensah and the rest of their crew, and all the various adventures, missions, and whodunits.
It also looks like there will be a TV adaption of the books expected to release later this year, about which I'm fairly optimistic. Although with Murderbot processing so many things in parallel, it will be interesting to see how it translates to this medium.
III
I tried out the Ultracube mod a few weeks ago, but the weekly friday facts for Factorio really have me excitedly waiting for the next expansion that might be releasing later this year.
The fff-414 details earlier today about resources spoiling on Gleba have me cautiously optimistic, since it's a mechanic that penalizes my habit of frequently buffering materials on my bases.
The music in fff-406 is amazing. A lot of my spotify history is whatever game soundtrack I'm listening to in the background while coding (FFXIV, Frostpunk, Octopath Traveler, etc) and this looks to be a strong addition. (The rest of my history is my kid's playlists.)
I have such a huge amount of respect for the factorio devs. It is obvious how much love and polish they put into the game and I can't imagine this expansion will be any exception.
IV
After writing the first three sections of this journal entry, I looked up out of curiosity if there had been any news on when Civ 7 was coming out, and lo and behold, it was accidentally announced earlier today! (It has since been formally announced for 2025.)
With previous Civ games releasing in 1991 (I), 1996 (II), 2001 (III), 2005 (IV), 2010 (V), 2016 (VI), this 9 year gap will have been the longest between major releases.
Last year I launched roze, a discord bot for tracking turns for multiplayer Civ 6 games. She is now a verified bot in over 100 servers, which is pretty exciting (and required me to do some extra data retention cleanups and introduce a terms of service). If they don't include built-in support for something similar in Civ 7, I'll try and get roze up and running pretty quickly after launch.
Home Journal Prev Next
university.
2024-06-16
There are two kinds of scientific progress: the methodical experimentation and categorization which gradually extend the boundaries of knowledge, and the revolutionary leap of genius which redefines and transcends those boundaries. Acknowledging our debt to the former, we yearn nonetheless for the latter.
-- Academician Prokhor Zakharov
"Address to the Faculty"
Prelude
While digging through some files, I found my college transcript from — looks at calendar — 13 years ago and thought it might be fun to jot down some recollections.
Transfer
General Chemistry I CHEM 102
General Chemistry II CHEM 104
Calculus MATH 220
Calculus II MATH 231
I took a few AP tests in high school and got out of intro chemistry and calculus freshman year. It's still interesting that after a decade or so of school before university, a handful of transfer credits from AP tests are the only things that carry over.
Fall 07
Engineering Lecture ENG 100
Undergraduate Open Seminar ENG 199
Calculus III MATH 241
Linear Algebra MATH 415
Computer-Aided Design ME 170
Univ Physics: Mechanics PHYS 211
Third Year Russian I RUSS 301
I actually started off as a mechanical engineering major, hence taking ME 170. It was cool to play around with CAD for a semester, but ultimately not what I wanted to do.
My AP physics score wasn't high enough and I didn't pass the exam to get credit for multivariable calculus, so even though I took both PHYS 211 and MATH 241 in high school, I had to take them again freshman year.
Spring 08
Intro to Computer Science CS 125
Discrete Structures CS 173
Freshman Honors CS 196
Survey of Russian History HIST 260
Principles of Composition RHET 105
Third Year Russian II RUSS 302
After quickly deciding to switch to a CS major, I had to take CS 125 and CS 173 before the program would let me officially transfer in. Which is so much easier than today, since you're apparently no longer allowed to move into the CS program from within the university.
Fall 08
Data Structures CS 225
Computer Architecture I CS 231
Numerical Methods CS 257
Computer Security I CS 461
Statistics and Probability I MATH 463
Learning data structures in CS 225 was one of the top two most important software dev classes I took. Useful for day to day coding fundamentals (and passing interviews).
Spring 09
Computer Architecture II CS 232
System Programming CS 241
Honors Course CS 296
Security Laboratory CS 460
Introduction to World Music MUS 133
University Physics: Elec & Mag PHYS 212
CS 460 was pretty neat, we read articles like Smashing The Stack For Fun And Profit and then implemented them in the computer lab.
Fall 09
Ethical & Professional Issues CS 210
Programming Studio CS 242
Theory of Computation CS 373
Distributed Systems CS 425
Communication Networks CS 438
Artificial Intelligence CS 440
I remember putting a certain penny arcade comic in a presentation for my CS 210 ethics class. Got a good score on it, but the teacher wasn't fond of the cursing.
Hands down, my favorite class at university was CS 242. This class had a weekly programming assignment that you could solve in any number of ways, but you would have to present your solution to a small group of other students and a TA. This meant you saw the different ways that everyone in your group approached the same problem.
Some weeks, the assignment would build up off of the previous week's work (without you knowing ahead of time), so if you wrote clean code, you'd be better off than if you quickly hacked something together and left yourself with a bunch of techdebt.
Probably the closest class in college to actually having a software job.
Spring 10
Database Systems CS 411
Programming Languages & Compilers CS 421
Algorithms CS 473
Special Topics (Planning Algorithms) CS 498
Intro Psych PSYC 100
Along with data structures, CS 473 is the other of the top two most important software dev classes. I still recommend Erickson's algorithms textbook as a canonical reference for learning or reviewing this topic.
When a student asked if dancing would be on the final exam, the answer was yes! We got a final where every question was about dancing.
Fall 10
Introduction to Data Mining CS 412
Senior Thesis CS 499
Special Topics (Sensing, Actuation, and Computation) CS 598
Intro to Abstract Algebra MATH 417
Intro to Social Psych PSYC 201
During my last year of college, I had to finish up some gen eds and decided to start taking some extra math classes like MATH 417 for fun.
CS 598 with LaValle was a super interesting dive into relevant research papers (and the only grad-level course I've taken).
Spring 11
Introduction to Bioinformatics CS 466
Senior Thesis CS 499
Graph Theory MATH 412
Set Theory and Topology MATH 432
Univ Physics: Quantum Physics PHYS 214
My senior thesis for CS 499 was A primer on covering spaces for robot exploration, which was essentially a variation of the art gallery problem.
Home Journal Prev Next
spacetraders.
2024-08-17
And so we return again to the holy void. Some say this is simply our destiny, but I would have you remember always that the void EXISTS, just as surely as you or I. Is nothingness any less a miracle than substance?
-- Sister Miriam Godwinson
"We Must Dissent"
Spacetraders is a "space-themed economic game with HTTP endpoints for automating gameplay and building custom tools." It's had me hooked during the evenings the last couple weeks in a "just one more turn" sort of way.
UI
I kicked off with a minimal web frontend to explore the mechanics of the game. Specifically, I built three pages to get started:
A
market
UI where I could see all the waypoints with markets and what goods they were importing and exporting.
A
fleet
UI where I could see the status of my ships, have them mine an asteroid, refuel as needed, transfer cargo to other ships, or fly around the system.
An
rpc
builder UI where I could hit arbitrary endpoints to fill the gaps for things that I hadn't added in my other pages (buying ships, handling contracts, etc).
Automation
Once I got the hang of the intro mechanics to the game, I started building some basic automation. This was done with a nodejs server that tells the fleet what to do.
Each ship is given a persona that assigns it an event loop which contains a sequence of actions to repeat indefinitely. I currently have five personas in use:
The
Hauler
persona (for my freighters) which has them fly to an asteroid, load from other ships until their inventory is full, and sell their cargo at a nearby market.
The
Miner
persona (for my drones) which has them fly to an asteroid and mine whenever they have cargo space.
The
Pricer
persona (for my probes) which has them fly in a loop around the different markets and stores the prices of goods in a postgres db. This uses a naïve nearest neighbor algorithm for generating the route.
The
Trader
persona (for my frigate) which has it find the most profitable good in the system, pick it up at one waypoint and sell it at another.
The
NOOP
persona for ships I have stationed at a particular waypoint (e.g. so I can buy ships at its shipyard, etc).
Current Status
The game is an alpha, so the server resets every ~3 weeks. The last reset was on 2024-08-11 (I started playing a little before then) and my handle for this reset is
ZAKHAROV.
At time of writing, I have ~1.5 million credits which puts me 14th on the leaderboard for this reset (mind you there are very likely more players that have more credits than me if you include the cost of their ships (and 1st is currently at ~500 million, so there is that)).
My fleet consists of 21 ships: 1 frigate, 4 probes, 1 shuttle, 3 freighters, and 12 drones.
What's Next
There are several directions I could go from here. Some ideas in no particular order:
  • Add ship information to my DB and build a live visualization of where all my ships are at any given time.
  • Add a queueing server between my API calls and the game server, to avoid hitting the dreaded "You have reached your API limit" errors.
  • Explore more mechanics of the game (visiting other system, market dynamics, etc).
  • Port my codebase to another language. I built this out quickly using JS, but it could be fun to try out Rust or Elixir or something well suited to this sort of project.
Home Journal Prev Next
magic.
2024-11-09
Urza and the Kor
My foray into magic began with the
Call of the Kor
deck from Stronghold (1998).
However, when I think of my personal magic nostalgia, the picture in my head is of the Lightning Dragon on the cover of those Urza's Saga tournament packs.
Of the cards I own from this generation, some of my favorites were Memory Jar, Rancor, and Deranged Hermit from Urza's Legacy (1999).
On again, off again
Magic as a hobby came and went. There were sets I drafted with my friends again and again like Mirrodin (2003), Champions of Kamigawa (2004), and Ravnica: City of Guilds (2005).
And sets I missed entirely.
While I mostly drafted, I do remember buying singles to get a set of Wellwisher and Llanowar Elves to build an elf deck around Voice of the Woods from Onslaught (2002).
Of the cards I own from this generation, some of my favorites were Isamaru, Hound of Konda from Kamigawa, Skyknight Legionnaire from Ravnica, and Sarkhan Vol from Shards of Alara (2008).
Duels
I briefly played Magic Duels in 2015, but gave up fairly quickly.
I posted on reddit about an issue with deck size limits (but never heard from the devs for that bug report).
Arena
I played a bit of arena a few years ago. There were two decks I built that I remember really enjoying.
The first was a Brushfire Elemental deck (Zendikar Rising, 2020) that used those landfall creatures to try and win the game quickly (and a few Goldspan Dragons (Kaldheim, 2021) to finish the job.
The other was an Archon of Sun's Grace deck (Theros Beyond Death, 2020) that used enchantments to make a bunch of pegasuses (pegasi?).
Intrigue and Critters
This year, I've found myself playing paper magic again, first with the preconstructed Murders at Karlov Manor commander decks and then drafting Bloomburrow and Foundations.
I absolutely love that full art lands have made a strong resurgence in recent sets. So many cool options, from the Phyrexia: All Will Be One lands in the Phyrexian language and the unique art style of the Kamigawa: Neon Dynasty lands to the stained glass Dominaria United lands, the stellar Theros Beyond Death lands, and the negative space Outlaws of Thunder Junction lands.
Of this generation, I've in general enjoyed the art and theme of Bloomburrow, but my runaway favorite card is the Mabel, Heir to Cragflame I drafted.
Final Fantasy x Magic
Another on again, off again game I've played over the years are the various iterations of Final Fantasy (e.g. see me previously trying to replay FFXV in the 2022 epilogue before my son was born (spoiler, he got here 2 weeks early) and looking forward to Dawntrail earlier this year (spoiler, it was great)).
So it's no wonder I'm excited for the upcoming collaboration between these two franchises next year. I can't wait to build a chocobo or moogle deck.
Home Journal Prev Next
artifacts.
2024-12-30
Superior training and superior weaponry have, when taken together, a geometric effect on overall military strength. Well-trained, well-equipped troops can stand up to many more times their lesser brethren than linear arithmetic would seem to indicate.
-- Spartan Battle Manual
Not the valve one.
After playing spacetraders a few months ago, I've once again found myself playing an API game. In Artifacts, you're automating characters in an mmorpg.
Last time around I wrote everything in JS to go fast, but wished I'd tried out something new. This time around, I went with
Rust.
I haven't used any languages with memory management since C/C++ at university, so actually thinking about the stack and heap and reference counting and all that was an interesting change of pace.
For some definition of interesting. Was that a &str or a String that I wanted?
Read the book.
I don't remember what blog I found it on, but a few days into using Rust, I read a comment like "you can't just jump into using Rust, you have to read the book". Whoops, I guess.
Personas.
My implementation for artifacts is pretty similar to what I'd done for spacetraders with personas I could attach to my characters, but just a different set of tasks. Usually characters stuck to a specific persona, but sometimes I would have them all do the same one overnight (e.g. to get a bunch of resources or level up). The ones I ended up settling on were:
The
Crafter
persona to make weapons, gear, or jewelry.
The
Gatherer
persona to chop wood and mine ore.
The
Fighter
persona for characters to farm individual monsters or tasks coins.
The
Angler
persona to fish and cook.
At one point I also had a
Chicken Chaser
that just battled chickens.
Rust positives.
As a fan of Optional introduced recently in Java 8 (okay so I guess 2014 isn't considered recent anymore, but at least that isn't as old as that chicken chaser reference (Fable came out in 2004) and I did have a coworker whose license plate was JAVA 8, but that's unrelated) as a way of making code more explicit and readable, Rust's Option is pretty handy as well. Result is handy for similar reasons.
Spinning up and coordinating multiple threads was super painless. If something went wrong with one of them during the night, the other characters could still do their thing.
loop {} is rad.
Grabbing code from other crates was relatively straightforward. I used chrono (for dealing with time stuff), reqwest (for making the API calls), and serde (for handling json).
Error messages during compilation are excellent. No notes. For someone totally new to the language, they provided great starting points for learning more.
Skies.
My five characters are named after protagonists from Skies of Arcadia, the best RPG ever made (when wearing my particular set of nostalgia goggles): Vyse, Aika, Fina, Enrique, and Drachma.
It is surprising that in ~2 years of doing this blog I haven't written anything about that game yet. Guess I have to replay it in 2025.
Home Journal Prev Next
p90x.
2025-01-20
If our society seems more nihilistic than that of previous eras, perhaps this is simply a sign of our maturity as a sentient species. As our collective consciousness expands beyond a crucial point, we are at last ready to accept life's fundamental truth: that life's only purpose is life itself.
-- Chairman Sheng-ji Yang,
"Looking God in the Eye"
14 years
of watching Tony Horton tell me to do my best and forget the rest.
In 2011, I'd graduated college and moved out to California with a few boxes and a duffel bag. After living on my own a bit realized, "Yeah, guess I should probably work out".
But this was the tail end of the era of dvds. Netflix had some streaming options, but not everything was available there yet. I had to wait for episodes of Dexter to show up in the mail one disc at a time.
So I bought the p90x dvds. And now in 2025, I've forgotten how many times I've stopped and started and just pushed play.
Sometimes I complete all 90 days, sometimes I don't. Sometimes I stream the workouts, sometimes I put the dvds in a PS3 or PS4.
But once again, today is day one.
MLM
I can't write something positive about Tony and p90x without the Beachbody caveat. Their content is good. Great. Shaun T, Vytas, and others have created a lot of fun, engaging workouts and programs.
But beachbody has historically had some very questionable practices like their MLM business model. Although thank goodness, it seems they finally ended it a few weeks ago.
Midnight workouts
Back in 2015 (and then again in 2018), a small group of us had a bet with the following rules:
  • Every time a daily workout is missed, you must put $5 into the pot.
  • You cannot do a workout until all previous workouts have been completed.
  • First person to finish 90 days wins the entire pot. If multiple people finish the same day, the pot is split.
  • X Stretch is not required (but recommended) on “Rest or X Stretch” days.
Those were definitely the p90x runs where I most consistently worked out.
Reddit
I had an alt I hardly used named u/greenbeansoup. Although, I rarely go on reddit at all anymore after the API changes in 2023 (that's around the time I dropped my main handle from the about me page on this blog).
Home Journal Prev Next
how.
2025-01-27
Technological advance is an inherently iterative process. One does not simply take sand from the beach and produce a Dataprobe. We use crude tools to fashion better tools, and then our better tools to fashion more precise tools, and so on. Each minor refinement is a step in the process, and all of the steps must be taken.
-- Chairman Sheng-ji Yang,
"Looking God in the Eye"
colophon
I've written previously in new site, who dis on the structure of this site, but not much on how I build it.
Everything on this site is hand-written in vim by sshing into (and attaching to a tmux session on) a linode (named santiago) from my laptop (more recently an M3 Pro named acen, but previously a 10+ year old asus zenbook with long-standing keyboard and not-wanting-to-boot issues). That server hosts this site and some of my other assorted projects.
I check my work on a staging instance of the blog, git push from the staging repo when I'm done, and then git pull from the prod repo to update the live site.
authorship
This blog does not and will not use AI or LLMs to generate any of its content. The code is entirely written by me or scripts that I've written and checked into its zkhr/blog github repo. (I briefly toyed around with the idea in 2023 of sharing dialogues with bots on my site, but I've since removed them.)
permanence
Jeph Jacques made a comment on QC #5458 that he could just go back and fix old comics, but it took him ~20 years to realize that.
I had this similar idea in my head that the content of these journal entries needed to be static snapshots and any changes needed dated caveats (like in birds), but at the end of the day, this is my blog so I can fix mistakes (like "sweet spot" to "soft spot" in pokémon scarlet).
And this is all checked into a git repo, so the history is still there if I want.
Home Journal Prev
Journal
read below or via rss
2025-01-27 -
how.
2025-01-20 -
p90x.
2024-12-30 -
artifacts.
2024-11-09 -
magic.
2024-08-17 -
spacetraders.
2024-06-16 -
university.
2024-06-07 -
looking forward.
2024-06-02 -
zoom.
2024-05-05 -
feed.
2024-04-10 -
godot.
2024-03-21 -
kotlin.
2024-03-15 -
dst.
2024-03-05 -
chromostereopsis.
2024-02-12 -
cookbook.lol.
2023-09-23 -
birds.
2023-07-30 -
project ideas i.
2023-06-24 -
euchre.
2023-02-24 -
three body problem.
2023-01-28 -
css: color.
2023-01-19 -
deck.
2023-01-10 -
roze.
2023-01-06 -
2022 epilogue.
2022-12-23 -
monster sanctuary.
2022-12-22 -
fonts.
2022-12-20 -
board game roundup.
2022-12-14 -
fusion.
2022-12-11 -
hilbert curve.
2022-12-08 -
pokémon scarlet.
2022-12-02 -
puzzle hunts.
2022-12-01 -
new site, who dis.
2022-11-29 -
booggle.
2022-11-25 -
hello world.
Home
Blogroll
RSS feeds I follow.
Blogs
Home on Simon Panrucker! (html, xml)
Chris Coyier (html, xml)
Oatmeal (html, xml)
Piper Haywood (html, xml)
Derek Sivers blog (html, xml)
eieio.games (html, xml)
Comics
FoxTrot Comics by Bill Amend (html, xml)
Extra Ordinary (html, xml)
QC RSS (html, xml)
RedGreenBlue (html, xml)
Sarah's Scribbles (html, xml)
Saturday Morning Breakfast Cereal (html, xml)
xkcd.com (html, xml)
Goomics (html, xml)
Dad Stuff
Bluey Official Website (html, xml)
Gaming News
Topics | FFXIV (html, xml)
Factorio Blog (html, xml)
Rock Paper Shotgun Latest Articles Feed (html, xml)
Tech News
The Unicode Blog (html, xml)
Generated from an opml file exported from Reeder.
Home
board game inventory.
As mentioned in my board game roundup blog post, I love the variety of games out there these days. This page is an inventory of the ones in my closet right now.
If you think there are games I might like based on what I tend to play, send me a message with your recommendations!
Inventory
  • 7 Wonders
  • Android: Netrunner
  • Between Two Cities
  • Boggle (see also booggle)
  • Broom Service
  • Bunny Kingdom
  • Ca$h 'n Guns: Second Edition
  • Codenames Duet
  • Dale of Merchants
  • Direwild
  • Dragonfire
  • Eminent Domain
  • Flamecraft
  • Gloomhaven: Jaws of the Lion
  • Gloomhaven
  • Hanamikoji
  • Horrified
  • Jaipur
  • Jenga
  • Lords of Waterdeep
  • Patchwork
  • Race for the Galaxy
  • Radlands
  • Risk
  • Roll for the Galaxy
  • Scythe
  • Shadowrun: Crossfire
  • Sherlock Holmes: Consulting Detective
  • Sushi Go!
  • Terra Mystica
  • The Big Book of Madness
  • The Castles of Burgandy
  • The Fox in the Forest
  • Trogdor!! The Board Game
Home
reading log.
A quick look at what I've read recently.
2025
A Memory Called Empire by Arkady Martine 2019 scifi
Babylon's Ashes by James S. A. Corey 2016 scifi expanse
Nemesis Games by James S. A. Corey 2015 scifi expanse
The Light Fantastic by Terry Pratchett 1986 fantasy discworld
Emily Wilde's Encyclopaedia of Faeries by Heather Fawcett 2023 fantasy
Cibola Burn by James S. A. Corey 2014 scifi expanse
2024
Abaddon's Gate by James S. A. Corey 2013 scifi expanse
Caliban's War by James S. A. Corey 2012 scifi expanse
Ancillary Justice by Ann Leckie 2013 scifi
Leviathan Wakes by James S. A. Corey 2011 scifi expanse
This Is How You Lose the Time War by Amal El-Mohtar and Max Gladstone 2019 scifi
System Collapse by Martha Wells 2023 scifi murderbot
Fugitive Telemetry by Martha Wells 2021 scifi murderbot
Network Effect by Martha Wells 2020 scifi murderbot
The Adventures of Amina al-Sirafi by Shannon Chakraborty 2023 fantasy
Exit Strategy by Martha Wells 2018 scifi murderbot
Rogue Protocol by Martha Wells 2018 scifi murderbot
Artificial Condition by Martha Wells 2018 scifi murderbot
Project Hail Mary by Andy Weir 2021 scifi
All Systems Red by Martha Wells 2017 scifi murderbot
Nettle & Bone by T. Kingfisher 2022 fantasy
Bookshops & Bonedust by Travis Baldree 2023 fantasy
2023
The Long Way to a Small, Angry Planet by Becky Chambers 2014 scifi
The House in the Cerulean Sea by TJ Klune 2020 fantasy
The Color of Magic by Terry Pratchett 1983 fantasy discworld
Legends & Lattes by Travis Baldree 2022 fantasy
Six of Crows by Leigh Bardugo 2015 fantasy
The Three-Body Problem by Liu Cixin 2008 scifi
Shadow and Bone by Leigh Bardugo 2012 fantasy
Home
The immaterial musings of
Ari Blumenthal
Who?
Journal
Projects
Projects
booggle.
A fictional ghost inspired web implementation of a popular word game involving a 4x4 grid of letters.
Learn more.
cookbook.lol
An online recipe tracker with some simple functionality around sharing, exploring, discussing, and modifying recipes.
Learn more.
roze.
The premier way to get turn notifications in Discord for Sid Meier's Civilization VI.
Learn more.
Home
Puzzle Hunt Toolkit
Assorted tools that I've found useful when working on puzzle hunts.
my tools
ariados is a tool suite that provides a simple anagram checker, pokemon lookup, and a code sheet.
useful sites by other folks
phenomist's Sets of Things is a list of sets of things that show up frequently in puzzle hunts.
enigmatics.org brute force checker for checking strings against a bunch of different encryption algorithms.
Mystery Hunt Word Search to run regexes against various dictionaries. You can also use Nutrimatic and Qat for similar tasks.
MIT Mystery Hunt Puzzle Index: All Keywords to check out similar puzzles from the past.
betaveros’s Have You Tried? to get unstuck.
dCode to decipher coded messages.
Sudoku Solver to solve sudoku puzzles.
other lists of useful tools
MIT Mystery Hunt Puzzle Tools & How-To's
betaveros’s puzzlehunt.net
Home
three body simulation
Start Home