{Word Play} Project Report
1. The Concept
Word Play is a cozy, mobile-first word puzzle for short sessions. The player traces adjacent letters on a themed board, finds every hidden word before the clock runs out, earns gems, and fills a library bookshelf.
It is built for casual players who want something easy to start and satisfying to clear — no account, no download, no long tutorial. Open the file, tap Play, and you are in a level.
The unique hook in one sentence: trace winding paths of neighboring letters on a themed board, then collect books as you clear each cozy category.
The loop is small on purpose:
- Open Play or pick a level.
- Drag across neighboring tiles (8 directions, including diagonals).
- A matching unfound word scores; a miss clears the trail.
- Find every word before time hits zero.
- Earn a trophy, gems on first clear, and unlock the next level.
- Repeat, and watch the bookshelf fill.
Pressure comes from the timer. Relief comes from finding a word: a time bonus, a colored path on the board, and a slot filling in the HUD. Running out of time offers a fast Retry. Boosters (Hint, Shuffle, Reveal) are a soft safety net — they help, but they cap stars, so there is a real choice between playing clean and spending help.
Long-term carrot: 18 categories × 3 books = 54 books. Book 1 for starting a category, Book 2 for clearing all 5 levels, Book 3 for 3-starring the set.
2. The Stack
No framework, no npm install, no build step. The game is three core files plus art.
- HTML5 — screens, markup, ARIA labels
- CSS3 — cozy palette, phone shell (max 560px), motion
- Vanilla JavaScript (IIFE) — levels, tracing, save, boosters, audio
- Pointer events — same code for finger and mouse
- localStorage (
wordPlaySaveV1) — progress on the device - Web Audio oscillators — tap, success, fail, gem ticks
- Optional local server:
npx --yes serve .
File layout:
`` Word Play/ ├── index.html Screens and accessibility hooks ├── styles.css Layout, theme, motion ├── script.js Levels, tracing, save, boosters, audio ├── assets/ Background and UI images (webp / png) ├── rules/ Mobile-game UI doctrine ├── sakurai/ Design checklists (concept, loop, UI, sound, motion) └── README.md ``
Levels are data-driven: word banks and tunables sit at the top of script.js. Screens are a simple state machine (home / levels / game / bookshelf / settings). One screen is active at a time.
To edit: look and layout in styles.css, copy in index.html, words / timing / scoring / boosters in script.js, button art in assets/ui. Hard-refresh after CSS or JS changes; cache-bust query strings are already on the stylesheet and script tags.
3. The 1 Day Sprint (+ polish pass)
The goal for the day was a playable phone game, not a feature dump: a clear loop, a unique name, and a board that actually feels like a puzzle.
Morning (Hours 1–3):
Locked the core play. The letter HUD had to read like a word game (W . . D), not a dump of full answers. Every cell on the board had to belong to a word — a 16-tile grid means 16 letters that all become words, no leftover junk tiles. Paths had to wind (row snake, column snake, or spiral) and allow diagonals, so tracing felt like the reference, not a straight crossword.
Word length became a design rule, not an accident: 3, 4, 5+ letters, so early levels are friendly and later ones have bite. Word counts grow with the level (Level 1 is 0/4, Level 2 is 0/5, and so on). A startup validator rejects a board if a path is out of bounds, skips a neighbor, reuses a tile, misspells the word, or leaves unused letters. If generation fails, a small Nature fallback still lets the game open.
The rest of the morning was the phone shell: centering the board, shrinking HUD and booster plates until they fit a portrait screen, and making Play actually start a run.
Afternoon (Hours 4–6):
Gave the game an identity and a reason to come back. The title became Word Play — a name that does not collide with other word games on the shelf. The home lockup, gem pill, and art buttons had to survive a real phone, not only a desktop preview.
Boosters were tuned per run (Hint 2, Shuffle unlimited, Reveal 1), with gem buys if you burn the last use. The bookshelf grew from a small set into 18 categories (Nature through City), 5 levels each, 90 levels total, 54 books. Settings covered sound, music preference, reduced motion, and a confirm-to-reset.
This was also the mobile-layout grind: buttons that looked fine on desktop were huge on a phone; text that sat on wood vanished on a small screen; safe-area padding and a 560px shell finally made the game feel like a handheld.
The Finish Line (Hour 7-8):
Tightened the rules so later levels stay readable. Cap words per level at 10 (not 12). Keep every word between 3 and 10 letters. Do not reuse a word already used in that category, and keep consecutive levels from sharing the previous level’s list.
Shipped a skippable three-step intro on Level 1, with a coach icon, so a new player can learn the drag in one sitting. Fixed Play when an overlay ate the tap. Progress saves on device. Dev shortcuts (?level=12, ?unlock=all) made the last hour of testing honest instead of a 90-level click-through.
By the end of the day the loop was closed: trace, beat the clock, earn gems, unlock, collect.
Polish (Aug 10):
A dedicated pass for feel, not new systems.
- Library atmosphere: wood background, dark vignette, cream / ink / coral / teal / amber palette.
- Art buttons and booster glyphs on plates that stay readable on wood.
- Colored paths after a find, gem-fly on clear, toast + SFX within a beat.
- Pause that actually freezes the timer; Escape closes a modal or returns Home.
- ARIA labels on main actions, letter board, and live word HUD.
- Intro head icon so the first-run tutorial has a face, not only text.
- Cache-bust tokens so a polish CSS/JS change actually shows up on device.
What stayed out of scope on purpose: looping BGM (the music toggle is saved, tones cover feedback), accounts, leaderboards, and a “real” shuffle that rebuilds the layout.
4. The Roadblocks
**Covering boards.
** A pretty grid is easy. A grid where every tile is used exactly once, every path is a real neighbor step, and the letters spell the bank words — that took a generator plus a validator. Without the fallback board, a bad seed would have shipped a blank Play button.
“I limited it to 10, why do I still see 12?” Word-count caps, letter-length rules, and cache fought each other. The live game uses min(10, 4 + levelIndex) and a 3–10 letter bank; an old cached script.js or leftover README copy still described a 12-word / 6×6 world. Hard-refresh and cache-bust query strings became part of the workflow.
**Play did not click.
** Twice. Overlay, hit-target, or a screen that looked active but was not the one receiving pointer events. On a phone-first UI, a dead Play button is a dead game.
**Mobile vs desktop.
** Wood-on-cream text, oversized HUD boxes, booster plates, and brand lockup all failed on a real device after looking fine in a wide window. The fix was not “add a media query and hope” — it was shrinking the shell, centering the board, and checking portrait after every visual change.
**Too easy, then too tight.
** Full answers in the HUD made tracing trivial. Hiding letters (W . . D) and forcing mixed lengths brought the puzzle back. Then later levels tried to pack too many words; the 10-word cap and 7×7 ceiling kept the board readable.
**Shuffle is cosmetic.
** Mixing tiles visually and restoring the real layout is honest about what one day can ship. A true scramble needs another layout pass, not a fake shuffle that lies to the player.
**Booster inventory vs per-run counts.
** Saved defaults (Hint 3, Shuffle 2, Reveal 1) and per-run uses (Hint 2, Shuffle unlimited, Reveal 1) are not fully tied together. Good enough for a prototype; easy to confuse if you treat save data as the live loadout.
5. Key Takeaways
- **Ship the loop first.
** Screens, tracing, timer, retry. Collection and juice only matter after Play starts a level.
- **Put tunables in data.
** Word banks, time (36 + wordCount * 6 + gridSize * 4), gem reward, booster costs — all at the top of script.js. Balance is an edit, not a rewrite.
- **Validate generated content.
** A winding-path puzzle will produce illegal boards. Reject them at startup or the player will blame the game, not the generator.
- **Design for a phone in hour one.
** A 560px shell, large taps, icons over labels, and a skippable intro beat a “we will make it responsive later” plan.
- **Constraints make the puzzle.
** Covering paths, 3–10 letter words, no reuse inside a category, and a 10-word cap are more interesting than a bigger grid with leftover letters.
- **Help should cost something.
** Hint and Reveal cap stars. That is the risk/reward, not a shop wall.
- **Name collision is a product bug.
** “Word Play” had to be distinct on the home lockup, not a generic title that sits next to every other word game.
- **Cache is a gameplay bug.
** If the device is still running yesterday’s script, the designer thinks the cap “is not working.”
My final thought:
Word Play is a self-contained cozy puzzle: three files, a library on the screen, and a bookshelf that gives you a reason to come back tomorrow. The 1-day sprint proved the loop; the polish pass made it feel like a phone game. It is ready to open, play, and iterate — without a build pipeline, and without pretending it needs a backend to be fun.