WritingEngineering
A block puzzle you can play with VoiceOver
The genre is a drag interaction, which means it has quietly excluded everyone who plays by ear. It did not have to.
Search the App Store for a block puzzle you can play with VoiceOver and you will not find one. Not because the genre is hard to make accessible, but because nobody bothered. The whole interaction is a drag: pick up a piece, carry it over the board, let go. A screen reader can tell you a piece exists. It cannot carry it anywhere.
O’Block 1.0.1 fixes that for the entire game, board included. This is what that took, and where it stops.
Every control gets a name
The easy half first. Every button in the app now has a name a screen reader can say, and a tap target at least 44 points on a side. That sounds like housekeeping, and it is, but the details matter in a game:
- The coin balance reads as “9,180 O’Coins”, not “9,180”. The coin mark is a drawing, so without a label every number in the app was a bare number.
- The hint and undo buttons read with their price: “Hint, 100 O’Coins”. You should know what a tap costs before you make it.
- Journey covers read their number and stars, or “Issue 3, locked”. Level cells read “Level 5, 2 of 3 stars”, or “Level 6, locked”.
- Leaderboard rows are one element each, rank, name and score together, instead of three separate stops.
- The blurred lists behind a play-gate are removed from the reading order entirely. If you cannot tap it, you should not have to swipe past it.
Dynamic Type is honoured up to 130 percent, and Reduce Motion collapses the line-clear animation to a single frame. Above 130 percent the fixed geometry of an 8×8 board and 86 point pills stops holding together, and a broken layout helps nobody, so it clamps there and says so.
The rack describes its pieces
Now the interesting half. A piece in the rack is a shape, and a blind player needs the shape, not a picture of it.
Where a name is enough, the rack uses one: “line of 4 across”, “2 by 2 square”, “one block”. Where it is not, because an L can have its open corner in any of four places, the rack reads the shape row by row after the name: “4 blocks, 2 wide by 3 tall. Row 1: block, block. Row 2: block, gap. Row 3: block, gap.” Verbose, but complete, and complete is the point. A player who cannot see the piece can still plan with it.
Double tapping a rack piece selects it. The hint says what comes next.
The board is 64 cells you can touch
The board itself is now 64 accessibility elements, one per cell, laid over the grid. Touch one and VoiceOver reads “Row 3, column 5, empty”, or “filled”, or “empty, ink cell” in Classic, or in the Journey, “filled, marked to clear” for a target.
With a piece selected, each cell’s hint says what a double tap would do, in full: “Places the 2 by 2 square covering row 3, columns 5 to 6; row 4, columns 5 to 6; completes row 4.” Every cell the piece would cover, and any line it would finish. That was the first thing a blind tester asked for, and it is the right question: a corner convention tells you where the piece starts, and nobody plays by where a piece starts. The tap follows the same logic: touching the middle of a gap a line should fill gets the line across that gap, not “does not fit here” because the piece’s corner would not go under your finger.
Nobody plays by touching 64 cells either. The board is one element ahead of its cells, “Board, 8 by 8”, and a double tap on it speaks the whole position in one go, row by row, then which lines are one cell from clearing and which cell they need. That started life as a rotor action on every cell, until a tester heard VoiceOver append “Actions available” to all 64 of them.
The pieces got names after some reading. Blind Tetris players call their pieces by letter, I, O, T, S, Z, J, L, and since O’Block’s pieces never rotate, the orientation is part of the name here: “T pointing left”, “L, foot at bottom right”, “S standing”, “corner, open at top left”. The row by row map still follows the four-block letters for anyone who does not know them, but a player who does has the shape in three words. Nothing is listed by hand; the name is read off the cells, so a T and an L of the same size can never share one.
Each screen opens on its news. A game opens on “Classic” with the two sentences a screen reader needs to play, not on “Back, button”. A result page opens on its summary, “Daily, August 26. 4530 points. Time 26 seconds. Day one. Come back tomorrow. Share is next”, with the details still there to swipe through.
The numbers say what they are too. “110” on its own is nothing; “Best score 110”, “Time 38 seconds”, “Score 320, combo times 2” are the game. The ink meter, three dots a sighted player learns by watching, explains itself in its hint: clear a line through an ink cell to earn a charge, three charges swap a piece.
After the drop the game speaks: “Placed. Score 320.” or “Cleared 2 lines. Score 640. Combo times 2.” When the last piece of a rack goes down, the new three are announced by name. A hint is spoken too, and so is the ending of a run.
The How to Play screen, a tiny board you drag one piece into, was the one place a screen reader could do nothing: a drag is the only gesture it offered. It now plays like the real board, a named piece and cells that say what a double tap covers, and its prompt reads “Double tap a cell in the gap” when a screen reader is running instead of “Drag the piece”.
None of this touched the drag. The cell overlay has no pointer handling at all, so a sighted player’s game is exactly what it was.
What we are not claiming
The board cells are 42 points on a 393 point iPhone, because that is what eight cells across a phone come to. Apple’s 44 point rule is for controls, and we hold it on every control; the grid is the game.
We tested this with VoiceOver. We have not tested Switch Control or Voice Control, so “playable with VoiceOver” is the claim, and “fully accessible” is not.
And the secondary grey text in the app sits at a 3.5:1 contrast ratio, under the usual 4.5:1 body-text guideline. We know. It is on the list.
Keeping it honest
The whole thing is covered by a test that walks every screen and checks that each tappable element has a name and a 44 point target, then plays a Classic game through the accessibility tree: select a piece, tap a cell, confirm the rack slot reads “Empty slot” afterwards.
The test loads the app’s real fonts before it runs. The default test font sets every glyph a full em wide, roughly twice the width of the one we ship, and with it the settings rows overflow on a phone that fits them comfortably. The layout under test has to be the layout players get, or the test is checking a different app.