← blog

pull_by_the_root

The idea that keeps coming back

I’ve had an app going around in my head since March: something to keep score in padel matches. It came out of a conversation with a friend. I planned it, shelved it, and every so often it came back. A few nights ago it came back again, through a different door, and this time I didn’t let go until it was working.

March: keeping score by voice

The basic problem is simple: when you’re playing, you’ve got nothing on you, and you don’t want anything either. My friend’s idea was to solve it by voice, with keywords, and I jumped in to figure out how to build it.

The plan was to transcribe the audio with Whisper (opens in a new tab) on the phone, or with a cloud service, and give each team its own keywords. A 30-second cooldown kept the same word from scoring twice, and each team had its own sound to confirm the point. I got as far as the architecture and the planning, but never wrote any code: I was busy with another project at the time.

Even so, I always saw a catch. If it failed or misheard something, you’d have to go check the phone anyway, which was exactly what we wanted to avoid. On top of that, building something useful and reliable was complicated. I never found an elegant fix for those errors, and that held me back.

Pulling the problem out by the root

A lot of the time we stop to look for solutions to a problem instead of pulling the problem out by the root. That’s what was happening to me with voice recognition: it solved not having the phone, but it opened up other problems. I’d start working out how to fix them, and the thing kept growing: aliases for every word, confidence thresholds, someone in charge of the phone, tests on a noisy court. And the “someday” list already had a tournament mode.

The way out showed up while I was scrolling X: a tweet with a stick-on counter for the edge of a padel racket. It clicked. If the score could go on the racket, it could also go on my wrist, where I already wear the band every match. That’s when I dropped sound as an option, and with it, I pulled the problem out by the root. Only then could I focus on solutions I hadn’t even thought of, because until that point I’d been pushing on the wrong side.

That’s why I think an idea deserves to come back if you keep running into the problem. Maybe the implementation wasn’t good at first, or wasn’t enough yet.

The band is already a court

The band is a Xiaomi Smart Band 10, a lot simpler than an Android watch. Even better: after all, it’s a fitness band, and now it tracks one more sport. My way.

That same night I started digging to see if there was a marketplace or if I could build my own apps. There’s no marketplace: Xiaomi has no public way to install third-party apps. But band apps are written in JS, as Xiaomi Vela quick apps (opens in a new tab), and aiot-toolkit (opens in a new tab) compiles them into an .rpk package. MiBand Hack (opens in a new tab) installs it on the band over Bluetooth, straight from the browser. With that sorted, the rest was simple.

Looking at it, I realized the screen has the same proportions as a court. So I split it in two: opponents on top, us on the bottom. A tap or a swipe right adds a point and a swipe left takes it away, for the team on whichever half you touch.

Isometric illustration of three layers stacked on a Xiaomi Smart Band 10: the band at the bottom; a padel court seen from above in the middle, with the net across the center of the screen; and the app on top, at 30-15 in the game with sets at 6-4 and 2-3.

Then I added the rules (15, 30, 40, advantage or golden point, sets to 6, and tiebreak), the games counter, who’s serving, a history to fix mistakes, and an option to keep the screen on. So I don’t have to look at it, the band gives a short buzz for every point and a long one when a point wins a game.

The history is my favorite part. In March, the data model had matches, teams, keywords, and scoring events. On the band, the match is the sequence of who won each point, and the score comes from replaying it. Undoing a point means editing that sequence, so the score can’t get out of sync.

Since it’s all JS, it’s easy for me to follow the code, suggest structures, and propose changes. There was a bit of back-and-forth with Claude (opens in a new tab) on the styles, a quick test without much detail to see if the idea worked, and a few rounds of UI and UX. The project structure and the test harness come from Calc+ (opens in a new tab), by Ari Wilson.

Now it needs testing, finding bugs and improvements, and more tweaking.

An hour to save 45 minutes

You always have ideas. Or rather, you always run into problems. I’ve always been the type to spend an hour writing a script that saves me 45 minutes of repetitive work. The math doesn’t add up, I know: the first time, I lose 15 minutes. But I learn, I have fun, and the second time I have to do the same thing, it’s already done. That’s when it starts adding up.

That happened to me a few months ago with Goodreads (opens in a new tab). There’s a lot about it I never liked, but it was useful. Until I wanted to log the books my daughter and I read: the app doesn’t support profiles, and my daughter is little, so I didn’t want to give her her own phone. So I set out to build a similar app, for personal use, and fix what I don’t like and add what’s missing while I was at it.

I started looking into how to build it as a native Android app, and I ended up building it: it imports my whole Goodreads history and already runs locally. It still needs quite a few late nights to take shape, and it’s not a product to launch. Still, it solves a problem for me, and I enjoy building it. But that’s a story for another post.

What changed is the distance between the idea and the sketch. Today the race is shorter and the finish line is always in sight, even in territory you don’t know, like Vela was for me. Validating an idea keeps getting easier.

The process, on the other hand, is the same one I follow with a client and their problem: come up with a quick, simple architecture, don’t get tangled up in complex structures, and be able to correct course in time.

Fast isn’t sloppy

Now, fast != sloppy, but it doesn’t have to be perfect either. What matters is not getting tangled up in details that take forever: the 20% of the work that solves 80% of the problem, as the Pareto principle goes. And on top of that, a thin layer of aesthetics. I may have moved to programming, but the designer still lives inside and I can’t help it. That’s why the app uses orange and blue, which stay distinguishable even with red-green color blindness, on a black background, which uses less battery on an AMOLED screen.

Between seeing the tweet, digging around, planning, and shaping something, in two hours, two and a half tops, I had the app packaged, transferred to the band, and published on GitHub (opens in a new tab), open to the community.

If you’ve got a band, you can download it from Releases (opens in a new tab), and the README has the install steps. I’ve only tested it on my Band 10, so it might not work on other models. If you try it and something breaks, open an issue (opens in a new tab). Or better yet: fix it and send a PR.

Not being afraid to try

We all have small everyday problems. Those of us who are developers, or who already think logically, have a small edge for solving them, and it’s worth making the most of it. You can build something fast, take advantage of AI’s speed, go test it, and if there’s something there, work on it and polish it until it’s solid and useful.

My scoreboard still needs the real test: a match. But at least this time, the idea came back knowing what problem it has to solve.