• I’ve been thinking a lot about social media this past week. It’s been hard not to, since for many of us “internet people” the sale of Twitter to Elon Musk has become some sort of political watershed moment on par with the election of Donald Trump. I don’t think I am exaggerating how emotionally affecting this has been for people, because the coverage of it on the internet has been hysterical, exhaustive, and exhausting. I know, because I have been feeling it in my bones, and I’m tired, I’m so, so tired.

    It doesn’t even really make sense, because Twitter was this joke of a website, prior to Elon Musk buying it. Like, ha ha, want to go get insulted by a bigot who is probably a pimple-covered fourteen year old boy (or at least that is what you tell yourself to help maintain your sanity because considering that the person on the other side of the screen is a fully developed adult person threatens to fracture the foundation that every hope and dream you have for humanity rests on), then go on Twitter, right? Twitter’s only real use was for people to take screenshots of others being funny or awful on it and post them on Reddit. So, wait, why do I now feel like this billionaire is taking a hot steaming dump all over one of the most important cultural repositories since the Library of Alexandria?

    When Elon Musk first started talking about buying Twitter, he started calling it the “world’s digital public square” and I couldn’t help but snicker inwardly about how pompous and pretentious it was to act like Twitter–the website that acts as scientific proof that humans have really done nothing with the miraculous gift that is our ability to engage in sustained intellectual thought except to bludgeon each other with it–was an important service to humanity as a whole.

    Like, yes, I get that all sorts of great political stuff allegedly happened only thanks to Twitter and all that, but for the most part, to me, Twitter was the place that gave a bully pulpit to Donald Trump, among other sorts of equally or more egregious things.

    But then Elon Musk bought it, and we started reflecting on what we were at risk of losing, and Twitter took on this sort of mythical quality, like it was truly the last unicorn of social media–our Facebook and Instagrams already sullied, our Snapchats and BeReals making us feel old–and Elon Musk was about to capture it and fuck it to death right in front of us and there was nothing we could do about it! Or was there?

    So a lot of us decided we’d try out Mastodon. I even started up an instance myself! And you know what, that felt good. It felt like I was doing something. I was taking a stand! When Donald Trump got elected, I went to a march or two, I went to a gathering that very night. But there was nothing I could do about that situation. I was completely powerless. What could I do? Write a stern letter? Throw a bunch of money at other politicians who, let’s be honest, didn’t seem that great either, up until that moment (much like Twitter now)? Wait four years and vote again? Oh god, the impotence, the rage. I’m a nerdy looking white male living in the USA, I was not brought up to feel powerless and simply be okay with it. Luckily, when it came to this Twitter situation, I, we could do something: we could leave.

    And so we did, I did, many of us did, in bigly numbers, or so I hear. (But, really, not very many. Especially when you factor in the people who are still using both, the cowards.) We went to the dino site, and many of us promptly began complaining about all the ways it wasn’t Twitter. Not just because that is how Twitter taught us to behave in a new public place, which it did, but because we didn’t want to leave Twitter, or at least we didn’t want to leave Twitter in a way that felt involuntary.

    We used to brag, “Hah! We haven’t used Twitter in months. That old thing?” But it was always there, and that was a comfort, because when we were taking a shit and had scrolled far enough through Reddit porn that we got to the ugly people no one wants to upvote, we could load up Twitter, and get angry at someone saying something we think is very stupid, which is just another kind of pornography when you think about it. But now our desire to use Twitter came right up against an even more unstoppable force in the universe: our desire to publicly broadcast that we care so much about a perceived injustice or unfairness that we’re willing to just barely inconvenience ourselves to make ourselves feel better about it, but without making any sort of a difference to the actual problem. You know, like a plastic straw ban. But this time, for Twitter.

    So we left Twitter, but we did so begrudgingly, except for those of us especially well equipped to huff our own farts, and hats off to you people, may you always have the strength of your convictions. But for the rest of us, Mastodon is basically methadone and we’re still sitting around jonesing for a hit the real stuff, the good stuff. My heart goes out to the truly pathetic cases, the people with a foot in both worlds: those using crossposting services. Shame on you. You disgust me.

    But, wait a second, hold on, back up… How did we get here? Why did “Elon Musk Buys Twitter” become such an important cultural moment? Who is this guy, and why do we hate him?

    For a while, Elon Musk was just the rich car and rocket guy who clearly wanted to be seen as cool. Then all of a sudden he’s taking pictures next to Donald Trump and smoking weed with Joe Rogan and it was like, wait a second, is this guy evil? And by evil I mean, obviously, that when it comes to the things that I think are really important, he does not think they are important at all. Plus, he’s like super smug, and my sense of justice really depends on people who are arrogant and wrong having bad things happen to them. This is what movies and television has taught me to expect and it’s really upsetting when reality doesn’t match up. Something has to happen! Twitter is going to crash, right, it’s going to literally explode, it has to! Excuse me, manager–wait, no–God, can something be done about this guy whom I do not care for?????! HELLO???

    Shit, hold on a second, I’m angry again. I wanted to be objective. I wanted to tackle this topic as nihilistically as I possibly can, because that seems to be the only way I can have any sort of healthy relationship with it. But when I think about all the stuff I know about Elon Musk, and that I know about what he’s done at Twitter, and to all those poor innocent Twitter employees, the little powerless little tykes, god bless their souls, I get overwhelmed and I think–damn, I need to load up Twitter, or the News app, or Reddit, or, gasp, Mastodon and see what latest bullshit Elon Musk is up to now!

    Our lizard brains aren’t conditioned to think critically all day long, especially about topics that overwhelm our senses. If you go anywhere on the Internet, you are inundated with opinions about Elon Musk and his Twitter takeover, and most of them are very negative (and gleefully so; maniacally so, to be less charitable), and when we see a lot of people with whom we already share opinions, sharing a new opinion with us, we think: wow, this must be Important. We don’t think: wait, should I actually care about this topic? Sometimes we do, like when I see an article about how mentally and physically unwell Selena Gomez is (answer: I do not), but most of the time we’re tricked by all kinds of little unconscious signals into letting stuff like this leak into our own thoughts and feelings. Suddenly, before I know it, I’m spending several hours setting up a personal Mastadon instance that’s going to cost me at least $20/mo on AWS, essentially giving money to one billionaire to assuage my discontent about another.

    This is the way Twitter has conditioned us to behave, like every event is either the best or worst thing that has ever happened in the entirety of human history. Elon Musk might not be that wrong when he says Twitter is essentially the world’s public square, because it is where we all get our marching orders when it comes to the direction of the mass hysteria of the present moment. And that’s the only way I can describe the feeling that can sweep social media at this point, it is a shared moment of pure hysteria, where our rational minds shut off and things that were silly moments ago now seem so dire that our flight or fight instinct kicks in.

    I don’t know about you, but I don’t want to live like this. I don’t want to even know who Elon Musk is. I don’t want to care about what happens to Twitter. Do we even want to live in a world where Twitter is this important? Twitter? Remember when we cared a lot about Hong Kong and Ukraine, certainly those were more worthy topics (though all we did about them was, ohpost on Twitter, well, we can virtue signal just as well on Mastodon–but who will see it, I hear your cries in my own head, in my own voice).

    Surely there must be something else for us to care about, anything to get us out of this endless cycle of ragebait news stories, precision engineered and algorithmically boosted to force us to care about things we really shouldn’t. How about ourselves? Is that even possible? Can I care about myself as much as I care about Elon Musk?


  • Diablo Immortal came out a few weeks ago. If you’ve been living under a rock for the past few years, this is the free to play mobile Diablo MMO that was announced to great fanfare years ago. I wasn’t planning on playing it at all, despite my love of ARPGs, because MMOs turned me off for a long, long time. But in the past year or two, I’ve played a few MMOs: Guild Wars 2, Elder Scrolls Online, Final Fantasy 14, and most recently Lost Ark.

    Diablo Immortal owes a lot to Lost Ark. DI is essentially “Lost Ark, but Diablo” in many ways. But I guess that’s sort of over-specific, because the best way to describe Diablo Immortal is to say that “it’s a Korean free to play MMO, but Diablo”. It has all the classic MMO mechanics, like limited daily quests and routines to get into.

    I was very hyped for Lost Ark, but eventually realized that it isn’t really a typical loot-based ARPG. Instead of killing monsters to grind out loot drops, you’re really just accomplishing tasks to hoard materials that you then use to improve your gear. Diablo Immortal is a bit of a middle ground: yes, there are tons of different currencies that you need to upgrade legendary gems, but there’s still a strong foundation of killing and looting to get incrementally better legendary and set gear.

    The core main quest is very Diablo 3, very typical ARPG. It’s a fun experience and you can have probably 40+ hours of fun for no money at all. That’s a great value, right there, and for the casual player there is a solid sequence of milestones to keep you progressing: first you want to complete the main quest, then you want to hit level 60, then you want to get your paragon level up to 30 to be able to unlock Hell 2 difficulty, and then… well, to me it seemed like the next obvious milestone was to be in a Dark Clan that achieved Immortal status.

    That seems to be the real endgame of Diablo Immortal. There’s a very neutered version of the typical MMO “World vs World” concept where the various clans in DI compete every week or two in a ladder competition to see who can rise to the top, called Shadow War. The winning clan gets to pick two other clans to become “Immortals”, who then get access to some special shop items and are used in a special PVP mode called “Raid the Vault”. So it seems like that’s kind of the true goal of Diablo Immortal, to win this ladder and become Immortals.

    And that’s where the game falls apart for users who don’t want to spend money, and where the massive internet hate machine around the game truly kicks into overdrive, because most of the game prior to this point is PVE and it doesn’t really matter what kind of gear you have unless you’re absolutely desperate to progress through the PVE difficulty levels.

    If you wanna play 60 hours of a game for free and then bounce off it (like most people do, I assume) then none of this should actually matter to you. But if you’re the kind of fool who feels like you want to ‘complete’ a game before you move on, then this Shadow War mechanic is designed specifically to try to extract money from you, and to make “whales” (people who are willing to spend thousands or tens of thousands of dollars on the game) feel like they’re getting their money worth.

    I say this because it’s probably impossible for any clan to win the Shadow War without a bunch of whales on the team, because they have such clearly superior gearing that there is no way for a free player to beat them. And hey, if they spent that much money on the game, I guess they should always win. You can understand that financially it would be a bad move for Diablo Immortal to ever let those whale players feel bad about anything, because then they’d take their massive bags of Saudi Arabian money (assumably) to some other game.

    Once the whales become Immortals, the Raid the Vault game mode becomes very unsatisfying for most players. In that mode, you’re in a party of four people fighting PVE mobs to collect some other form of currency. After a floor or two, NPC Wardens start calling out for Immortals, and four people from an Immortal clan will join the game and, being whales, they will instantly obliterate you and kick you out of the vault. It’s not great, it feels bad, and it’s no fun.

    So, I followed the path that I could follow: I beat the main quest, I got to level 60, then I got to paragon level 30, discovered that in order to progress in Hell 2 difficulty in any way, I was going to just have to grind out gear and likely never achieve any real level of power or success in comparison to the people who were willing to shell out more money, and realized that there was little to no chance I was going to make any sort of meaningful contribution to a clan that was going to win the Shadow War. So… I bounced off.

    There’s also one other reason for my departure: I paid $10 for the battle pass. In most games when you buy a battle pass, there’s an optional upgrade (usually $10-15) that jumps you ahead in the battle pass. It’s totally optional in mostly all games and you can grind out the battle pass content yourself, so I skipped it in Diablo Immortal (it’s called the “Empowered Collector’s Battle Pass”). Imagine my surprise when I hit level 40 (max level) in the battle pass and I still didn’t have the full cosmetic set promised in the battle pass. Then I looked closer: if you want the teleport cosmetic and the blue avatar frame, you also have to buy that battle pass upgrade for another $10.

    Well, there’s no fucking way I am doing that. I am not paying $10 just for a teleport cosmetic and an avatar frame. At the same time, I feel extremely insulted and misled that there are battle pass related items that you can’t get unless you paid $20 for the battle pass instead of just $10. It just seems so incredibly greedy in the end. I paid $10 for the battle pass, $10 for the ‘boon of plenty’ to show my support, and then $20 for the “Prodigy’s Path” that gives you legendary gems as you grow in paragon rank. So all told, I spent $40 only to be told at the end of the BP “lol jk you gotta give us more money if you want the full BP cosmetic set”. No, nope, not going to do that. That’s a bridge too far for me.

    All told, with the amount of time I got out of the game, my cost per hour of enjoyment was less than $1, which is still a pretty great value when it comes to a game. It’s just too bad the very end of my experience was kind of shitty and negative. I think that really sucks.

    So to punish Blizzard for their transgressions I went online and bought Diablo 2 Resurrected and I’m having a ton of fun with it. C’est la vie.


  • The Staircase, the new HBO series that just wrapped up, was very entertaining. I didn’t watch the original documentary, but I had read an article all about “the owl theory”, which I had found very convincing, so I was vaguely familiar with the murder of Kathleen Peterson.

    To someone unfamiliar with some of the details of the case, it was very easy to feel like the series was giving a lot of credence to the owl theory, by repeatedly showing Kathleen being spooked by owl sounds outside. Is the subplot with the bats a further allusion to Kathleen’s alleged issues with wildlife? Probably?

    The series leaves out certain facts about the crime scene that can strongly influence your opinion about Michael Peterson’s innocence, and I think it’s extremely suspicious. I can understand that the show, for the sake of suspense, may want to paint an somewhat ambiguous picture of Michael early on, so they can hit you with more damming evidence later, but by the end I don’t think the show went far enough in this regard.

    Before the last episode of the show aired, I did some googling and found a lot of people who were like me: people who felt like Michael Peterson wasn’t guilty beyond a reasonable doubt, and the show didn’t help remedy this perception much. But after finding a very eye-opening post on Reddit about the case, all doubt was gone for me, and by the end of the show I ultimately felt like it was extremely misleading.

    I felt the same way after the 2018 Waco series which portrayed David Koresh as a likable rockstar character and not the sociopathic child molestor he actually was. To the credit of The Staircase, it’s not as egregious as the Waco series in regards to making the psychopath at the center of the series seem super cool and hip, but I still call into question the compulsion to create media that feels a bit like the narcissist himself was involved in crafting their portrayal.

    Sure, you could say it’s so that the audience can sort of feel what it was like to actually be there, and to be so thoroughly suckered by the charisma of these men, but I really don’t think that is much of a defense. At the end of the day, these were men who did bad things, and leaving out details and events so that the main character of the show still remains somewhat likable is just dishonest and manipulative.


  • I recently purchased a cheap electric guitar setup so that I could take my third… fourth?… try at learning to play guitar, in the hopes that I can start writing songs. I knew from experience that I would want some sort of audio interface for the guitar (for recording) and that I wanted to use virtual pedals on the iPad (for playing around & recording) so I ordered an IK Multimedia iRig HD 2 at the same time.

    A few weeks later I got an email from Fender advertising the Fender Mustang Micro which seemed, to me, like a good idea, because I’d already noticed that it wasn’t 100% convenient to just “pick up and play” my guitar.

    At a minimum I needed to plug the guitar into the amp, turn the amp on, and then depending on my surroundings either adjust the volume to not annoy anyone, or also plug in some headphones. On top of that, I was “stuck” wherever I placed the amplifier, which made life more complicated when I moved the amp from one side of the living room to the other. The guitar set I got came with a basic amp with some basic gain options, not much in the way of effects to monkey with for fun, either, so the iRig was necessary if I wanted to experiment with different tones and gain levels.

    If I didn’t want to use the amp for practice, then I’d have to use my iPad and the iRig somehow. This meant I’d have to get the iPad out, plug the iRig into the iPad, plug my guitar into the iRig, plug my headphones into the iRig, and then load up GarageBand or ToneBridge and get going. This was a lot of cables, and there was no way for me to do this without headphones: when you plug the iRig into the iPad, your iPad is forced into piping audio out through the iRig’s headphone jack. So if I wanted to listen to my playing without headphones, I’d have to plug the iRig’s headphone jack into speakers somehow. I’d done this with a mini-plug to RCA cable to my amp, but I could also do it with a portable speaker so long as it had wired input. But… so many cables everywhere!

    The Mustang Micro seeks to solve this problem. It’s a tiny little device that plugs directly into your guitar, and has a mini-plug output for plugging in your headphones. It has 12 different virtual amps built in, with 13 effects that can be used with each, and has EQ and Modifier buttons to adjust the sound of your guitar with each amp and effect. It’s also fully self-powered with a rechargeable battery. This is a big benefit over the iRig HD 2, which sucks power from a device over USB and cannot be used on its own. In the end, the Mustang Micro takes all the “headache” out of being able to just pick up a guitar and practice with it whenever you want.

    The Mustang Micro has Bluetooth support for getting audio into the device. The main use for this is that you can connect your iPad via Bluetooth to the Micro and listen to your lesson videos, or favorite songs, while playing along. You hear both your guitar (with any amp and effects) and the iPad audio in your headset, and the ‘mix’ of the audio for each is dependent on the Bluetooth volume of the iPad. This is pretty slick and very useful.

    When I eventually discovered that you can also plug the Mustang Micro into the iPad to use it as an audio interface, I got very excited, but also annoyed: Did I waste $120 on the iRig 2 HD? The Mustang Micro seems to do all the same stuff!

    The answer, ultimately is “no”, for one very big reason: when you have the Mustang Micro connected to an iPad via USB, it does not receive any audio from the iPad, it only sends audio to the iPad. If you want to hear what is happening on the iPad, you have to connect the iPad to the Micro via Bluetooth.

    Problem solved, right? Nope! Whatever you hear over your headphones connected to the Micro is exactly what is sent back over to the iPad. In other words, with Bluetooth connected to your recording device, you’ll create a massive feedback loop, where your guitar will be playing over itself, along with whatever else you’re playing while recording.

    If you want to use the Mustang Micro for recording, you’ll want to plug your guitar into it, and then get audio out of your device some other way. Unfortunately with the iPad Pro, there is only one USB-C port, and no audio output, so there is no other way to get audio out other than the speakers on the iPad itself. You could wear some wireless headphones, but there will always be a delay associated with that.

    If you have an external audio interface for your iPad already, and a suitable USB hub so you can attach multiple devices to it at the same time, this may be a non-issue for you. I’m assuming that most people reading this are relatively new to guitar, and recording, and don’t want to buy several devices to record themselves playing at a decent quality.

    In Summary

    If you’re looking for a device that can act as an all-in-one recording solution for your iPad, the iRig HD 2 is the best option.

    If you’re looking for a device to make practicing as hassle free as possible, and want to easily add more tones and effects to your noodling sessions, the Fender Mustang Micro is the best option.

    That said, if you already have a recording environment set up that doesn’t involve an iPad, or you already have a USB hub with a separate audio interface for your iPad that you use for monitoring, the Mustang Micro might be perfectly suitable as a solution for recording your guitar.

    If you feel like you have to choose just one, I’d go with the Mustang Micro. While you can’t use it for all-in-one iPad recording, it’s still an impressively versatile device that will not go unused in your toolbox. In the event that you want to do some guitar recording, it’s still a great tool. It’s just not suitable for people who want to do all their recording on an iPad with only one gadget attached.

    I’ve seen people online who use the Micro connected via a mini-plug cable to a portable speaker so they can play out in public. Nifty! You could do that with an iRig 2, but you’re still looking at a lot of cables and devices to accomplish the same goal.

    Fender Mustang Micro

    • Great device for easy “pick up and play” practice
    • Lots of built in virtual amps and effects which makes it superior to products like the amPlug series
    • Self-powered with a 5-6 hour rechargeable battery
    • 1 cable minimum for playing: just the headphone cable
    • Not an all-in-one solution for recording music with an iPad
      • You can not monitor with headphones and record at the same time
    • Allows you to play sound out of a connected iPad’s internal speakers
      • You can noodle with virtual pedals without headphones on
      • You can record this way if you wanted, but it’s not ideal in my opinion

    IK Multimedia iRig HD 2

    • Great device for recording to iPad
    • No built in effects
    • Not powered, requires a USB device to power it
    • 3 cable minimum for playing: guitar cable, headphone cable, and USB cable
    • All-in-one solution for recording music with an iPad
      • You can monitor with headphones and record at the same time
    • Cannot play sound out of a connected iPad’s internal speakers
      • You cannot noodle with virtual pedals without headphones or an external speaker attached


  • Last week I got my Panic Playdate in the mail. I preordered it last July, and have been following it since the May 2019 EDGE announcement, so you could say it was a long time coming. It’s such a nice feeling device, and good looking, too. Sure, the non-backlit screen can be annoying, but I firmly hold the opinion that portable gaming is pretty stupid, so I’m not jumping on the bandwagon of acting like no backlight is some sort of extreme deal breaker. I was looking forward to building things for it, and the general feel and look of the thing just makes me extra excited.

    My last stint of game development aspirations were cut a little short due to PICO-8’s code volume limitations. I hadn’t actually run up against those limits yet, but getting close to them filled me with so much anxiety and dread that I just couldn’t keep going–it was clear there was never going to be enough room for me to build the game I truly wanted to make. So, it stopped being fun, and I quit.

    Playdate development promises to be less anxiety inducing. There is no limit on how much code you can write, beyond the physical limitations of the device itself, which is very generous in regards to RAM and storage space. There are new restrictions, though: unlike the 16 colors available in PICO-8, the Playdate has only two colors: black-ish and gray-ish (technically black and white, but on the device both colors are more silvery). This presents an extremely interesting challenge for someone like me, who has no confidence whatsoever in his artistic abilities.

    I decided to start with what I know, and built a spaceship flying around, similar to my PICO-8 game, but also significantly different.

    I’m using some icons from The Noun Project (disclaimer: I work there) that I quickly redrew in Aseprite (to varying degrees of success).

    Another new challenge is that because the screen is so small, high resolution, and not backlit on the physical Playdate, you have to make your sprites pretty large to make them legible. The Playdate simulator inadvertently downplays this issue by virtue of being so large on your screen (Panic should create an option to remedy this). This is a big change from PICO-8’s gigantic chunky pixels, where a single pixel can be perfectly visible to the player.

    Because of that, the way my space game worked on PICO-8, where every ship was a single pixel flying around a large star map you could freely explore, simply won’t work on the Playdate. It’s forced me to think of a different way to adapt the general gameplay loop, and I think I’ve come up with an idea I like and will pursue. I won’t talk about it yet, we’ll see if I build it.

    I wanted to spend some time contemplating the aforementioned game idea, but wanted to keep building. So I decided I’d try porting my MultiClock screensaver over to Playdate. Figured it would be a fun programming challenge, and I was right!

    The biggest difference is that SpriteKit comes with performant methods for rotating sprites in real time, part of its animation system. You can rotate sprites in code with Playdate, but it is processor intensive so they do not recommend doing so. So instead I had to draw the clock hands in Aseprite, something I’d never used before, and create each frame for the hands rotation. In the above video, we’re up to 32 frames, almost enough to make the rotation look pretty smooth. Maybe not yet as smooth as I’d like, but the next jump is from 32 to 64 frames and that’s going to be a bit tedious.

    Right now I really just have the time display working, none of the animation system or alternate patterns from the screensaver have made it in. I am pretty sure I’ll be able to build the animation system out similar to how it works in the screensaver, with a queue and callbacks and so on.

    I figure this’ll look nice when and if the Playdate Stereo Dock comes out some day.

    Oh, also, I bought Panic’s new code editor, Nova, to use for Playdate development. Figured it would be “more fun” to build Playdate stuff using all Panic software, and besides, any excuse to give Panic my money is a good one. It’s a nice feeling app. Nice enough for me to give up GitHub Copilot during my day job? Probably not. But I dunno! The urge to be a total and complete Panic fanboy is pretty strong.


  • Howdy! This is my weekly post where I talk about whatever programming stuff I’ve been up to.

    MultiClock

    This week I made two small changes to the MultiClock 1.2 Beta PR to add an option to remove the dial design. I realized a day or two ago that it was kind of weird there was no “None” option for dials, though I don’t think the screensaver looks very good without a dial. But I already think some of the options don’t look good, that’s not really for me to decide anyway… to each their own!

    I also finally remembered to enable ignoreSiblingDrawOrder, which is allegedly a good optimization strategy, because, well, this person explains it as well as I could it:

    When ignoresSiblingOrder is false, SpriteKit renders nodes in the order they exist in their parent’s children array — that is, the array order determines which one draws “on top of” the other. It also means SpriteKit has to render each node one at a time, so you’re losing efficiency to OpenGL draw call overhead. 

    When ignoresSiblingOrder is true, SpriteKit relies exclusively on the zPosition property for figuring out what order to draw in. This means it can sometimes combine everything at the same z into a single draw, which makes rendering faster. But it also means that if you want to control which nodes draw in front of which others, you need to set their zPosition appropriately.

    rickster on StackOverflow

    Version 1.2 contains the very important animation system changes that fixes multi monitor support, but I still feel like it needs something more to justify its full release. I’m not sure what though. I do kinda want to redo the animation system more so that hands can move at variable speeds, and possibly even in multiple directions, but… Not feeling that pull strongly enough yet.

    There’s also the Apple TV version, kinda forgot about that idea…

    Not Much Else

    Haven’t been up to much else. I spent a bunch of time playing Lost Ark, and now Elden Ring, so I haven’t been coding again. I am starting to feel the itch though, as evidenced by me changing this website up. Building out the products page made me look for screenshots of Textile, and it really made me miss how much fun it was to play a game that I was building out, so maybe I should pick up work on rpg-laravel again.

    We’ll see! Elden Ring is pretty soul-sucking. I think I can hear it calling to me now, gotta run!


  • I migrated this blog from Gatsby to WordPress. I’m sure to many people that sounds insane. There’s so many tutorials online on how to migrate in the other direction, and even plugins that export all your content to Markdown files to stick into Gatsby, but nothing if you want to go another way.

    I’m doing it mainly for ease of use. I’m old school, I’ve been using WordPress since 2003 at least. HTML and CSS are in my blood. You know what isn’t in my blood? JavaScript, React, dealing with NPM. Eventually I gave up trying to modify my Gatsby site because getting the dev environment to run locally became headache inducing.

    WordPress, on the other hand, is very easy to reconfigure. I just update the CSS file! I started with BlankSlate, a set of template files with no styling applied. It was perfect for me. I didn’t want to have to learn what all the new template files and methodologies were. I just wanted something I could style and hack around, and this theme was perfect.

    I also wanted to be able to easily write posts on my site, without having to load up a git client on my phone. Being able to load up the WordPress app on my phone and write this post on a whim at my kitchen table is a serious perk. It’s also much easier to add photos and videos to my posts, I can upload them right in the interface. WordPress gets a lot of flack from engineers, but you really can’t beat the ease of use.

    (Not everything is perfect, the new posting interface can be a bit glitchy and annoying at times.)

    In a similar vein, I wanted to be able to toss off small, microblog style posts without titles, kinda like media rich tweets. WordPress isn’t 100% built to be happy about posts without titles, but it works, and it was extremely easy to modify the styles so that micro posts have a Twitter-like post format, and long-form posts have a more traditional blog look.

    It boggles the mind that I have been blogging in some form for 23+ years now. What is time? It seems like it wasn’t that long ago that I was an angsty freshman in high school, using Blogger. Now I’m an angsty adult, on the precipice of my 40’s, still using WordPress. The time, it flies! Either way, you should be able to expect me to write and share a wider variety of content on here now.

    We’ll see!


  • Howdy! This is my weekly post where I talk about whatever programming stuff I’ve been up to. Let’s just dive right in!

    dotBeat Internet Time

    You might have noticed that last week I released a small macOS app called dotBeat Internet Time. Let’s talk a little about the why and how I built it.

    When I started streaming a few weeks ago, I figured it would be a good idea to think of future ideas to build on stream. I even started a GitHub Project for stream ideas. Earlier in the week, my friend Dan Crum and I had been talking about the glory days of the internet, and one of us mentioned Swatch Internet Time, a throwback to 1998. I thought of this when coming up with project ideas, I thought it’d be pretty easy to create a menu bar app to show the internet time, and threw it on.

    Before setting to work however, I wanted to size up “the competition”, to see what else was out there already.

    The first app I found, BeatBar does the job, basically. It shows the internet time in the menu bar, and then features a drop-down SwiftUI interface for converting internet time to local time and vice versa. There’s a couple downsides to this app, in my opinion:

    1. It uses SwiftUI, which means you must be running macOS Catalina or newer, which I learned with PiBar is a big negative to some people.
    2. The drop down UI is confusing, with two sliders that change times in a weirdly arbitrary way (the top slider does increments of 10 .beats, the bottom slider does increments of 15 minutes).
    3. The app is priced at $4.99 in the Mac App Store. That seems like a lot of money to me.

    Next up, iBeatTime in the Mac App Store is a free app, which also displays the internet time in your menu bar. It has a ‘converter’ interface for changing your time to internet time and vice versa. Somehow the interface ends up being even worse than BeatBar, with just two fields and you have to select which conversion you want to do. This makes little to no sense to me, but at least the app is free.

    BeatTime has apps for every platform, but the macOS app is basically a glorified widget and doesn’t appear to display the time in the menu bar.

    There are also a couple iOS apps in the App Store, like Internet Beat and Swatch Beats and they all look pretty terrible. There’s an Apple Watch only app, @Watch which doesn’t look too bad.

    So all in all I came away with the impression that there’s definitely room for improvement in regards to the apps out there currently. They either have somewhat bizarre UX or just poor design and appearances in general. I figured I could definitely do better, though there isn’t exactly a lot of space for improvement: displaying the internet time in the menu bar is pretty straightforward, and the ‘converter’ function doesn’t seem that elaborate. In one app I saw (not sure if I found it again and linked to it above) the ‘converter’ functionality allowed you to set a timezone. This seemed like a good idea to me: when you receive an internet time, you obviously need to convert it to your local time; but when you are sending an internet time, it becomes more important to be aware of what the other person’s timezone may be. You don’t want to set an internet time that is going to be 3AM for the recipient.

    But what does a good UX for that look like? The one app that had this feature just had a bunch of timezones in a drop down. This works, I guess, but you have to already know what timezone the person is in, and when you have one timezone picked, you can’t see the others. So I figured… why not display them all? Additionally, I simplified the ‘selection’ interface down to a single scroll bar. This scroll bar adjusts the .beat from 0 to 999, showing you your local time the whole way. No need for multiple scroll-bars or different inputs.

    You can watch me build most of the app and ruminate over these design decisions in the VOD for the stream. The stream misses out on some of the more fun work, like programmically building out the massive timezone UI, which you can see in the final SimulateTimeViewController. You can see the code is actually pretty simple. I set up an array with all the timezones I want to display (and there are actually many more timezones than the 32 I display in dotBeat) and a fallback name in English. Then when the window loads, I iterate on that array and do some extremely lazy pattern matching to set up all the constraints for them.

    It’s really Apple’s Date, TimeZone, and DateFormatter classes doing nearly all the heavy lifting. You get a lot of good functionality out of those classes, namely localization. While I haven’t run dotBeat in any non-English locales, it should automatically adjust the times and names of the timezones to match a users locale. If you set your mac to use 24-hour time, it’ll change the times in the app to match. That’s pretty neat!

    As with my other projects, dotBeat is open source and free to download. You can check out the source and download it on GitHub. If you’re interested in supporting me as a developer, you can also purchase it for $1.99 on the Mac App Store.


  • This week on stream I built a small macOS menu bar app I’m calling dotBeat Internet Time. It’s a small, focused app with two features: 1) It displays the current Swatch Internet Time in the menu bar, and 2) It allows you to figure out how Internet Time corresponds to your local time, as well as most of the timezones on earth.

    What is Internet Time? Back in 1998, Swatch (the Swiss watch company) thought that in our rapidly globalizing world of the early internet, a globalized method of telling the time was necessary. They decided that each 24 hour period would be broken up into 1000 “.beats” instead of 1440 minutes, and that they would start counting from midnight “BMT” (GMT+1). These beats are notated with an @ symbol. So for example, @42 is 4:00 PM local time in California, but it’s 5:45 AM the next day in Nepal.

    dotBeat Internet Time screenshot

    You can download it for free from the releases page on GitHub.

    You can also buy it on the Mac App Store for $1.99, if you want to be nice and show some support for me as a developer.

    The app, like my others, is open source.


  • Howdy! This is supposed to be my weekly post where I talk about whatever programming stuff I’ve been up to. Let’s just dive right in

    Laravel & Streaming

    Like I said last week, I planned to start streaming this week and was going to use it as an opportunity to learn Laravel, so that I could make a web-based game. Well, I did it! I streamed four times (Monday, Tuesday, Wednesday, and Friday) for 3 hours each time. The only full-time viewer was my friend Dan, though a few people wordlessly filtered in and out. I don’t think it’s very exciting to watch me program, though you do get to hear about my thought process as I build things.

    The first two days of the stream were spent watching this Laracast series, Laravel 8 from Scratch so that I could learn some of the basics really thoroughly before jumping in. This was a bit of a slog, the tutorial lies in the sweet spot where an inexperienced programmer could get lost, and an experienced programmer could get bored. I got bored about 7 hours in, which is pretty good considering it was a 9 hour tutorial.

    Instead of jumping into my ultimate goal project, I decided to revisit an old project of mine called Textlike. It was a very rudimentary web-based roguelike I built out of PHP about 10 years ago. I figured it would be cool to try to rebuild it in Laravel, since it’s inner workings are still somewhat familiar to me, so I can focus on learning the ins and outs.

    By the end of the week, I got pretty far into some of the basics: floor generation is complete. Initially I got moving between rooms working, and once that was working I set my sights on handling room generation. The way Textlike generated rooms 10 years ago was entirely on-demand and didn’t make for very interesting floor layouts. This time around I decided to lean on maze generation, which I researched a bit. Then I found some existing PHP code and adapted it for my needs, using it as the data model used to create all the rooms on a floor and define the connections between them.

    So now some important things are done: account creation (very easy thanks to Laravel Breeze), character creation and deletion, and room navigation. I’ve already got enough code in place that I think it’s starting to get a bit smelly. I’ve put a lot of business logic inside my models, which I think is a code smell. I’m also not well versed in Laravel Livewire best practices, and I feel like the way I have things set up right now is a bit weird, with multiple components… I could get more into it, but maybe I’ll wait for a later post once I know more about Livewire.


    That’s actually it for this week. I’m writing this on Tuesday, so I’m late, and I’ve already done some cool things I’ll have to write about next week! Maybe there will be an announcement post tomorrow, for a project I started on stream yesterday and finished today. We’ll see!