How I built a Wordle-style daily puzzle in SwiftUI (no backend)
I recently shipped Gemdoku: Daily Block Puzzle , a 9×9 block puzzle for iPhone. The core feature is a Wordle-style Daily Challenge: every player in the world gets the same goal, the same move limit and the exact same sequence of pieces each day. It turned out to be a fun little engineering problem. Here's how it works under the hood, all in plain Swift and SwiftUI, with no backend. 1. One puzzle…
I recently created Gemdoku: Daily Block Puzzle, a 9x9 block puzzle for iPhone. The main feature is a Wordle-style Daily Challenge, where everyone worldwide plays the same game, has the same move limit, and sees the exact same sequence of pieces each day. It was a fun engineering challenge, and I built it all in Swift and SwiftUI with no backend.
To give everyone the same puzzle, I generate it without a server. The game is fully offline, has no accounts, and doesn't collect any data. I use Swift's RandomNumberGenerator protocol to create a seeded random number generator for the puzzle. The SplitMix64 algorithm is tiny, fast, and good enough for games.
The same type of GameRNG serves both modes: with no seed, it falls back to the system RNG for Classic mode, and with a seed, it's fully deterministic. The seed is simply the date, generated by converting the date to a number in the format YYYYMMDD.
I faced a time zone bug early on. My first version used Calendar.current, which meant players in different time zones would have different puzzles and leaderboards. I solved this by creating a dedicated UTC calendar that all daily-related functions use. This ensures every player worldwide is on the same puzzle and leaderboard at 00:00 UTC.
Each day requires more than just a piece sequence. It also needs a goal, a move limit, and, on harder days, a starting layout. To avoid any changes to the goals from affecting the piece sequence, I derive the goal using a separate stream. I XOR the day's seed with a constant to create a unique stream for the goal. The piece sequence keeps the raw seed, allowing me to tune goals freely without changing the pieces.
The difficulty builds throughout the week based on the weekday. Mon and Tue are easy, Wed and Thu are medium, and Fri to Sun are hard. For the harder days, I start with blocks already on the board. Instead of a random scatter, I mirror each block four ways, creating a designed puzzle that reads like it was intentionally created.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.