Advertisement · 728 × 90

Posts by gabe

This may be one of the best posts following a feature release of an OSS program I’ve seen in a long time. So informative, including for readers that might be less familiar with details like Lua syntax. I’ll be switching to vim.pack ASAP.

3 weeks ago 2 1 0 0

Very well put. I think it really highlights the distinction between those using AI to help People and those using AI to help only themselves.
The folks in the latter camp may lie or not even know they’re in that camp, but they don’t have to acknowledge it for it to be true…

3 weeks ago 0 0 0 0
I Can't Help but Code I know how good LLM agents are at writing code, now. I have access to very modern models and tooling through my job. Some of my coworkers chew through the usage limits within days to prototype and refactor. I use them to write out explicitly-explained code in 30 seconds that would’ve taken me 10-20 minutes to write. That genuinely can save me hours a day. But when I sit down to start my new fun niche project, or when I do some voluntary programming for the MMO I help run… I just can’t help but write the code myself. I have LM Studio set up and hooked into both Zed and a VSCode extension (though admittedly my tool of choice for writing code is neovim). I can generate text using qwen3-coder-30b at a perfectly reasonable pace on my desktop. My work laptop with access to the latest models is sitting right next to me. But I can’t stop myself from coming up with how _I_ would implement the thing and end up just doing it myself. I like the **style** of code that I write. I inject my voice, I make silly comments and commit messages, I format things in a particular way. I like **writing** the code itself. I've fine-tuned my neovim config to make the process of getting what's in my brain onto the screen as effortless and joyful as possible. The dopamine hit received when the code I wrote works is proportional to how much **effort** I put into making it work. Sometimes it can come from the pride of how quickly I got something to work. “It worked first try!” feels very different when you typed (or tab-completed) every symbol compared to when an LLM generated them all. In the end I’m looking a reflection of myself and I’ve potentially even discovered something small about my consciousness. I'm not exactly trying to compare programs and art, though it can be a valid comparison in some cases. I’m reflecting on my instincts despite the practicality of the tools made easily1] available to the modern programmer. Though, maybe some day people will more commonly start paying attention to how software is made instead of how well it works. It makes me think of stores like Etsy and how ["handmade" things can feel cozier than their mass-produced counterparts. * * * 1. arguably at the notable expense of freedom, the environment, and human rights, but I digress ↩︎

I Can't Help but Code (https://dabe.tech/posts/handmade-code/

3 weeks ago 1 0 0 0
The Year of the Linux Desktop will be Distroless Every now and then I see blog posts[1] lamenting Linux Desktop experiences. Some lovingly and some with genuine frustration and disdain. When I read these, I tend to feel emotions ranging from mutual frustration to the desire to offer help. The help often takes the form of “it’ll work if you use X!” or “try starting from scratch, the defaults are much better now!” which I’m certain everyone writing blog posts about Linux have heard a thousand times by now. I then quickly realize that everyone has different goals and needs when setting up a Linux desktop, so it’s kind of a futile effort to offer generic, default-based help. I figured this is just the way FOSS desktop computing is and sometimes people just need at least a little case-specific help to get things up and running. In my view, this pitfall is the main roadblock in the way of Linux from taking off as a major contender for widespread desktop adoption. However, I have a feeling that “distroless” desktop images will change this reality in the near future. Distroless is a concept relating to containers. The idea is to slim the contents of a container down to only the minimum components needed to serve the intended functionality. The universal blue (ublue) project has taken the term in a new direction (it might actually be unrelated to the prior meaning but I figured it was worth mentioning) and is applying it to the desktop as a whole. The practice utilizes emerging and increasingly stable tooling for building and running bootable container images[2] that aren't tied to any specific suite of apps or settings. They're essentially cutting out everything that makes a distro a "distro" and offering building blocks to layer in reproducible functionality, just like we do with container images for software now. One of my personal favorite aspects of bootable containers and atomic desktops is that with a single command, anyone helping you troubleshoot your system can know the exact base state of your system, since it's unchangeable and consistent for everyone else using that image. I feel like this has the potential to supercharge community assistance efforts and massively stabilize desktop functionality. The days of losing audio output, webcams not working, and network interfaces acting up may be fully coming to a close. If the ublue project continues on its trajectory, problems may arise that sound very familiar to the desktop incumbents (Windows and macOS). Problems like bloated base feature sets to accommodate every possible user, large and frequent updates, and over-opinionation. However, it's all still Linux, and the concept of distroless empowers flavors and spins that can serve pretty much any group of people with a shockingly out-of-the-box experience. As the core tooling evolves and matures, I really believe that desktop Linux will thrive under this new paradigm. **So get out there and go check out a ublue image in a VM!** The more tinkerers that use it and contribute to the user experience, the faster the whole thing can become "average user ready".3] Ublue [likes to openly share rough user counts and stats so you can see how many other people are trying things out along with you. That's the important part of what I want to get across, but I've written about my personal experience transitioning to and daily driving ublue images, if you're interested. ## My Experience Now, when I first came across ublue and the images that build from it like bazzite, I initially rolled my eyes at the terms used like “cloud native” and “atomic” and passed on it all. I assumed it was just some new experimental niche project. I’ve fiddled with immutable (Fedora brands them as atomic) desktops before. I was put off by the tooling and didn’t see enough benefit to actually switch my main machine to something atomic. I don’t yell at clouds and I absolutely love containerization but I also know that “the cloud” is quite a common buzzword for tech marketing. Things changed while I was hanging out in a Discord server and someone mentioned that they’d been using bazzite for a while now as their daily driver. I thought, well, bazzite is some gaming focused distro right? That seems silly to rely on for general-purpose tasks. But I had just finished having a good conversation with this person so I gave it another really good look. Within an hour or so, I was convinced that I needed to try this as soon as possible.[4] To avoid major disruptions, I ran bazzite in a VM in my main desktop for about a week before fully switching over. Every time I did some task, I tried that same task out in parallel in the VM to see how my workflow would change. My biggest concern was development and software tooling, since that’s half of what I do with my desktop. Within a day or so I found myself just doing entire development cycles inside the VM, not really missing a beat. This was thanks in large part to tips provided by the bazzite documentation. The read-only filesystem necessitated that I make some changes to my workflows, but these changes honestly excited me. I quickly recognized that my computing environment was more organized and that I was avoiding behaviors that could be bad for the long term health of my desktop. It helped that I’m already a big proponent of flatpaks and have years of experience distro-hopping[5] without losing my personal data in the process. Once I installed bazzite on my bare-metal hardware, I was immediately delighted by all the little community-lead bells and whistles I found at my disposal. One such tool is ujust, which is a collection of helper scripts that can do things like configure your system or run maintenance tasks. Not only did they make my life easier in setting up my desktop, but they exposed me to some of the features I had available to me right out of the box with no modification, such as distrobox assembly from a config file. Fast-forward to today: I daily drive bazzite desktop. I have my home theater mini PC running the “handheld”6] version of bazzite that boots directly into the controller-friendly Steam UI. My Framework laptop runs Aurora developer edition, providing me with an up-to-date, stable dev system despite my infrequent use of laptops. I’m planning out my move to [uCore for my home server/NAS box. The whole experience has been very pleasant, and I’ve been able to work several things out before and after installation with some help from people in the ublue Discord. I'm excited to see where these projects take me! * * * 1. I Want to Love Linux. It Doesn’t Love Me Back, I had others in mind but I can't find them now :( ↩︎ 2. Fedora Atomic intro, bootc, composefs ↩︎ 3. To be fully transparent, I don't think any of the major ublue images are ready to widely recommend over distros like Mint or Debian. Those are just so stable/mature. I still feel like I need some technical experience to really make these atomic desktops shine, but they require way less tinkering than I've ever needed in other desktops. I think ublue or similar images can reach "blanket recommendation" at an unprecedentedly rapid pace. ↩︎ 4. I’d like to point out just how nice the bazzite website is. It’s rare that a website is cool/pretty enough to have an affect on my opinion of something, but they did a great job with this one! ↩︎ 5. Yes, I found a wiktionary entry for this. Every other reference to “distro-hopping” was some longish blog post or article so I figured this was just the best way to get the idea across… ↩︎ 6. Look at all this amazing documentation I’m linking to. I just love that. ↩︎

The Year of the Linux Desktop will be Distroless (https://dabe.tech/posts/distroless/

3 weeks ago 0 0 0 0
The Making of GameJay and Word Hunt Online My partner got me into playing Word Hunt through the popular iOS iMessage games app GamePigeon. If you aren't familiar, Word Hunt is basically just Boggle, which is a game where you have to find words in a 4x4 grid of randomly generated letters under a certain time limit. The game board kinda looks like this: | | | ---|---|---|--- p | e | e | i o | t | s | s r | e | d | i e | h | t | n Anyway, I eventually went on a crusade to move all the people I communicate with onto a chat platform called Telegram for a plethora of motivations. _2025 edit:_ Many of these are no longer valid due to the platform's enshitification. _2026 edit_ : In fact, they're so invalid, I've actually turned off the GameJay Telegram backend and don't plan to host any backend for it until I manage to make the platform compatible with some other chat platform. But I believe this post still showcases an interesting technical journey, so here we go anyway! I wanted to text my friends via Telegram but I wanted to keep playing boggle. I mean word hunt. Simple problem, simple solution. ## a complicated solution So Telegram has a rudimentary gaming platform where bots can serve up little games within a chat. I couldn't find any pre-existing games that implemented Word Hunt (or any games, really, for that matter. the platform was not too popular), so I decided to just make it myself. I also figured that I might as well set up my bot to be able to replicate _all_ the GamePigeon games at some point. I basically wanted to make a clone of GamePigeon. Telegram is blue and... blue jays are a commonly considered flavor of jay, so... GameJay. ### building a games platform as a bot A "game" to Telegram is just a web app hosted elsewhere that reports back some info as rounds of the game are played. A single bot can serve several games via Telegram's API. They even allow for implementing a sort of searching functionality built right into the chat box. It felt natural to design GameJay to host all sorts of clones of popular chat-app games, including billiards, checkers, and mini-golf. The goal is for GameJay to eventually become an abstract logic layer that can facilitate any game with a minimal set of attributes. However, what I did _not_ want to do was fully plan out the infrastructure needed to support every game that I’d want to eventually make before I even started coding. So, I kept the goal of future-expandability in mind as I worked on Word Hunt Online (WHO), but focused first on getting WHO working as a proof of concept. My hope was that, once all the back-end pieces for WHO were in place, adding a second game would flesh out many of the things I didn't account for in terms of supporting other kinds of games. Thus, GameJay would logarithmically approach the fully desired flexibility as I kept adding games. Given that I haven't started on a second game yet, I'd say I'm sticking to the vision pretty well so far. ## Word Hunt Online I started thinking about the hard parts of making this game so I could tackle them first and figure out what I could and could not do with WHO. The first step was fully familiarizing myself with Telegram's games API. The biggest problem (besides the fact that I had to make time to program all this) was that the gaming platform was pretty basic: it only accepts scores and only keeps track of high scores. The rest of the game is instructed to be an instance of a front-end web-app that eventually sends the player’s score. The games from Telegram’s standpoint don’t have any concept of turns or rounds or even multiplayer interaction. That poses a problem for Word Hunt, where players go head-to-head and each game has its own winning score. All-time high scores don’t mean much since they are entirely dependent on the randomly generated boards. But I would be damned if I didn't have my Word Hunt so I came up with ### a workaround for scoring The actual score that each player achieves for a particular round of a game is not the score that I send to Telegram. If I did send the actual score, no one would be able to easily keep track of who won a round if they scored below the highest scores for that game’s leaderboard.[1] There would also be no way to notify users of who was the winner. So instead, I treat the scores stored in Telegram as the number of wins achieved by that player. This way, as soon as more than one player gets a score for a round, the winner amongst all currently scored players can be determined. Telegram automatically sends a notification to the chat when a new “high-score” (in our case, a new maximum number of round wins) is recorded. This means that a notification will _only_ be sent for the player with the most wins in the chat, but that’s better than no notifications at all. We'll come back to notifications. All that logic functioned pretty well after a LOT of edge-case-catching. It was a bit tricky because I wanted to handle having ### multiple players in one game (and other added features) While making WHO I decided that I wanted to actually improve on GamePigeon's version of Word Hunt. One massive improvement is to allow every member of a chat to participate in the same round of a game. In GamePigeon, only the first two chat members to click on the game notification get to play. Handling this turned out to be easier than expected. I just had to re-calculate the winner whenever a new player finished their round in the game, and allow the round to persist for some time (3 days, for now) so people had a chance to take their turn. This can create an exciting scenario where someone has the opportunity to "steal" a win from a player who currently holds the highest score in a round. After smashing several more edge-cases, the feature was working. When a player finishes a round, they’re shown a results screen where they can see all the words they found, lined up against the words and scores of every other player in that round. I'm pretty proud of the UI for this screen; it's simple and effective at presenting the information, in my opinion. I reached this design after a few iterations with feedback from friends. This screen updates every couple seconds with the results of other players' rounds, both in-progress and completed, so you can nervously watch their scores creep towards yours. ### integrating with Telegram Integrating back to the Telegram app and the device itself required a lot of creative thinking since, as I mentioned, the games API was pretty basic. I didn't have access to any device features like haptics, native UIs, and system notifications. All my ideas for sending notifications through Telegram just ended up feeling like bot spam. But I think I implemented a minimum set of features to make things flow smoothly enough for the game to be worth repeatedly playing. I wanted a way for users to quickly see who won a game and by how much without having to actually leave the chat screen. Thankfully, there exists pretty robust support for editing messages sent by bots (made INCREDIBLY accessible by the grammY library, _huge_ shoutout to that project), so I was able to utilize that. The placements (1st, 2nd, etc...) are shown as buttons below the game's message in the chat, and pressing a button shows the score that player received. I initially had the scores in the buttons themselves, but I got feedback that seeing the score that another player achieved in a game before you even see the board was intimidating/off-putting. ### the actual game I made the game itself in Phaser because I made a few things with it before and it felt like the simplest way to make any sort of multi-faceted UI in a website. It may feel like overkill for a game made of squares with letters in them and a single flow to the results screen, but I was not about to figure out how to do all that in pure HTML/CSS/JS nor learn another JS framework so, Phaser it is. Phaser is also just very cool. Figuring out the UX was fairly straightforward, made easier by great feedback from my friends. The hardest part of the UI was the dragging interaction to make words. The dragging feel took a couple iterations to pin down. It had to be smooth and forgiving enough to remain accurate while the player quickly tried to match words. I tried to achieve this by rounding out the hitboxes of the tiles a bit and having some forgiving out-of-bounds checking as long as the press event is held. The most involved technical challenge was figuring out how to generate a board and get all its valid words. I started by trying to do it all from scratch. I ended up going down a git of a rabbit hole, trying a naive solution of a recursive search through a board of randomly generated letters to find all chains of 3+ letters that are found in SOWPODS. I did end up getting this working using some depth-first search approach, but that unsurprisingly turned out to be way too slow. After doing more research into ways to solve the problem of finding all valid words given a 2-D array of letters (that's what a Boggle board is, after all), I came across the trie data structure. It provides very specific algorithmic benefits for the problem of finding valid words in lists of letters, and is in fact used in many Boggle solvers. Including the one I ended up using in this game! At first I tried to implement it myself for fun, but I just couldn't wrap my brain around how it was used to efficiently track word chains. I eventually gave up and found a library to do it for me. But it was a good mental exercise! After implementing the libraries, testing the logic of the functions, and thoroughly wrestling with JS modules, the core game functionality was done. ### the user experience Then came coding up the interface of the game. I think the most interesting thing I had to cook up for this part was how to track "chains" of letters and display if the currently built chain contained a valid word or an already-found word. Basically I just had to create a finite-state machine for tracking the current chain status and handle all the events that could transition its state. In retrospect, I probably would have spent way less time hacking away at this if I had drafted up an FSM for it to start with, but I was more interested in just charging forward until I ended at a satisfactory solution. There were some aspects I had to fiddle with, such as handling traversing to letters already in the chain, matching duplicate words, and dragging outside the board, all while keeping in mind the golden rule of game design: #### always forgive the player I actually don't know if people phrase it like that, but I know I stole the idea from somewhere. Basically, do everything you can to give the player the best chance of reaching a successful state. Make their hurtbox a little smaller, let them scramble up a ledge they otherwise may have just barely missed, and let them keep their chain going even if they drag outside the board, as long as the next tile is valid. I even did a little math to enable this: const isTileReachable = lastTileInChain && Phaser.Math.Distance.Between( lastTileInChain.row, lastTileInChain.col, tile.row, tile.col, ) <= Math.sqrt(2); ## GameJay My process for ensuring GameJay worked as a generic games back-end was so iterative and test-driven that I can't even really remember all the twists and turns I took to get it into its current state. I remember spending a _lot_ of time on the logic for determining which player was the winner of a particular game of WHO and how to recalculate the "scores" with any number of players finishing at arbitrary times. I basically turned Telegram's rudimentary high-score-storing API into an incremental database. And I did it for free! I tried to preemptively use generic concepts when supporting WHO features, like implementing the idea of "turns" even though every player in a WHO game only technically gets one turn. Or when to consider a game "complete" even though anyone can take their turn in a WHO game at any point that the game is valid. ### persistence As I explained, Telegram's game API was providing all the storage I needed to make WHO scoring meaningful. As such, I opted to just not have GameJay itself store anything. It would be awesome to record things like scores between Telegram users across different chats (since Telegram's built-in scores are per-chat), or achievements like highest scoring word, highest scoring game across all chats, etc. However, that would not only require hosting my own database, but also would require implementing a UI to actually access this data. So I opted to forgo features like that for now in favor of simplicity and getting a working game. As for the games themselves, they did require some in-memory state to be stored for some amount of time so that people could join a game that was started some time in the past. I could store all that in a database, but due to the motivations mentioned prior, I decided to just keep all games in memory and clean up old games after a certain expiry period. To keep the code simple, this expiry gets checked whenever a new game is created or an existing game is joined. I don't care about lingering games if there's no activity to push the memory usage one way or the other, so I think this method works well. Keeping everything in memory could very well bite me later on, but only if the games see enough activity. I already put a somewhat arbitrary limit on the number of games that can exist at a time, but that's certainly a bridge not worth crossing until I get there.. or something.[2] ### hosting I needed some way to host the game that was more stable than my home server. WHO is just a static webpage so I can host that just about anywhere. I started with GitHub pages and eventually moved to Cloudflare pages cuz of the vibes maybe. DigitalOcean's app platform was my first thought for where to host GameJay itself, so that's what I went with. $5/month ain't bad. That did require me to containerize GameJay, but I was gonna do that anyway because I love containers. I want to move to a more eco-friendly hosting provider, such as GreenGeeks or something from this directory that I found while searching for eco-friendly hosting providers. Funny enough, Cloudflare is in that directory, but I'm not sure how much effort they put into being green while also running one of the largest network infrastructures in the world. Due to pricing and convenience, I'll likely wait to make the move until I first start to see some meaningful traffic. ## Looking ahead As I said before, the goal for GameJay is to host all kinds of little chat games (GamePigeon clones). Creating WHO wasn't _too_ much effort, and now that I have a lot of the groundwork laid out, adding more games should be much less of a daunting task. I can get fancy by adding real-time interactions using web-sockets and lobby systems, as well as more complex UIs. I can do this on a game-by-game basis, since they are all stand-alone web-apps. Other devs can even make games for the platform as long as they conform to GameJay’s REST API! I do plan on publishing a spec for the API once it’s in a more mature state. If I do end up implementing some sort of GameJay-wide storage, I'll likely want to develop a pluggable UI system for displaying common stats across games, or just integrating it into Telegram's chat interface, since you can do some pretty fancy stuff in there. ### Telegram mini-apps Those of you who are well-informed are probably seething at my failure to mention Telegram's newer mini-apps API. I wouldn't blame you, since this is literally just the games API but supercharged. It provides access to hardware features like notifications and haptic feedback, allows you to make complex menus for the bot itself that integrate perfectly into Telegram's UI, and just gives much more freedom in general for what can be accomplished by the underlying web-app. Well, all that came out after I had finished like 80% of GameJay + WHO. I was filled with a large mixture of emotions while reading the announcement of mini-apps... Converting GameJay to a mini-app is absolutely in my plans, but for now I'm satisfied with what I've accomplished so far using the games API. Now stop reading so dang much and go play some Boggle I mean Word Hunt I mean Word Hunt Online. * * * 1. Leaderboards are unique for every chat. This is how Telegram’s scoring backend works automatically. ↩︎ 2. "Walk a man across a bridge, and he'll have dealt with one problem. Teach a man to cross bridges, and he'll deal with problems for life." ↩︎

The Making of GameJay and Word Hunt Online (https://dabe.tech/posts/Gamejay/

3 weeks ago 0 0 0 0

I honestly had the same thought until I looked at the rest of the graphic and also saw this bsky.app/profile/nomo... You and I are officially just too git-brained

2 months ago 2 0 1 0

kingdom hearts 2. I play through it like every 4 years. any time there’s some decent size change in my life. it’s one of those grounding games.

though the last play through might really be the final one, since I got a full 100%

2 months ago 0 0 0 0

Besides the fact that it’ll likely get translations wrong/improperly localized with no way for Shen to check,

- typesetting is part of the art
- it’s not free, chatgpt is gobbling the input data, the servers cost money to run, and now an actual translator doesn’t get paid

Essentially: no

2 months ago 0 0 0 0
Advertisement
Preview
Narjo - Navidrome & Emby Music Player for iOS The ultimate Navidrome & Emby client for iOS with widgets, Siri, UPNP/DLNA support, and more.

If you wanna go down the self-hosted streaming route, there are some great iOS opensubsonic clients. I recommend www.narjomusic.com or testflight.apple.com/join/LDWqgjAs

Those have provided good offline support in my experience.

There’s also this list www.navidrome.org/apps/?platfo...

3 months ago 0 0 0 0

might as well ban smartphones too

3 months ago 0 0 0 0

also this OST goes insanely hard I’m listening non stop

3 months ago 0 0 0 0
Goombella - Paper Mario: The Thousand Year Door Remake OST
Goombella - Paper Mario: The Thousand Year Door Remake OST YouTube video by Charisma entertainer

Wild that the Paper #Mario Thousand Year Door remake referenced #nyancat in Goombella’s theme youtu.be/1EmkKFaT7V4?... @1:06

3 months ago 0 0 1 0

“yeah, I don’t care, change it to whatever you want” - guy who cared a lot up until 30 seconds ago

10 months ago 1 0 0 0
A glass jar of sausages

A glass jar of sausages

This is what happens when you let @corporateclash.net Discord members dictate what you should have for dinner during the v1.11 downtime...

A glass jar of sausages.

It's so. weirdly. soft.

I hate this 2/10

1 year ago 3 2 1 0

solksing my belove

1 year ago 1 1 0 0
Advertisement
Post image Post image

I would have called these images fake two hours ago.

1 year ago 861 233 12 5
Post image

SILKSONG IS REAL

1 year ago 883 327 5 1
Post image

Wait a sec… #TikTok got unbanned in US around 1pm EST… which would land right around January 20th in #china

I think TikTok devs forgot to account for timezones when they set up their stunt to credit #Trump for “unbanning” the app…

1 year ago 5 2 1 0
Video

how do you all remember every UUID? I find it really hard. so I wrote them all down on every uuid dot com

the list has fast search across all 2^122 values (so you can find your favorites) - hoping to add some social features like "trending UUIDs" soon!

1 year ago 1167 277 48 47
A black-and-white picture of a desk with a cup of Cogfee on the left and scattered papers everywhere. A Suit pushes forward an envelope with the word "NOTICE" on it, sealed with the C.O.G.S. Inc. logo in wax.

A black-and-white picture of a desk with a cup of Cogfee on the left and scattered papers everywhere. A Suit pushes forward an envelope with the word "NOTICE" on it, sealed with the C.O.G.S. Inc. logo in wax.

"Department audit is underway. The Chairman has an action plan."

February 16th, 2024.

2 years ago 57 27 5 3

I tried to get to my prescription provider through my health insurance portal, and I saw at least 15 redirects go through my browser URL bar until it finally landed. Some crazy legacy code shit going on there.

2 years ago 1 0 0 0
Toontown: Corporate Clash logo

Toontown: Corporate Clash logo

Good morning Bluesky! We've just made the jump over and wanted to say hi!

We are a free-to-play reimagination of the defunct Disney MMORPG Toontown Online, adding QoL features and new expansions.

Follow us for regular updates on what's new in the Tooniverse!

2 years ago 65 29 7 1