About me

Tallinn, Estonia EEST, UTC+3

My journey so far

I’ve always had an itch for making things. My first software product was a framework/wrapper thingy that transformed an ugly scripting API into an elegant collection of objects and methods. Almost like jQuery.

The API itself is for something quite peculiar — legal, Lua-programmable bots (pets) inside an MMORPG called Ragnarok Online. It’s an unorthodox feature in a game that’s no less weird, but… that’s a story for another day.

The latest release of the framework is still downloadable from the Google Code Archive.

To give you a feeling for what it does, consider this Lua code written against the default API:

function GetTarget(myid)
  local result
  local agressors = {}
  local agressorsCount = 1

  for i, actor in ipairs(GetActors()) do
    if actor ~= GetV(V_OWNER, myid) and actor ~= myid then
      if GetV(V_TARGET, actor) == GetV(V_OWNER, myid) then
        if IsMonster(actor) == 1 then
          agressors[agressorsCount++] = actor
        else
          local motion = GetV(V_MOTION, actor)

          if motion == MOTION_ATTACK or motion == MOTION_ATTACK2 then
            agressors[agressorsCount++] = actor
          end
        end
      end
    end
  end

  local minDistance = 100

  for i, agressor in ipairs(agressors) do
    local distance = GetDistance2(myid, agressor)

    if distance < minDistance then
      result = agressor
      minDistance = distance
    end
  end

  return result
end

My framework shortens it to just a few lines of human-readable code:

function GetTarget()
  local agressors = List()

  for i, actor in Owner.surround.each() do
    if actor.group.is.Mob and
       actor.target.is(Owner) and
       actor.action.is.Attacking
    then
      agressors.add(actor)
    end
  end

  return agressors.closestTo(Owner)
end

Playing games is fun and all, but it was time to get a job. So right around the time when I was wrapping up this project, I started my career as a Java web developer. Writing complex, performant SQLs, crafting integration testing harnesses, tinkering with CSS — I tried to do and learn as much as I could. Though from the start, I started feeling a strong pull towards the visual bits. When React popped up on my radar in 2014–2015, I immediately saw it as a game-changer. Having built a couple of highly dynamic UIs with jQuery in the years prior, React felt like a breath of fresh air in comparison. Eventually, my fascination with the user experience has led me to become a full-time front-end developer at the current startup.

The jobs that I had over the years were always interesting in their own ways, though I never managed to find one that would scratch my maker itch or one where polish would be valued over the volume of work. To fill the void, I continued having small side projects throughout the years. Some of them are just experiments, others full-blown products.

Here are a bunch of them worth highlighting:

  • In 2013, I built a canvas-based mobile game MUSIC. For production, it was packaged into a native container with a hardware-accelerated canvas-compatible JavaScript runtime. To this day, the game works almost flawlessly in the browser — a testament to the stability of the Web. I’ve summed up my experience building it in an old blog post.

  • Right around 2015 or a bit before, the Web Audio API started appearing in the browsers, so I attempted to mix music and geometry with the canvas element to build a music player. Present me finds it a bit cringey, but hey — I don’t judge my past self.

  • In 2022, I decided to tackle two challenges at once — to practice my product-making skills and to help my spouse with her hair care routine. The result was a mobile-focused, offline-capable PWA for journaling built with Next.js, Framer Motion, Tailwind CSS, and PlanetScale. The full technical details of this endeavor are documented in an article.

  • My involvement with open-source is pretty sparse. The most notable mentions are:

The most special projects for me though were the native Apple apps.

SmartPaste, for instance, grew out of a tweet by Derrick Reimer:

Derrick Reimer
Derrick Reimer
@derrickreimer

It looks like @_mihhail did it! 🔥 smartpaste.app

Derrick Reimer
Derrick Reimer

Paste without formatting EXCEPT bold, italic, lists, and hyperlinks…


"Paste without garbage formatting"

Seeing the original quoted tweet I figured:

Why not? I could gain experience making a real product and solving a real pain point at the same time.

My confidence in the technical viability of this app stemmed from my previous experience with Mac apps. Namely, the most long-term project of my life — Paper.

Since 2015, this app has been my playground for polish, gimmicks, and all the crazy ideas I could think of. I spent most of this time building in a cave, but lately, I decided to crawl out of it and tell my story.

I have taken this as an opportunity to learn how to present my thoughts in the most delightful manner. Every article has a short slug for shareability and a catchy title to stand out from the noise. Not forgetting about accessibility, I made sure to use semantic HTML and descriptive alt texts for media.

The first article got to the top of HackerNews.

  1. 1.
    Vote triangle
  2. 2.
    Vote triangle
  3. 3.
    Vote triangle

The second one as well.

  1. 1.
    Vote triangle
  2. 2.
    Vote triangle
  3. 3.
    Vote triangle

(there is also a third one that’s simply a nice evergreen resource)

Finally, something I simply cannot leave unmentioned is that at one point Paper was printed in a physical magazine. For a software developer, it is a pretty surreal experience to have your digital code manifest in real life like that.

Paper
Paper
@papereditorapp

Paper has been printed on… paper… 😯


In the November issue of @mac_and_i 👀

twitter.com/mac_and_i/stat…

Thumbnail
Mac & i
Mac & i

heise-Angebot: Mac & i 6/2021 jetzt im Handel https://heise.de/news/Mac-i-6-2…

#AppDatenschutzbericht #Apple

And that’s a super-quick overview of my journey so far.

My LinkedIn has my full employment history, in case you’re interested.

Developing taste

We can often tell if something looks great, but most of us can’t produce great (work, things, products, designs). There is a gap between taste and skill. This gap makes us dissatisfied with our current work, pushing us to seek ways to improve it in the next iteration.

For an amateur, the gap is huge, and it leads to constant frustration — a lot of people give up. The key, however, is to persist. As you gain experience, your capacity to produce greatness starts to catch up with your ability to detect greatness.

With this observation in mind, I’ve picked up a few habits and points of reference over the years:

  • Whenever I work with designers, I try to dissect their thinking process. I study their mockups to find both the bigger patterns and the subtle touches.

  • I regularly skim through Product Hunt. When I land a good-looking website, I stop to analyze why I think it looks good. And vice versa — what made me think that something is not good enough?

  • I follow accounts like SaaS Shots to expose myself to various UI designs, repeating the same ritual mentioned in the previous point.

  • I try to incorporate delightful design details into personal projects.

  • I return to my old projects to understand what could be improved in the next one. It is often the case that in the moment the end result feels good, but seeing it a few months later, I immediately spot the rough edges.

  • A somewhat strange UX-y routine I have is watching car reviews on YouTube. I find it simply fascinating to observe and compare the choices different car companies/designers make to solve the same handful of (often orthogonal) problems e.g. button layout, digital vs physical buttons, reachability of controls, minimalism, etc. Somehow, it feels a lot like software UX, but here you have a couple of extra dimensions to play with and think about.

  • Apple’s APIs are a huge source of naming inspiration for me. I find their choice of words in the technical department to be on par with the customer-facing stuff. For example, where one might use the words SyncingStore to describe a syncing key-value store, they call it UbiquitousStore. What you might call a Transition, they called a Segue. BlurVibrancy, UI BuilderStoryboard. The list goes on.

And with that, I thank you for taking the time to read this.