Inspiration

Most word games ask you to find a word. I wanted one that asks you to find the word — the single arrangement that uses every letter you have been given, with nothing left over.

That rule turns each round into a small chain. You start with three letters, build a word, receive one more letter, and rebuild from scratch. The tower grows one floor at a time:

RAY → AYRI → YARIM → YARDIM

I built Word Tower as a calm, offline-friendly Turkish word puzzle: no timers, no streak-shaming, no attention traps. One tower a day, a quiet page of paper and pencil, and a reason to look up a word you did not know.

What it does

Word Tower is a Turkish anagram-chain puzzle for mobile and web. Each floor gives you a pool of letters and one rule: use all of them.

  • Daily tower — one curated tower per day, plus an endless mode and a replayable archive
  • Twin floors and bonus words — some floors have two valid answers; extra words you find add to your score
  • Word meanings — every accepted word comes with its definition, and a personal word notebook collects the ones you discovered
  • Journey — 218 published towers grouped into chapters, with rest stops, collections and seals for finishing a tower clean, hint-free or error-free
  • Hints as an economy — credits earned from play can buy a first letter, a definition or the full word; upgrading a hint only charges the difference
  • Progress — statistics, streaks, achievements, a leaderboard and shareable result cards
  • Comfort settings — dark theme, high contrast, reduce motion, sound and haptics, full screen-reader support
  • Works offline — a session in progress keeps its tower, its accepted words and their definitions on the device

Playing does not require an account. Sign-in is optional, and the account can be deleted from inside the app.

How I built it

Client. Flutter, targeting iOS, Android and web from one codebase. State is Riverpod with immutable state objects — every move produces a new snapshot rather than mutating the last one, which made replay, undo and crash recovery fall out almost for free. The code is organised by feature (game, journey, economy, archive, notebook, shop, …), each with its own data / domain / logic / presentation layers, and an architecture test keeps those dependency directions honest. Firebase covers analytics, crash reporting and remote config; RevenueCat handles purchases and AdMob the optional rewarded ads.

Content pipeline. The puzzles are not hand-written. A set of Python tools filters a Turkish dictionary against a frequency list, generates every valid anagram chain, scores its difficulty, and runs validators for schema, anagram correctness, one-letter steps, dictionary membership and repeat spacing across a whole language line. Only what survives all of that reaches a human curator.

Backend. A NestJS + MongoDB service with an admin panel publishes content releases. The app fetches a single manifest and downloads only the packages whose SHA-256 hashes it does not already have; everything is verified before an atomic SQLite transaction swaps the active catalogue. The manifest also carries a reader version, so a release the installed app is too old to parse is refused cleanly instead of crashing on it.

Challenges I ran into

Turkish is a hostile language for this game. Measured on the same quality-filtered lists, English yields roughly ten times more four-floor chains than Turkish — 86,818 easy chains against 7,452. The cause is not morphology but anagram density: in three-letter pools, 17.3% of English arrangements are anagrams versus 8.5% in Turkish. Hard towers in Turkish bottom out at about a year of daily content. The fix was to stop deriving difficulty from entry length and compute it from the chain instead, and to accept that curation, not generation, is the bottleneck.

Turkish casing. toUpperCase() on a Turkish string gets i and ı wrong, which in a letter-tile game is not a cosmetic bug — it changes which tiles exist. That needed its own locale-aware utility used everywhere letters are rendered or compared.

Moving content off the bundle. The app originally shipped its catalogue as assets. Serving it from the backend meant the app could now start with nothing playable, so I added a full-screen content gate that holds startup — with its own retry, offline and too-old-to-parse states — rather than letting the home screen open onto an empty game.

Accomplishments that I'm proud of

  • It shipped. Word Tower is live on the App Store.
  • 218 curated Turkish towers, every one machine-validated and human-reviewed.
  • A content release can go out from an admin panel and reach players without an app update.
  • Immutable state end to end, with golden-image tests for the screens and a suite that runs clean under flutter analyze --fatal-infos.

What I learned

Generating puzzles is easy; deciding which ones are good is the real work, and no filter replaces a person reading the list. I also learned how much a language's own statistics constrain a game design — the same rules that give English years of content give Turkish months, and the design has to absorb that rather than argue with it.

On the engineering side: making state immutable early paid for itself repeatedly, and treating downloaded content as content-addressed and verified — never as "the server said so" — turned a whole class of corruption bugs into a single failed hash check.

What's next for Word Tower

  • Android release
  • English as a shipped language; the content pipeline already produces it
  • More journey chapters, monthly collection files and the discovery slot that is built but not yet populated
  • Deeper word-notebook features for the words players actually meet

Built With

Share this project:

Updates

Submission history