RSSAmplifier

Blog

Marcus' Blog

Recent content on Marcus' Blog

mbuffett.comRSS feed ↗39 posts

Latest posts

Improving in chess is hard. I built the world's most human-like chess AI to help me.

Getting better at chess is really hard . My theory is that it’s at least partially because of the feedback lag. Imagine learning to play the violin, but you have to play each song with earplugs in, then listen to the recording after. This is roughly what chess learning feels like, outside of focused drills. You play a game, ignorant of which moves are good and bad, then you get feedback from…

An honest review of my last year building Chessbook

Last year, I quit my job to work full-time on a chess app I created. It’s my first time working full-time on a project of my own, and it’s been both terrifying and gratifying. To close out my first year, I’m sharing an honest account of the mistakes I’ve made as a founder as well as the the things I felt I did well. Marketing 2 /5 Ugh. I’ve tried paid ads virtually everywhere (Meta,…

My Deep-cut Book Recs

Here are some lesser-known books I’ve loved, that you won’t find in typical recommendation lists – the deep-cuts. Replacing Guilt: Minding Our Way This book is all about the role of guilt. When is it useful, when is it not, what can be done about it. This could have easily been packaged like a best-selling pop-psychology book – padded to 200 pages with a sampling of the same anecdotes…

Treat your onboarding users like toddlers

One of the biggest realizations I’ve had when building Chessbook is that onboarding a user is really hard. A user that’s coming in from some generic marketing, or from a blog post they found, or from organic search… well, the closest mental model is that they’re precocious toddlers. They won’t read more than a couple sentences of explanation. Usually they’ll…

How I prevent myself from committing temporary code to production

I have a chronic problem of committing debug code to production. I often adjust code while testing out assumptions, reproducing issues, or trying alternative ways of implementing a feature or fixing a bug. When I’m committing thousands of lines per week, and with no-one reviewing my commits, occasionally some of this code slips through. A couple months ago I had one particularly annoying…

Locality of Behaviour, over the Single Responsibility Principle

Bob : This is where I keep all the notes I wrote in red pen, and likewise for all my blue notes, my green notes, and my purple notes Alice : Doesn’t this split your chemistry notes up into 3 different piles? Why not keep those together? Bob : gasp – and break the Single Color Principle? Disclaimer The shitty part of becoming a more senior engineer is your opinions become a mystifying web of…

A Made-up Name is Better Than No Name

In working on Chessbook recently, I often found myself referring to (position, move) pairs. Specifically positions that are stored as EPDs, and moves that are stored in San notation. let difficulty_by_epd_san = //...; let existing_epd_sans = //...; let unique_moves_by_epd_san = //...; fn epd_san_plus_to_condition ((epd, san_plus): & (String, String)) -> _ //...; I got so used to thinking of these…

Creating an optimized keyboard layout for the next generation of the Datahand

Ever seen this keyboard? This was called the Datahand, it was a radical new approach to keyboards that mostly only existed within a small community of RSI sufferers. It cost $2,000 in 1993, which is north of $4,000 today, so you really had to need this thing to justify the price. Even now there’s a small community that continues to use these. For a long time after Datahand shut down…

The 2030 Rust Update

Welcome to the end-of-year update for the Rust language. 2030 has been a huge year for us, with some huge wins but also a couple setbacks. We’d like to highlight some of these moments and look back on the past year of work on Rust. Async woes Despite our best efforts, there are still some large issues with async rust. Async traits come with significant limitations, async closures…

A Bunch of Programming Advice I'd Give To Myself 15 Years Ago

I finally have the feeling that I’m a decent programmer, so I thought it would be fun to write some advice with the idea of “what would have gotten me to this point faster?” I’m not claiming this is great advice for everyone, just that it would have been good advice for me. If you (or your team) are shooting yourselves in the foot constantly, fix the gun I can’t tell…

Abstractions Are The Best, Abstractions Are The Worst

Abstractions are the best Your code will be safer and more readable. It will prevent entire classes of bugs. It will be easier to add new features. You can inject dependencies at runtime to make testing easy. You can swap out your third party dependencies. You can adapt quicker to business logic changes. You can treat X and Y as the same thing. They’re both forms of Z, after all.

Managing My Motivation, as a Solo Dev

One of the biggest sticking points of being a solo dev is maintaining motivation. I’ve been keeping a journal entry about how to hack my motivation, what works and what doesn’t. Here are the things that have worked. Convert external sources to motivation I’ve always known that I’m more extrinsically than intrinsically motivated, so I have a couple systems that help to give…

Processing 6 Billion Chess Games in Less Than 2 Hours

Background I run a chess site, https://chessbook.com . We ingest a ton of games, nearly 6 billion, to power our various statistics. Our current database has about 900 million lines. We’re working on our next evolution of this database, and that entails re-ingesting all these games, but going much deeper on each game. Our existing solution was already pretty optimized, you can’t get…

Compressing Chess Moves Even Further, To 3.7 Bits Per Move

I wrote a post yesterday about how to compress chess moves. I was pretty happy with my hand-rolled compression scheme, which achieved a per-move size of 9.5 bits. I almost just rolled with it, but I’ve been thoroughly nerd-sniped here, so I took another crack at it. To know the board state or not One of the main considerations in compressing chess moves is how much chess-specific computation…

Compressing Chess Moves for Fun and Profit

UPDATE: I’ve written a new post with a new technique which is about 2.5x more efficient than this approach Chess notation has come a long way since descriptive notation , now we have nice and decipherable Standard Algebraic Notation, like Qxf7 (queen takes on f7) or Nf3 (knight takes on f3). This is a great text format, but a massive waste of space if you’re trying to store a lot of…

How useless is memorizing openings, as an amateur Lichess player?

I recently downloaded Lichess’ database of all December ‘21 games. After using it to generate puzzles for my chess training site, I realized I could also use it to find out something I’ve been wondering a long time: how useless, exactly, is it for me to memorize chess openings? I’m ~1700 on Lichess, so I chose the ELO range of games for these statistics as 1600-1900. The…

Generating Chess Puzzles Fast with Rust and Stockfish

Generally, chess puzzles will present you with a position and ask you to find the best move. There’s only one, and all other moves are losing. These are great, but I’ve been thinking of a different style of puzzle that I’d like to practice with. What I want is a chess position, then two moves presented as options; one is a blunder, and one is the best move. The idea is to train…

Book Review 2021

The annual book review, 2021 edition. Ratings are solely about how much I enjoyed the book. I’m not reviewing these books like a critic, if the book has a bunch of tropes or something, but it kept me hooked from start to finish, I’m not going to mark it down. For example, I actually love reading books with a Mary Sue main character, so my rating is going to be divorced from a book…

Scattered Thoughts on Why I Waste My Own Time

I spend way too much time on reddit, hacker news, twitter, feedly, coinbase, robinhood, email, etc. I’d like to spend time on things that are more meaningful - chess, digital painting, side projects, reading, video games, exercising, meditating, etc. This has been a problem for years. This post is only slightly adapted from my personal notes, so excuse the lack of structure; I didn’t…

Thoughts on chess improvement, after gaining 600 points in 6 months

I played chess briefly with my friends in high school, where I had a rating of around 1100 online. I gave up the game for about 10 years, then picked it back up again recently, in May. I’ve tried a ton of different approaches in the past 6 months, switching things up whenever I stopped seeing results. I’ve improved from 1238 to 1802, and based on my win rate currently I think…

An Incomplete Explanation of the Proc Macro That Saved Me 4000 Lines of Rust

Recently I&rsquo;ve been working on a project to surface census data via a GraphQL API, mostly as a way to learn GraphQL. I did end up learning GraphQL, but I also ended up learning a lot about proc macros. I was using Juniper, which creates a GraphQL schema using structs like this: #[derive(GraphQLObject, Copy, Clone, Debug)] struct Demographics { female: Option < i32 > , male: Option < i32 > , }…

How Much of the Hitchhiker's Guide to the Galaxy Can You Fit on a QR Code?

I&rsquo;ve been dealing with QR codes recently, as one of my side projects generates them, and I got curious about how much data you can really fit in a QR code. Specifically, I wondered how much of my favorite book I could fit on one QR code. QR Code versions QR Codes have different versions, but they&rsquo;re not versions as you&rsquo;d generally think about them, version in this case just means…

Unironically Using Kubernetes for my Personal Blog

There&rsquo;s no shortage of posts like “Let’s use Kubernetes!” Now you have 8 problems , or Do I Really Need Kubernetes? , which tend to argue that unless you&rsquo;re orchestrating 1000 containers, you&rsquo;re good without Kubernetes. Also, I thought this tweet was hilarious: So&hellip; Hi, I&rsquo;m the guy using Kubernetes for my blog and small side projects, here&rsquo;s why I love it (to…

My Experience Switching to Gatsby, from Next.js

Just some quick thoughts on Gatsby and Next.js, after trying both for a project I worked on recently ( this one ). I&rsquo;ve been a Next.js user for about a year, and for this project I tried to use Gatsby, with limited success. Hot-reloading Hot-reloading started out pretty shaky for me when I first tried Next.js about a year ago. But since 9.4 it&rsquo;s been spot-on. Gatsby hot-reloading…

CRUD with Rocket and Sled

In my last project I used Sled and Rocket . I had to piece together how to use the two from a few different places so I put together this quick guide in case it helps others. The full code for this walkthrough is availabe here , if you want to fast-forward to the finished product. A lot of this ends up being about error handling, so that using sled in endpoints is more ergonomic. If you…

Creating a Snake Clone in Rust, with Bevy

Bevy has seen rapid adoption recently, but the learning resources are still fairly scarce. This is an attempt to provide a next step after the Bevy book. The final product looks like this: It&rsquo;s about 300 lines of Rust, so buckle in; this is a lengthy walkthrough. If you want to fast-forward to the finished code, the code lives here . For each section there&rsquo;s a diff at the top, which…

Thoughts on Structured Editing: Breaking Away from Syntax

I was aimlessly browsing Github and came across sapling , a very early-stage structured editor. It was inspired by this blog post , which talks about structured editing. Structured editing has had my interest for a while. I&rsquo;ve put a lot of time and effort into getting really good at text editing, but I&rsquo;m holding out hope that in 10 years plaintext editing will be outdated. The idea…

Migrating from Redux to Pullstate

Recently I migrated my side-project from Redux, which I&rsquo;ve used in every React project for the past four years, to pullstate , here is my tale. Problems with Redux Feel free to skip this part if you already know the pain points of Redux, there&rsquo;s nothing in here that hasn&rsquo;t been discussed a million times before. These are the problems as I see them, most important first: The…

As a hobbyist rust developer, I want to think less about error handling

I saw the call for blog posts in the 2021 rust roadmap , so I figured I&rsquo;d throw in my 2 cents, since I&rsquo;ve been working on a project recently that uses rust on the backend. As the title suggests, I&rsquo;ve been finding myself spending too much time on error handling. I want to preface this by saying I&rsquo;m just using rust for hobby projects. If I were writing rust in production or…

Unconventional React Things: Styling Edition

I&rsquo;ve developed an unusual approach to styling in my React code. It&rsquo;s sort of a functional, atomic css approach. Other methods I&rsquo;ve used are BEM + separate css files, styled components, and tailwind. By far this is the one that lets me move fastest on my personal projects (I haven&rsquo;t yet subjected anybody at work to dealing with it). Without further ado. Element Styling const…

Programming and Tacit Knowledge

The Commonplace blog has been writing a lot on tacit knowledge recently. As someone who&rsquo;s been programming for a long time (8ish years), these articles resonated deeply. I won&rsquo;t go into too much detail what tacit knowledge is about, since the above posts do such a good job with it. If you&rsquo;re not familiar, check them out. Explicit knowledge vs tacit knowledge Essentially, explicit…

Why I Self-Host My Website Analytics

Recently I made the switch to self-hosted analytics, after being a long-term Google Analytics user. Almost every website you visit will have a Google Analytics tracker on it. I think there are idealogical and technical reasons to opt for self-hosted analytics instead. Tracking efficacy This one&rsquo;s quick. You&rsquo;re more likely to get analytics for a given user if you&rsquo;re using…

Replacing ngrok with ktunnel

ngrok is a tool that proxies traffic from a subdomain (like http://2fb551c6b2fd.ngrok.io ) to a port on your localhost. I&rsquo;ve been using it off and on for years. There&rsquo;s a couple use cases I&rsquo;ve used it for: Forward web traffic to a local next.js / webpack server, to show a website in progress without having to deploy it. This way I can send an ngrok link to a friend/coworker and…

The CLI tools I use while doing full-stack dev

I&rsquo;ve been working on a web project for a few months now and thought I&rsquo;d take stock of the tools I&rsquo;ve been using. So I went through my zsh_history (fun fact, since March I&rsquo;ve run 3,950 commands for this project). These are only the &ldquo;generic&rdquo; tools, I&rsquo;ve excluded any stack-specific tools, like ghci , pgcli , docker , spago , etc. I&rsquo;ve also excluded…

Setting up tmux and kitty for true color support

I&rsquo;ve been using kitty and tmux together for years and recently realized my setup for true colors was broken, thanks to neovim&rsquo;s :checkhealth command. After some searching and trial and error, the setup I ended up at was this: Remove any export TERM lines from .zshrc , .bashrc , etc. Set these options in tmux: set -g default-terminal 'screen-256color' set-option -sa terminal-overrides…

My Year in Books: 2019

This is just a rapid-fire summary of the books I&rsquo;ve read this year and what I thought about them. Note that the links in here are affiliate links. Any profit will be donated to the Amazon Conservation Association , in the rare event people read this and buy a book. Without further ado. The Name of the Wind by Patrick Rothfuss Became one of my favorite fantasy books. Very interesting magic…

Scraping Goodreads Sitemaps with Haskell

Recently I acquired a project, Now What Do I Read? . One of the steps in acquiring the data was to scrape the sitemaps of Goodreads . The project was written in Go, and I decided to rewrite it in Haskell, mostly to mix it up a bit. Writing everything in Python and JavaScript gets old eventually, quick as it may be. This will probably turn into a series in which I go through the rest of the process…

Setting up Neovim for Haskell, as of October 2019

I started a Haskell rewrite of a project, and after not having used Haskell for a long time, found the process of setting up my Vim environment to be a pain. There&rsquo;s nothing exciting here, but by the end of this quick guide you should have: Haskell + Stack installed Autocompletion, go to definition, type lookups, and more via HIE and CoC GHCi via Intero (it does more, but overlaps with HIE a…

Creating a basic chess AI with Python

Recently, I made a chess program in Python and published the source on github here . The code is just under 1000 lines, about 20% of which is dedicated to the AI. In this post I’ll cover how the AI works, what each part does. and why it works like that. You can just read through, or download the code and mess around with it as you read. The AI is all in the AI.py file, although it might help to…