THOUGHTS & INSIGHTS

Blog

Exploring the development of projects, applications, and video games. Reflections on design, productivity, and life as a developer.

Recent Articles

Deep Links That Work: The User Who Taps a Link Without the App

Deep Links That Work: The User Who Taps a Link Without the App

A link in an email opens the website instead of the app, or opens the app on the home screen and loses the context. How universal links and app links work, why they fail silently, and how not to lose the user who doesn't have the app installed yet.

Hades: When Dying Means Moving Forward

Hades: When Dying Means Moving Forward

In almost every roguelike, dying means losing. In Hades, dying moves the story forward, opens new conversations and makes the character stronger. How Supergiant turned defeat into the engine of the game, and how to implement a prioritized narrative event system.

Random Isn't Fair: When Your Game Should Cheat With Chance

Random Isn't Fair: When Your Game Should Cheat With Chance

A 25% crit chance can miss ten times in a row, and players will read it as a bug. Why crits need pseudo-randomness (PRD, shuffle bags, true hit) while loot can stay purely random.

Idempotency Keys in APIs: Why Retrying a Request Is Dangerous Without Them

Idempotency Keys in APIs: Why Retrying a Request Is Dangerous Without Them

Retrying an HTTP request sounds harmless until it duplicates a charge or creates two orders. How idempotency keys work, where to store them, and how to implement them in TypeScript without coupling to a specific provider.

Why Multiplicative Scaling Doesn't Break Balatro

Why Multiplicative Scaling Doesn't Break Balatro

Balatro lets your score grow by several orders of magnitude in a single run and stays legible. It's not the jokers holding that up: it's that ante requirements scale just as fast.

Doze and the Process Lifecycle

Doze and the Process Lifecycle

The system decides when your app gets to work, and that decision is not yours. Doze, App Standby buckets, and why scheduling a task is not the same as running it.

Android Permissions Change Depending on the Phone Brand

Android Permissions Change Depending on the Phone Brand

Xiaomi, Samsung, Huawei... every manufacturer has its own permission hell. Why you end up writing your own permission manager, and how to tame the per-brand quirks.

Marching Cubes: From Voxels to Smooth Meshes

Marching Cubes: From Voxels to Smooth Meshes

Cubic voxels are easy; smooth terrain is not. How Marching Cubes turns a density field into a triangle mesh, why interpolation is the whole trick, and what breaks when you add chunks and LOD.

The Journey of an Error: From a Backend 500 to the Message the User Sees

The Journey of an Error: From a Backend 500 to the Message the User Sees

An error crosses four layers before it reaches the user: the HTTP interceptor, the mapping to domain errors, the default behavior policy, and the render safety net. Three implementations (TypeScript, Kotlin and Swift) of the same pattern.

The Roster as a Resource: Darkest Dungeon's Economy of Scarcity

The Roster as a Resource: Darkest Dungeon's Economy of Scarcity

In Darkest Dungeon heroes are consumables and the hamlet is the real protagonist. A breakdown of roster management, opportunity cost, and an economy designed so you never have enough.

Showing 1-10 of 26 articles