19 August 2026 · Patmos Software
I built a lives economy into a puzzle game and then deleted the whole thing, because the game turned out to be too fair to charge anybody.
Shikaku is a logic puzzle. You divide a grid into rectangles, each rectangle holds exactly one number, and that number is how many squares it covers. I was building it free-to-play with a soft wall: three lives, one regenerating every thirty minutes, and you lose a life when you make three reasoning errors in a single puzzle. Run out and you wait, or you pay.
That is a shape you have seen a hundred times. It is also, as built, unreachable.
A life costs three errors. Three lives cost nine. Lives regenerate at one per half hour, so emptying the tank means nine reasoning errors inside about ninety minutes.
Not nine taps in the wrong place. Nine times being wrong about the puzzle, in an hour and a half, on a game whose first eight levels have no look-ahead in them at all and cannot really be failed.
I never once hit the wall. Not in a full evening of trying, and I was trying — by that point I was deliberately playing badly to see the screen I had built. Nobody who was actually enjoying the game was ever going to see it.
The numbers were wrong, but that is not the interesting bit. I could have set lives to one and the error budget to two and reached the wall by Tuesday. What I could not do was fix the reason the errors never arrived in the first place, because every one of those reasons was a decision I still think is correct.
A mis-swipe costs nothing. Dragging across a rectangle you
already drew is clumsiness, not a reasoning error, so it is free. So is
changing your mind mid-drag: come back to where you started, let go, nothing
happens. In the code there is a single flag,
MoveRejection.costsAMistake, and it is false for
.overlapsExisting and true for everything else. Charging for
fumbles makes a game feel hostile rather than hard, and it is the cheapest
possible way to inflate an error count. I refused to do it and the error
count stayed low.
Nothing is ever judged against the stored answer either. If you draw a rectangle covering six squares around a 4, the game tells you it is six squares and the number says four. It does not tell you “that’s not right”, because feedback you cannot reason about is not feedback. But a player who is told exactly what is wrong with a move makes fewer subsequent wrong moves, and my error count went down again.
The third one is what really did it: dead ends get caught at the move that causes them. A rectangle can obey every visible rule and still make the rest of the puzzle unsolvable — leaving some number with nowhere to go, or a square that nothing can reach. Without a check for that, you find out twenty moves later at a square nothing fits, and you get charged for a mistake you made ages ago. So the game enumerates each unplaced clue’s remaining candidates after every move and rejects the one that broke it, immediately.
Before that check existed, one bad idea cascaded into five or six errors as you built on top of it. After it, one bad idea costs exactly one error and you back out. I had taken the single largest source of errors in the game and divided it by five, on purpose, for good reasons.
And the opening cannot be failed, by design. The early boards are small enough that the answer is nearly visible, which is how you teach a rule without a tutorial. It also means the one part of the game every new player is guaranteed to see produces almost no errors at all.
Which is the whole problem, stated once.
Four separate decisions, none of them wrong, all pulling the same way. The paywall was downstream of every one.
So there were two ways out.
I could make the game worse. Charge for mis-swipes. Remove the dead-end check and let people fail slowly and confusingly. Steepen the opening so beginners lose. All of these would have made the paywall reachable, and all of them would have made the game meaningfully worse at the exact moment somebody was deciding whether they liked it.
Or I could change the model.
Free to level 40, then one payment for everything: levels that do not run out, the Expert, Master and Grandmaster tiers, and all three themes. The Daily Challenge stays free forever either way. No ads, no subscription, no accounts.
The gate is one rule. Levels 1 to 40 never serve Expert or above, which is what lets the whole thing be “past level 40” instead of a tier lock that could strand a free player halfway through a run on a level they cannot open. That one constraint on the level plan is doing a lot of quiet work — it also means the hard tiers are genuinely something the purchase unlocks, rather than content that was already there behind a different sign.
Running out of errors now simply loses the board. You keep your three per puzzle, but there is no currency behind them. Losing your work and your time is tension enough for a game somebody has paid for once.
LivesManager became PlayerWallet — hints
and the unlock, nothing else. A class called LivesManager with no
lives in it is the kind of lie that costs somebody an hour six months later,
and that somebody is me.
But the stored property is still called hasUnlimitedLives.
Renaming a persisted property risks SwiftData treating it as a drop-and-add,
and silently stripping a purchase somebody paid for is not a risk worth taking
to make a field name read nicely. Everything goes through
hasFullGame instead.
The product identifier is worse and for the same reason:
com.patmossoftware.shikaku.unlimitedlives
That SKU sells a game with no lives in it, and it always will. A product ID cannot be changed after it exists. Only its meaning did.
I do not know yet whether the content gate converts better than the lives economy would have, and I never will, because the lives economy converted at a rate I could not measure — nobody reached it.
What I am fairly confident about is the general shape of the mistake. A free-to-play wall is a machine for converting player failure into money, and I had spent the whole build carefully engineering failure out of the game. Those two projects were in direct opposition the entire time and I did not notice until I sat down with a calculator.
If you are building the fair version of something and monetising the unfair version of it, at some point one of them has to go.
Shikaku is on the App Store. Free to level 40, one payment for the rest, and the daily puzzle is free forever.