Donpa Squad (ドンパ隊) — a manga-styled Minesweeper for Apple platforms (iOS 16+ and macOS 14+). Classic mode shipped first, and the "epic" variants it was architected for all landed on the way: huge zoomable maps, Round (torus) edges, and hex grids (the Hive family) — each added without touching the game logic.
v0.1.0 (classic mode), v0.2.0 (big boards + cross-device sync), v0.3.0 (board variants + the config/scoreboard redesign), v0.4.0 (friendly rivalry — peer-to-peer score sharing, rivals and squads, the home-screen redesign, per-board saves, forced-guess luck tracking, and the Lunatic tier), v0.5.0 (progression — achievements, unlockable boards, Drills, how-to-play, Nearby exchange, sound & haptics), and v0.6.0 (keyboard & accessibility, plus the daily challenge) shipped to TestFlight along the way. Donpa Squad is on the App Store (iPhone, iPad, and Mac — one Universal Purchase). See CHANGELOG.md for the version history, ROADMAP.md for what's next, and ARCHITECTURE.md for the key design decisions.
- Board families
- Controls
- Start and end of a game
- Scores
- Progression
- Rivals — the Mess hall
- Settings
- AI assistance
- Version history
- Development
- License
A Drills / Basic / Grid / Hive switch in the New Game popup chooses the
board family (open it from the home screen's New game button, the in-game
config badge, the result screen, or ⌘N):
- Drills — the practice family: every board is verified fully solvable by pure deduction (no forced guesses, ever) at a fixed 12 % mine density, in five sizes (XS–XL) with their own best times — learn the patterns, then speedrun them.
- Basic — the original Beginner / Intermediate / Expert presets.
- Grid — square cells (eight neighbours); pick a Difficulty and a Size, plus the board's Edges: Flat (a map with edges) or Round (the world curves back — a torus that scrolls seamlessly in every direction).
- Hive — hexagonal cells (six neighbours), same Difficulty / Size / Edges axes; each tier carries a touch more mines than Grid so the difficulty matches.
The Grid/Hive size ladder runs XS / S / M / L / XL / XXL / XXXL as powers of two (8² up to 1024² = a million cells); the larger boards are panned and zoomed, with a minimap for navigation. Difficulty is mine density, so it composes with any size — six tiers from Trainee up to Lunatic (classic Expert's 20%, where essentially every game forces real gambles). Each tier carries its military rank insignia — chevron stripes for the lower ranks, a star, a star-in-laurel, and the crescent moon for Lunatic. The chosen family and selections are remembered.
The size and difficulty rows are chip rows — every option visible, one tap to pick — with a line below each showing the board facts and a short flavour tagline. A small dot on a chip marks a selection path with a game in progress (family → size → difficulty → edges, each level filtered by the ones above), so you can find a parked game by following the lit chips down — and the Start button becomes Continue when the exact selection has one.
On macOS the popup is keyboard-drivable: ⌘1–4 pick the board family (Drills / Basic / Grid / Hive), ↑/↓ move between the remaining rows (Difficulty / Size / Edges), ←/→ cycle the selection within the highlighted row, Return starts, Esc closes.
New to Minesweeper? The ? on the home screen (also in About) opens a
short illustrated How to play guide — the goal, dig/flag, chording, the
mine counter, and forced guesses, each with a mini board. The long version
lives at donpa.app/how-to-play.
A toggle in a thumb-reachable corner of the board switches a tap/click between Dig mode and Flag mode, so you can place flags without risking an accidental reveal. Its corner follows the Toggle side setting (left/right) for your grip. A tap on a revealed number always chords in either mode, and a long-press is always the opposite primary action.
The board chrome is split in two: a thin top strip shows a tappable config badge (the current game's rank insignia + size, which opens the New Game popup) and read-only metrics — flag counter, live clear-%, timer, and the 🎖️ High Scores button — while a strip beside or below the board holds the Retry / Pause / Home actions plus the dig/flag toggle. Unopened tiles carry a faint manga screentone keyed to the toggle (dots for dig, hatch for flag).
| Action | Dig mode | Flag mode |
|---|---|---|
| Tap/click hidden | Reveal | Flag / unflag |
| Tap/click number | Chord | Chord |
| Long-press hidden | Flag / unflag | Reveal |
| Other | iOS | macOS |
|---|---|---|
| Other action | Long-press | Right-click or Control-click |
| Pan | Drag | Two-finger scroll / click-drag |
| Zoom | Pinch | Pinch (trackpad) or ⌘-scroll |
The other action (long-press, right-click, or Control-click) does the opposite of the current mode: in Dig mode it flags, in Flag mode it digs (and on a revealed number it chords, like a normal tap). So on a two-button mouse the toggle just assigns the buttons — Dig mode gives you left-to-dig, right-to-flag (the classic layout), Flag mode swaps them — and you never have to flip the toggle mid-game.
On macOS the pointer reflects the mode while a game is in progress — a pointing hand to dig, a flag to flag (a plain arrow otherwise); holding Control shows the other mode's cursor, since Control-click does the opposite action. Panning is bounded to the board: it rests with a little breathing room past each edge, and pulling further rubber-bands with resistance before springing back. When the whole board already fits on screen, panning is disabled. A Round board has no edges to hit — it pans forever, and the minimap's "you are here" box splits across the seam.
The whole app plays and navigates from the keyboard — on macOS, and on iPad/iPhone with a hardware keyboard (hold ⌘ there for the system shortcut overlay). ⌘/ opens the full in-app reference; the highlights:
| Key | Action |
|---|---|
| ↑↓←→/WASD | Move the board cursor (or a list/menu selection) |
| Return | Dig/chord at the cursor; press the focused button |
| F | Plant or clear a flag at the cursor |
| Space | Toggle dig/flag mode; toggle the focused control |
| Tab | Next control group on a screen (wraps) |
| Esc | Pause / resume; back out of any screen |
| ⌘N | New Game (opens the config popup) |
| ⌘R | Restart with the same setup |
| ⌘B | Return home to the Barracks |
| ⇧⌘M | Mess hall |
| ⌘F | Toggle mode |
| ⌘⇧S | High Scores |
| ⌘? / ⌘, | How to play / Settings |
| ⌘+ / ⌘− | Zoom the board in / out (also ⌘-scroll) |
| ⌘0 | Toggle the minimap between small and large |
| ⌘1–⌘4 | Pick the board family or screen tab |
The app opens on a home screen built around the title art: a Continue card shows your latest in-progress board (its progress, time, and when you last played — expandable to every board you have going), with New game, the Service Record, and the Mess hall below, and ⚙️ Settings / ⓘ About in the corner. Tapping the art continues the latest game (or opens New Game when nothing's in progress).
Every board keeps its own in-progress game — starting a quick round on another board no longer discards the big one you had going; a game is cleared when you win or lose it, and opening New Game or the Service Record mid-game pauses the clock. Return home any time from the in-game Home button or the Barracks menu item (⌘B) on macOS — the game pauses and saves, never discards.
When a game ends, a comic result panel slides in over the board — a triumphant one on a win, a dramatic one on a loss, with a "new record" flourish when you beat your best time. It dims only the board, so the control strip stays live:
- Retry / Home (and the config badge for a different game) remain usable on the chrome — no need to dismiss the panel first. Retry starts a fresh game with the same setup (new mines); the config badge opens the New Game popup.
- Dismiss the panel to inspect the finished board via the X, a tap anywhere, or Esc.
The 🎖️ button (in the top strip in-game, or on the home screen) opens the Service Record: per-board records — best time, games cleared, and best cleared-% from losses — plus lifetime career totals (games, tiles, flags, mines, playtime), a Breakdown of where your play goes (proportion bars across family, size, and difficulty, by playtime or game count), and the Decorations grid (see Progression). The board list groups by size, and once you've won every difficulty at a size the group shows your combined best — the full-clear time for that tier (Basic gets a Total for the classic trifecta). The row for the board you're playing is highlighted, and a new best is celebrated on the result panel (with the improvement over your old record).
Scores live locally (via UserDefaults) and can optionally sync across your
devices with iCloud — an opt-in toggle in the Service Record footer, off by
default. Synced devices merge their records for display while each device keeps
ownership of its own history; the reset action then offers a true cross-device
erase (a device that was offline during the wipe clears itself when it
reconnects). With sync off, everything stays on-device.
Stats are keyed by board geometry, not by tier name, so the format stays stable across variants: every family × edges combination — and any re-tuned tier — gets its own scoreboard entries rather than reinterpreting existing scores.
The board matrix unlocks as you play. A fresh install starts with sizes XS/S/M at the two lightest ranks on the square families; each win opens the next rung — sizes climb one at a time, ranks climb on wins at S or larger, the Hive opens on your first win anywhere, and Round edges open after a win at M or larger. Locked options stay visible with a padlock and tell you exactly what opens them; a win that opens something stamps an UNLOCKED sticker on the result panel. Boards arriving from a rival (head-to-head, a share link) are always playable — an invitation is the discovery moment. Established players pass every gate automatically: the gates read your existing records, nothing is stored, and a stats reset locks the ladder again.
Decorations — 20 achievements in the Service Record, each with its own hand-drawn medal: starters, skill feats with real floors (no farming Bare Hands on a tiny board), a luck feat that reads your recorded forced guesses retroactively, tiered volume milestones (bronze/silver/gold), and four hidden gags shown as ? until you stumble into them. Decorations are journey milestones, not progress trackers — chasing faster times or rarer luck is the scoreboard's job — and the whole block folds away (and stays folded) once it's served its purpose. Earning one stamps a gold DECORATION sticker on the result panel. Decorations sync across your devices under the same iCloud toggle as scores — and unlike scores, they survive a stats reset: they're history, not statistics.
The Mess hall (from the home screen) is the social room — peer-to-peer, with no server and no accounts:
- Share your scores. Your share card sits right on the screen: type a display name, optionally include career totals, and swap cards with Nearby exchange. Shares are signed by a key in your Keychain. The signature is what keeps a rival being the same person over time: the first share is taken on trust, but from then on updates apply only when they come from that same person — someone else reusing the name shows up as a separate add, never a silent overwrite. Your own devices present one identity via iCloud Keychain.
- Swap in the same room. Nearby exchange trades score cards with a player next to you over local Wi-Fi/Bluetooth — open the sheet on both devices, tap their name, and the cards cross both ways in one handshake (each side still confirms an incoming card before it lands). What you receive is a snapshot of the scores they chose to share (updated only when they swap again), kept strictly separate from your own records; removing a rival simply deletes their data. You can nickname a rival, and compare head-to-head board by board with a running tally. Your own other devices are hidden from the list.
- See where you stand. In the Service Record, expand any board for a leaderboard — your best slotted in among your rivals', fastest first, with a standing medal on the row.
- With iCloud sync on, your rivals follow you across your own devices under the same switch as scores.
The ⚙️ button opens settings (⌘, on macOS):
- Appearance — System, Light, or Dark; the board and chrome share one palette that follows the choice (System tracks the OS).
- Toggle side — which corner the dig/flag toggle hugs (left/right), for your grip.
- Question marks — add a ? step to the flag cycle (flag → ? → clear) for marking a maybe; off by default. A ? is only a note — it never counts as a flag for the counter or chording.
- Sound — procedural effects for opening, flagging, and the win/loss stings; on by default. On iPhone the Ring/Silent switch mutes them too, and they never interrupt your music.
- Haptics (iOS) — a light tap on flags, chords, and digs; on by default.
- Language — follow the system, or force English / Finnish / Japanese.
All selections are saved between launches.
Donpa Squad is built with substantial AI assistance, stated openly rather than hidden. The project is human-directed — design, gameplay, and every visual decision are the author's — but the code is largely AI-written and the current scene art (title, result, pause panels) is AI-generated (DALL·E). The procedural visuals (app icon, manga UI glyphs, board screentone) are AI-written code, not generated images. If commissioned art replaces the generated pieces later, this note will credit it.
High-level only — see CHANGELOG.md for the full detail (per-patch and per-build). Donpa Squad is on the App Store for iPhone, iPad, and Mac.
- The public 1.0. The full beta feature set, ship-shape: three board families (Basic / Grid / Hive) with Flat and Round edges, sizes from a tap to a million cells, the daily challenge, achievements, friendly rivalry, full keyboard play, and VoiceOver board play. For the store, remote score sharing narrowed to Nearby (in-person, peer-to-peer) — the link/QR channels and squads are parked, to return as bounded challenge cards.
- New (1.0.1): per-device stats — a Scores by device view breaks your synced record down across iPhone, iPad, and Mac, with device nicknames, "where a best was set" glyphs, and an All / iPhone / iPad / Mac career filter. Moving to a new device is handled cleanly (keep your history, or start the new device fresh), and Nearby now asks both players before swapping. Plus the fix that a daily-challenge clear counts as a career win.
- New: the whole app works from the keyboard — a focused-cell board cursor (arrows/WASD, Return digs/chords, F flags) and full navigation over every screen (Tab between control groups, arrows within, Return presses the focused button or the default, Space toggles, Esc backs out), on macOS and on iPad/iPhone hardware keyboards; ⌘/ opens a shortcut reference.
- New: the board plays with VoiceOver cell by cell — the cursor doubles as the screen-reader interface, speaking, moving, digging, and flagging the focused cell at any board size.
- Improved: a large-text/small-screen pass — score columns grow with accessibility text, sheets scroll instead of clipping, and every window and sheet fits scaled "larger text" Mac displays.
- Changed: the Mess hall header is compact everywhere (the rivals list gets the room) and Nearby is the share card's headline action, with the QR code full-size behind a button beside Share link.
- New: the Daily Challenge — one shared board per day, same layout and same luck for everyone. Every attempt opens in review (study freely — the clock starts on Start), retries are unlimited, and the day keeps your best time, pace, and attempt count. A calendar reaches back to day one; playing on the day builds a participation streak (a tiered Roll Call decoration at 1/7/30), shared score cards carry your dailies to rivals for a head-to-head Dailies section, and the career gains a Daily orders segment.
- New: pace — every win shows its 3BV/s sweep rate (a number board luck can't inflate), with recent and best pace per board in the Service Record; the raw skill reading the scoreboard builds on.
- Changed: decorations recalibrated as milestones, not progress trackers — the block folds away and stays folded, one luck badge and one Expert speed badge replace the luck/time ladders (20 total).
- New: strictly opt-in Game Center reporting of decorations — off by default, Game Center untouched until enabled, and a late opt-in reports everything already earned; the toggle lives under the decorations.
- New: an "Unlock all boards" Settings toggle skips the unlock ladder for experienced sweepers — freely reversible, wins earned meanwhile count.
- New: Spotlight/Siri shortcuts — "Continue my board" and "Start drills", no setup needed; plus a rare, well-timed App Store review ask.
- Improved: restarting keeps your zoom, the minimap pins to your toggle side, and family switching in New Game is instant on the Mac.
- New: Decorations — 22 achievements with hand-drawn medals in the Service Record: skill feats, retroactive luck feats, tiered milestones, hidden gags; synced, permanent, celebrated on the result panel.
- New: progressive unlocks — the size/rank/family/edges matrix opens as you win, with visible teasers and UNLOCKED stickers; veterans pass automatically via their existing records.
- New: the Drills board family — verified no-guess practice boards (XS–XL, 12 % mines) with per-size best times, on its own leftmost New Game page.
- New: Nearby exchange — swap score cards with a player in the same room, both directions in one handshake, over local Wi-Fi/Bluetooth; no server, nothing leaves the room.
- New: How to play — a
?on the home screen opens a short illustrated in-app guide (dig/flag, chording, the mine counter, forced guesses), with the long version at donpa.app/how-to-play. - New: sound and haptics — procedural sound effects (an open tick, a fuller cue when an area floods, flag/clear, and win/lose stings) and per-move haptics on iOS, both on by default and separately toggleable; the iPhone Ring/Silent switch mutes the sound too.
- New: an opt-in question-mark flag cycle (flag → ? → clear) for marking a maybe, off by default.
- Changed: new players start on Drills (the no-guess on-ramp); the iCloud sync switch also lives in the Mess hall, and sharing now asks for a name first.
- Improved: result pills restyled for contrast + Dynamic Type; a readability/VoiceOver pass across the app (spoken toasts and save-dots, 44 pt chips, combined rival rows).
- New: peer-to-peer score sharing — hand someone a QR code or a donpa.app link built from your best times (career totals opt-in). Shares are signed, so once someone adds you, later updates to your scores can only come from you; no server, no accounts. Opens from the system Camera and Messages too.
- New: rivals and squads — people you add stay as read-only snapshots, nicknamed and sorted into squads, with head-to-head comparisons and your rank slotted into every board's leaderboard. The Mess hall gathers all of it on one screen, and rivals/squads sync across your own devices with the same switch as scores.
- New: a game in progress on every board — starting a quick round no longer discards the big board you had going; New Game marks selections with a game in progress and offers Continue.
- Changed: the title screen became a home screen — a Continue card for your latest board (expandable to all of them), New Game, the Service Record, and the Mess hall. The Mac Game menu speaks it too (⌘B for home).
- New: the Service Record shows full-clear times (your combined best once every difficulty at a size is won) and a Breakdown of where your play goes, by playtime or game count.
- New: luck, tracked honestly — when no safe move exists (or a sealed pocket could never be resolved anyway), the exact odds of the guess you take are computed from what the board showed; the Record counts forced guesses faced, survived, and your luckiest escape, with a toast mid-game — its wording escalating with the odds beaten, from a lucky guess to a MIRACLE — and the same verdict stamped on the result screen. Chords count too. The number on the toast and the forced guess stamp is always the survival odds your click had at that moment — 86% on a loss means genuinely robbed, 25% on a win is one for the memoirs. A guess-death with no stamp means a safe move still existed somewhere: the board had more to say. Tracked on every board (the million-cell XXXL scores its sealed pockets). The bookkeeping is exact but conservative: a recorded guess always carries its true odds — never an estimate — but a rare position too tangled to analyze (and, on XXXL, anything other than a sealed pocket) goes unrecorded rather than mis-scored.
- New: a sixth difficulty, Lunatic (20% mines; Hive 22%) — the tier where the board fights back.
- Changed: times truncate instead of rounding up (a 49.95s clear is
49.9, matching the in-game clock), record improvements show the change you
actually see, and long clears roll into
h:mm:ss.t.
- New: Hive (hex) boards — a six-neighbour hexagonal grid alongside the square Grid, in both flat and wrapped edges (a hex torus that scrolls seamlessly in every direction).
- New: Round (torus) boards — an edges toggle where the board wraps, so panning off one side flows in from the other, forever. Scores are kept separate from Flat boards.
- Changed: the New Game screen is organized by board family — Basic / Grid / Hive (classic presets / square / hex), each with a Flat / Round edge toggle and its own remembered size and difficulty. It adapts to the screen: a swipe-pager on a phone, a family sidebar on iPad and Mac.
- New: the Service Record gained Family and Flat/Round filters and expandable per-board records — tap any board to see its own games, wins, best five times (with dates), and full career stats, shown the same way as your lifetime totals.
- Changed: board sizes rebalanced to powers of two (up to 1024² ≈ a million cells) and difficulty tiers re-tuned so the five ranks stay distinct on big boards. This resets all existing scores — a one-off clean slate before 1.0.
- New: a cross-device erase that stays erased (an offline device clears itself on reconnect instead of resurrecting old scores).
- Fixed: offline sync updates promptly, the minimap shows/hides reliably and follows light/dark changes, and the top status bar reads clearer.
- New: iCloud cross-device sync for high scores and career totals (opt-in, off by default; conflict-free, degrades to local-only when signed out).
- New: lifetime career stats (games, tiles, flags, mines, playtime) in a reworked one-sheet Service Record.
- New: bigger Modern boards — the size ladder now runs XS to XXXL (up to a million cells), panned/zoomed with a resizable corner minimap you can tap or drag to jump around.
- New: the New Game difficulty/size pickers became a swipeable carousel; a resumed game restores your camera position; macOS gained mouse/keyboard zoom.
- New: an over-flagged number (more flags around it than its count) gets a faint ring — a quiet nudge that you've slipped, without saying which flag.
- Changed: huge boards stay responsive (reveal, mine placement, and the minimap compute off the main thread; the first tap is always instant).
- Fixed: the cleared-% and loss "best %" now floor consistently; flags survive a loss; correctly-flagged mines don't detonate.
- Classic Minesweeper on iOS and macOS: first-click safety, flood-fill reveal, flagging, and chording, with a dig/flag input-mode toggle.
- Two board modes — Classic (Beginner / Intermediate / Expert) and Modern (a difficulty × size grid), chosen in the New Game popup.
- A SpriteKit board with pan/zoom, a manga theme (comic result, pause, and title panels), and a procedural detonating-mine app icon.
- Per-board best times + games-cleared stats, autosave/resume, pause, light/dark appearance, haptics, and an About screen.
The codebase is mostly a Swift package (Packages/DonpaCore): a pure
DonpaCore logic target with zero UI imports (fully tested) and a DonpaKit
SpriteKit + SwiftUI target on top; thin iOS/macOS app shells host it. All board
variation is isolated behind two seams — Topology (logical neighbours:
square ↔ hex, bounded ↔ wrapped) and CellLayout (coordinate → pixel) — so
new board types land as new conformers without touching the game logic.
ARCHITECTURE.md covers the load-bearing decisions and
AGENTS.md the conventions, build commands, and asset pipeline.
Requires Xcode 16+ and XcodeGen
(brew install xcodegen); the .xcodeproj is generated, not checked in. A
Makefile drives everything from the command line:
make # list the available targets
make run-mac # build + launch the macOS app
make run-iphone # build + launch on an iPhone simulator (DEVICE="SE" to pick)
make run-ipad # build + launch on an iPad simulator
make test # run the package logic tests (no Xcode project needed)
make uitest # run the iOS UI tests in a simulator (local only; not on CI)No third-party runtime dependencies (nothing ships in the app; SwiftLint / swift-format are dev-only tools, not SPM packages). CI runs SwiftLint (pinned) + swift-format, the logic tests (with coverage), and both platform builds.
Donpa Squad is free, with no ads and no in-app purchases. If it brightened a commute and you'd like to support the work, you can sponsor the developer on GitHub — entirely optional, and thank you.
Code: MIT. The name and brand assets ("Donpa Squad" / ドンパ隊, the icon, and the artwork) are reserved and not covered by the MIT grant — see TRADEMARKS.md. In short: fork the code freely, but a public fork needs its own name and branding.