Posts

Improving Player Retention And Daily Engagement

Designing Daily and Weekly Engagement Systems Mobile game retention depends heavily on creating compelling reasons for players to return daily. The goal: establish a feedback loop where players log in, complete manageable objectives, watch some ads, and feel rewarded—all within approximately 20 minutes. This post covers the systems I implemented to achieve that: daily quests, daily challenge levels, weekly competitive levels, and significant changes to community level creation. Quest System Overview The quest system includes both daily and weekly objectives. Daily quests can be completed in a single session. Weekly quests require sustained engagement—they need 100 points to complete, with individual quests awarding 10 points each, meaning completion takes at least five days of play. Both quest types reward players with chests containing progression resources. Daily Challenge Levels Daily challenges use existing levels from the regular level pool but layer up to three chal...

Supporting A Cosmetic Ball System

Separating Ball Effects from Ball Cosmetics This game features a gacha system where players spend gems to acquire ball shards. Collected shards unlock new balls, each with unique visual assets and passive effects. These effects meaningfully change gameplay: modifying the number of level attempts, adjusting ball bounciness, altering ball weight, and more. The challenge was designing a system that lets players leverage these passive effects without forcing them to look at balls they don't want to see during gameplay. The Initial Design Problem My first implementation conflated too many concerns in a single interface. The configuration scene—where players select which balls to use—also contained shard management and upgrade functionality. This created confusion: configuration should be about selecting options, not upgrading them. The solution was to separate these responsibilities. I created a dedicated Upgrade tab where players spend shards to upgrade balls, removing that f...

Xcode Simulator vs. Physical Device Lessons Learned

Xcode Simulator vs. Physical Device: A Costly Lesson in Button Behavior The Xcode Simulator does an excellent job emulating target devices—nearly perfect in most regards. However, relying on it exclusively for validating game behavior is a mistake. There are always subtle differences, and identifying them early prevents significant rework. This post documents a case where I failed to catch a critical issue until six months into development, resulting in a multi-hour remediation effort across hundreds of UI components. Early Indicators: The Subtle Differences Before diving into the main issue, it's worth noting the smaller discrepancies I encountered earlier in the project. These served as early warnings that simulator and device behavior don't always align. Visual Scale Mismatch: During the first two months of development, before I had established a device testing workflow, I was routinely enlarging the simulator window to see my work more clearly. When I finally deplo...

Customizing the playing experience with special ball effects

Customizing the playing experience My original vision for BallBuilder was strict equality. Players would unlock balls through coins earned by playing, and every ball would be functionally identical—just cosmetic variety. Everyone competes on equal footing. Through discussions with my development partner and general brainstorming, I realized this approach left significant potential on the table. The ball system could offer much more than cosmetic choices. It could become a customization layer that changes how players approach puzzles. The concern with giving some balls mechanical advantages is obvious: pay-to-win dynamics. But I concluded that advantages can exist without breaking competitive integrity, as long as skill remains the primary differentiator. A better ball might make a puzzle easier, but it won't solve it for you. Passive Effects: The Core Concept Each ball in BallBuilder now has a passive effect that activates when equipped. These effects range from subtle ad...

Solving Aspect Ratio Problems For Good!!

The Problem: Inconsistent Gameplay Across Devices BallBuilder is a physics puzzle game. Levels contain various components—triangles, rectangles, fans, portals—that players interact with to guide a ball to the goal. Consistency matters. A puzzle that's solvable on one device must be solvable on another, using the same approach. Early in development, I was building on an iPhone. When I used Xcode's device emulator to see how the game looked on an iPad, I was immediately disappointed. The layouts were wrong. Components appeared in different relative positions. The carefully crafted levels didn't translate. This was a fundamental problem that I needed to solve. First Attempt: Percentage-Based Positioning My initial approach used fixed pixel coordinates. This was obviously wrong—devices have different pixel counts, so a component placed at pixel 100 would appear in completely different locations across devices. The first real improvement was switching to percentage-b...

Implementing a Gacha system

Design Goal: A Configurable Player Experience BallBuilder is a physics puzzle game where players launch balls to complete objectives. I wanted to create a system where players could deeply customize their experience through unique ball effects. Each ball would have passive abilities that influence gameplay—some subtle, some significant. Once I committed to unique ball effects, the next question was progression. Should each ball be a binary unlock? That felt flat. Instead, I designed a multi-level upgrade system where each ball can be leveled up, making its effect incrementally stronger. This creates longer-term engagement and more meaningful choices about which balls to invest in. What is a Gacha System? For readers unfamiliar: a gacha system is a randomized reward mechanism common in mobile games. Players spend currency to "pull" or "summon" from a pool of possible rewards, with different rewards having different probabilities. The name comes from Japanese ...

Duplicated Configuration Data Solution

The Problem: Duplicated Configuration Data I ran into a fundamental architectural problem while building BallBuilder: configuration data was duplicated between the frontend (Swift/iOS) and the backend (AWS). Consider a simple example: an upgrade costs 100 gems. For that transaction to be secure, the backend must validate the cost—it cannot trust whatever value the client sends. This means the cost has to exist in both places: hardcoded in Swift for the UI, and stored on the backend for validation. This creates an error-prone system. Every time you change a value, you must update it in two locations. Miss one, and the game breaks. Observing the Problem in Practice I noticed this pattern while using Claude to write code. Claude would make a change to a configuration value in the Swift codebase, then we'd update the mocked API call, which also required the same change. Watching this happen repeatedly made it clear: this approach is unsustainable. Two sources of truth for the...