Crate Shift: Why Sokoban Is Harder to Build Than It Looks
Sokoban is one of those games that every programmer eventually decides to build. The rules fit in one sentence: push every crate onto its target. I'd played it for years, assumed I understood it, and started Crate Shift on a Friday afternoon expecting to finish by Sunday. I shipped it three weeks later, having learned things about puzzle design I hadn't expected to need.
The Push Mechanic Has More Edge Cases Than You Think
The core rule is straightforward: you can push a crate if the cell behind it is empty. But the implementation hides complexity. Crates can be adjacent to each other, and you can't push a stack — only one crate moves at a time. My first pass allowed a player to walk through crates if they approached from an angle that my collision check missed. Diagonal adjacency was the culprit: I was checking only the four cardinal directions for the player's new position but not also verifying the push destination was free before moving the player. The fix was simple once I found it, but it took two hours of playtesting edge cases I'd never thought to try. The second edge case was the move limit: when pushing onto a target square already occupied by another crate, the scoring update fired twice. This only surfaces in a specific puzzle configuration I hadn't generated yet. Lesson learned: write test puzzles specifically designed to break your assumptions, not just to exercise the happy path.
Building a Deadlock Detector
A deadlock in Sokoban is a state where one or more crates can never reach any target, making the puzzle unsolvable from that point. The most common deadlock is a corner deadlock: a crate pushed into a corner can never move again. I built a static deadlock checker that runs after every move. It flags any non-target corner cell and any non-target position where a crate is adjacent to two walls on perpendicular sides. When a deadlock is detected, the UI flashes the affected crate red and offers an undo prompt. I chose not to block the move entirely — some players may not notice the deadlock immediately and forcing them to undo before they've realized the situation is frustrating. Instead the visual warning and the undo prompt work together. Players who want to explore still can; players who trust the detector get a quick escape. This design choice reduced restart-from-beginning events by about 60% in internal testing.
Why I Hand-Crafted Every Puzzle
I spent two days trying to generate Crate Shift puzzles algorithmically. The approach was to place crates and targets randomly, then run a backward BFS from solved states to find reachable start configurations. It produced valid, solvable puzzles — but they were consistently unsatisfying. Generated Sokoban puzzles tend to have one obvious first move, several mechanical middle moves, and then a surprising constraint at the end that doesn't feel earned. Good Sokoban design introduces the constraint gradually, lets you see the target but not the path, and makes the insight feel like your own discovery rather than an accidental encounter. I couldn't teach an algorithm to do that. So every Crate Shift puzzle is hand-designed, tested with a fresh set of eyes, and refined until the moment of insight feels deliberate. Fewer puzzles, but every one worth solving.
Browse All Games