mark cerqueira well-rounded nerd

Excellent Tooling is a Great Teacher

I’m a big believer in programming languages living in an ecosystem and not in a vaccuum chamber.

Today’s thought takes me back to my on-site interview at Evernote. Given I had both iOS and Android experience (but had done Android more recently) I interviewed with some Android engineers and one iOS engineer. During the interview I was asked if my Objective-C code would look Java-esque; in short, was I still capable of writing idiomatic Objective-C code.

Writing Kotlin today that interview question comes up again and again in my mind. I still feel like I’m writing Java but in Kotlin and learning how to make it more idiomatic as I go along. Learning comes from a bunch of places like coworkers, Kotlin documentation, and example code but another great teacher has been Android Studio.

Here’s some Kotlin code I wrote recently. It’s not the best way to accomplish what I’m doing in Kotlin. Android Studio inspections to the rescue! Within a second of writing this code I got some green squiggle marks under the for. Command-enter and then selecting Replace with count{} gave me this:

Yes I could pore through documentation and blog posts about writing idiomatic Kotlin but there’s nothing more frictionless than having your development tool give you a hand when it sees you’re writing Kotlin in a Java-esque way. Thanks Android Studio for teaching me about count!

Hotel Complaning in 中文

This week’s Chinese unit has us covering everything about hotels (酒店, jiǔdiàn). The writing assignment involved writing a script between an angry customer (顧客, gùkè) and a hotel receptionist (服務員, fúwùyuán).

As always, I strove to make an entertaining and humurous story. This tale has an angry American who feels like he’s getting nickel and dimed but ultimately cannot wait to relieve himself especially when presented with an amazing Japanese toilet!

顧客: 你好!我不高興!
服務員: 對不起。在我的酒店,我要我的顧客都很高興。你跟我說有什麼問題。
顧客: 單人間太小了!我是美國人,我很胖!我需要一個大房間。
服務員: 其實我有一間套房,但是你說太貴了!
顧客: 那麼,你可不可以給我一個比較大的房間?
服務員: 對不起,我不可以。如果你要一個比較大的房間,你需要給我三百九十九元一晚。
顧客: 什麼?!太貴了!那個房間裡可不可以上網?
服務員: 可以,可是上網要給錢:一百九十九元。。。一晚!
顧客: 什麼?!這個酒店只要顧客的錢!
服務員: 不是。我也想要我的顧客很高興!
顧客: 那個房間裡有沒有廁所?
服務員: 那個房間裡有一個日本廁所。可以用來洗你的屁股。
顧客: 哇,太好了!我需要給你多一點錢嗎?
服務員: 不需要。可是如果你要熱水你要給多九十九元一晚!
顧客: 好。我需要大便。我很需要日本廁所和熱水。再見!
服務員: 再見!
顧客: 我沒錢了。。。

Key part of the story: 可以用來洗你的屁股 = kěyǐ yòng lái xǐ nǐ de pìgu = can be used to wash your butt.

Xenoblade Chronicles 2 - Patch 1.3.0

Xenoblade Chronicles 2 developer Monolith Soft released a doozy of a patch – 1.3.0 – today. This patch adds New Game Plus which lets you carry over a ton of stuff from your existing playthrough… PLUS lets you bond with some story-related Blades, unlocks a new level in driver affinity trees, unlocks new battle skills, and introduces a level decrease mechanic that you can leverage to earn rewards.

This is all great and is egging me to dive into a second play-through right now. But I’m also super excited about the quality-of-life improvements in this patch!


First up is something I pointed out in an earlier post discussing quality-of-life improvements to make the game less of a chore: faster Blade bonding. In patch 1.3.0 you can now skip the entire Blade bonding awakening sequence! Huzzah!

Notice the key icon at the top of the Blade photos

Next is a thing I didn’t know I wanted until I got: favoriting Blades. This prevents you from accidentally releasing Blades but I’ve found it’s great for flagging all of my Blades that have completed their affinity trees. When I’m sending Blades out on Merc Missions now (to hopefully help them unlock nodes on their tree), it’s a lot easier for me to tell who I should be sending out.

Nintendo Everything has a nice post covering all the changes if you’re interested in reading more about Patch 1.3.0.

Satisfying the UnsatisfiedLinkError in ReLinker

In the Twitch Android app we leverage some native C++ code. Android’s default PackageManager used to load libraries in these situations is brittle so we leverage ReLinker to provide more robust loading. We recently moved from compiling our C++ externally to setting it as a Gradle dependency and letting Gradle handle compilation.

As we rolled out the update that included this change, we saw a bunch of UnsatisfiedLinkErrors pop up:

The vast majority of these errors were happening on Android 4.x. We didn’t have to look far for a potential solution as ReLinker has an awesome README that mentions that recursive loading can solve intra-library dependencies that the system’s library loader may fail to “on older versions of Android.”

Our theory is that moving from externally compiling the native code to having Gradle do it changed how the library’s dependencies were being packaged and older devices were choking because of this change. So we threw the recursively() method at it and fortunately it solved our problem 100%.

Stuck in Super Mario RPG

Writing about how Super Mario RPG was my first love the other day brought back another memory that has stuck with me. This is a great story that features:

  • Super Mario RPG - my first JRPG and an amazing game all-around
  • The redemption of Nelson, the cousin who deleted my save file in the aforementioned story
  • No internet connection, knowledge of GameFAQs, or friends who were also playing this game
  • Immigrant parents who don’t speak English

It’s 1998, I’m 10 years old, and I’m in the Sunken Ship in Super Mario RPG. To unlock a door in the cellar I need to input a 6-character word given these clues:

  1. There is an “s” in the word.
  2. It is found on the bed of the ocean.
  3. It has two vowels.
  4. It has four consonants.
  5. At least… two consonants are side by side.
  6. The “r” comes before the “l”.

Boom! I’m stuck. I have no idea what the word is. A jump box controls each of the 6 letters, offering 5 options for each character:

1. m c o t p
2. o t e s y
3. a r e t s
4. a t r s c
5. t e r l o
6. s t e k r

I have no idea how to solve this. I’m (only a little) clever now, but I certainly wasn’t back in fourth grade.

My parents (Portuguese immigrants) don’t speak much English but I take the “It is found on the bed of the ocean” clue and try to get info out of them. No luck. The computers at school only let us read Encyclopedia Britannica and play Oregon Trail so the Internet is not an option. Even if I had access to the Internet, I don’t have confidence that my fourth grade self had the technical know-how to search for the solution here.

And so I’m stuck.

I fought this battle hundreds of times...

In a room before this puzzle room there is a Dry Bones you can fight over and over again so I just grind all my characters to the max level. And then when that’s done, I’m stuck and I don’t have anything more to grind: the ultimate pain in a JRPG! Also worth mentioning: near where this Dry Bones hangs out is a shaman merchant who tells you how many characters of the puzzle you got correct. This merchant will play a critical role in what’s to come.

Enter my cousin Nelson – tragic hero who deleted my save file – but will now redeem himself and save me from this impasse. I tell him about my issues and he realizes we can brute force the puzzle but use the merchant to help make that strategy more tractable. We shuffle between the puzzle and the merchant trying each character until the correct number of characters increases.

And so we finally arrive at the password: PEARLS.

I was finally unstuck! With my now overpowered party, I’d go on to finish the game without any major hurdles. Most importantly, Nelson went from a tragic hero to a true hero!