• v2.12.2 f8eb602d4c

    Emily released this 2026-11-11 07:17:05 +01:00 | 1 commits to main since this release

    Universal Gaming 2.12.2 — live sync between your devices

    Unfinished games now follow you from device to device while you play.
    Sign in, start a game on your phone, open the app on your desktop, and the
    game is already there — no button to press.

    How it works

    • A game is uploaded about a second after it changes, and every device polls a
      cheap revision cursor every five seconds, so a move made here shows up there
      almost immediately. Only the games that actually changed are downloaded.
    • A game that is open is never replaced under your fingers. If another
      device changes the game you are playing, the screen shows
      Updated on another device with a Reload action, and your own progress
      wins the conflict.
    • A game that is not open is adopted silently, so the continue badges on the
      home screen are already correct when you get there.
    • A finished game is cleared on the other devices instead of lingering as a
      stale "Continue" entry.
    • A device never reacts to the echo of its own writes: each installation has a
      random id, and the server records which device wrote last.
    • A game you played offline is uploaded rather than overwritten when you come
      back online — the newer local save wins.

    Where to find it

    Account → Live sync shows whether sync is running, the last sync time and a
    Sync now button, and switches the feature off per device. Everything is
    translated into German, Spanish, French and Italian.

    Bug fix included

    Sudoku saves are stored per difficulty (sudoku-hard, killer-sudoku-expert),
    but the save API only accepted the plain game ids, so any backup that
    contained a Sudoku game failed with 400
    . Both the backup and the new sync
    endpoint now accept the per-difficulty ids.

    Server

    Live sync needs backend 1.6.0 or newer (/api/v1/sessions, gated by
    SESSION_SYNC_ENABLED). Older servers keep working: the app reports
    This server does not support live sync and stays local-only.

    351 tests passing (app) and 68 tests passing (backend),
    flutter analyze clean.

    Assets

    Platform File
    Android UniversalGaming-2.12.2-android.apk (Android 7.0+)
    Android (Play) UniversalGaming-2.12.2-android.aab
    iOS UniversalGaming-2.12.2-ios-unsigned.ipa (re-sign with Sideloadly/AltStore)
    macOS UniversalGaming-2.12.2-macos.dmg (Apple Silicon + Intel)
    Linux UniversalGaming-2.12.2-linux-x86_64.AppImage
    Web UniversalGaming-2.12.2-web.zip

    Checksums are in SHA256SUMS-2.12.2.txt.

    Downloads
  • v2.12.1 0bdb2322fa

    Emily released this 2026-11-10 23:50:39 +01:00 | 2 commits to main since this release

    Universal Gaming 2.12.1 — the last English is gone

    The translation pass started in 2.12.0 is finished. With German, Spanish,
    French or Italian selected, no user-visible text remains in English.

    Newly translated

    • "How to play" for all eleven games — goal, rules, controls and tips for
      Sudoku, Killer Sudoku, Mahjong, Minesweeper, Klondike, Classic Solitaire,
      Spider, FreeCell, Pyramid, TriPeaks and Chess
    • The chess learning path — lesson titles, subtitles, goals and every step's
      prompt, hint and explanation, for all eight lessons
    • Chess online lobby — challenge form, section headings, status lines,
      sign-in gate and every error message
    • Account screen — sign in, register, password reset, profile, e-mail
      confirmation, account deletion, save backups and the server configuration
    • Web footer — outdated-build notice and links

    Under the hood

    • About 110 new ARB keys, plus two content tables: lib/l10n/game_help_text.dart
      (help sheet) and lib/games/chess/chess_lesson_l10n.dart (lessons). Both fall
      back to English, so a half-finished translation never shows an empty screen.
    • Tests now enforce the coverage: every game and language must be present with
      the same number of rules, controls and tips as the English sheet, and every
      lesson step must be translated. The layout test also renders the longest help
      sheet (chess) in all four languages on a 360 px phone.

    335 tests passing, flutter analyze clean.

    Assets

    Platform File
    Android UniversalGaming-2.12.1-android.apk (Android 7.0+)
    Android (Play) UniversalGaming-2.12.1-android.aab
    iOS UniversalGaming-2.12.1-ios-unsigned.ipa (re-sign with Sideloadly/AltStore)
    macOS UniversalGaming-2.12.1-macos.dmg (Apple Silicon + Intel)
    Linux UniversalGaming-2.12.1-linux-x86_64.AppImage
    Web UniversalGaming-2.12.1-web.zip

    Checksums are in SHA256SUMS-2.12.1.txt.

    Downloads
  • v2.12.0 37098c8d52

    Emily released this 2026-11-10 21:10:19 +01:00 | 3 commits to main since this release

    Universal Gaming 2.12.0 — five languages

    The whole interface now ships in English, German, Spanish, French and Italian.
    On first start the app follows the system language; if the device speaks none of
    the five, it stays in English. Settings → Language switches at any time, and
    "System language" hands control back to the device.

    What is translated

    • Every screen: home, game hub, all eleven games, leaderboard, onboarding, settings
    • Every dialog: win screen, promotion, resign, mode picker, clear leaderboard, update/news sheet
    • All controls, tooltips, status lines, counters and placeholders
    • Enum labels: Sudoku/Killer difficulties, Minesweeper levels, chess computer strength, chess sides and game status
    • Chess online statuses and challenge invites
    • Leaderboard game names

    Under the hood

    • Strings live in lib/l10n/app_{en,de,es,fr,it}.arb, generated from a single
      table in tools/build_l10n.py, so no language can drift or silently lose a key
    • context.l10n falls back to English when no localization delegate is installed,
      which keeps the existing widget tests working unchanged
    • The language choice is stored as AppLanguage next to the other settings

    Fixes

    • The Sudoku hero badge no longer overflows with the longer German text

    331 tests passing, flutter analyze clean.

    Assets

    Platform File
    Android UniversalGaming-2.12.0-android.apk (Android 7.0+)
    Android (Play) UniversalGaming-2.12.0-android.aab
    iOS UniversalGaming-2.12.0-ios-unsigned.ipa (re-sign with Sideloadly/AltStore)
    macOS UniversalGaming-2.12.0-macos.dmg (Apple Silicon + Intel)
    Linux UniversalGaming-2.12.0-linux-x86_64.AppImage
    Web UniversalGaming-2.12.0-web.zip

    Checksums are in SHA256SUMS-2.12.0.txt. Windows binaries must be built on a
    Windows host.

    Downloads
  • v2.11.13 64b9eedcb8

    Emily released this 2026-11-10 17:21:28 +01:00 | 4 commits to main since this release

    Universal Gaming 2.11.13

    Finishing the Sudoku number pad, and getting the sizes right.

    The pad is square where there is room

    2.11.12 put the nine keys in a 3 × 3 grid, but a third of a desktop or iPad side
    panel is a long, flat rectangle - so the keys still did not read as a pad.

    They are now square on tablet, desktop and web, capped at 104 px and centred,
    so the block stays a block instead of stretching with the window.

    Bigger keys on a phone

    Phones go the other way: the keys grow from 52 px to about 74 px tall (they
    scale with the window height, 58-82 px), and the digit scales with them. That is
    the size they should have had all along.

    Smaller secondary actions

    Undo, redo, erase, notes and hint are used far less than the number keys, so
    they give up their height: one slim row of five at 44 px instead of two rows
    of 54, with a smaller icon and label. That pays for the taller pad without
    shrinking the board - the 3 × 3 block still fits a 360 × 640 phone.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 318 tests pass
    • New tests: square keys on the wide layout (width equals height, capped at
      104), taller keys on a phone, and the five secondary actions sharing one row
      that is shorter than the number keys.

    Downloads

    Platform File
    Android UniversalGaming-2.11.13-android.apk
    Android (Play) UniversalGaming-2.11.13-android.aab
    iOS (unsigned) UniversalGaming-2.11.13-ios-unsigned.ipa
    macOS UniversalGaming-2.11.13-macos.dmg
    Linux x86_64 UniversalGaming-2.11.13-linux-x86_64.AppImage
    Web UniversalGaming-2.11.13-web.zip

    SHA256SUMS-2.11.13.txt lists the checksums of every asset.

    Downloads
  • v2.11.12 c1d09f0636

    Emily released this 2026-11-10 16:28:23 +01:00 | 5 commits to main since this release

    Universal Gaming 2.11.12

    One fix: the Sudoku number keys.

    The number keys are a 3 × 3 pad

    The nine keys used to sit in one long strip. On a phone that meant nine targets
    about 38 px wide - narrower than the cells they fill - and on a desktop window a
    row of very flat rectangles.

    They now form a 3 × 3 pad that mirrors the box the digits go into, so each
    key is a comfortable third of the panel and the numbers sit where the player
    expects them. Keys are 52 px tall on a phone and 56 px in the desktop side
    panel, with the remaining-count badge moved in from the corner to suit the
    larger target.

    The pad fits a 360 × 640 phone without squeezing the board out of the window.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 317 tests pass
    • New tests: the nine keys form three rows of three at phone and desktop widths
      (equal size, in reading order), a key still enters its digit, and the whole
      screen fits a small phone without overflowing.

    Downloads

    Platform File
    Android UniversalGaming-2.11.12-android.apk
    Android (Play) UniversalGaming-2.11.12-android.aab
    iOS (unsigned) UniversalGaming-2.11.12-ios-unsigned.ipa
    macOS UniversalGaming-2.11.12-macos.dmg
    Linux x86_64 UniversalGaming-2.11.12-linux-x86_64.AppImage
    Web UniversalGaming-2.11.12-web.zip

    SHA256SUMS-2.11.12.txt lists the checksums of every asset.

    Downloads
  • v2.11.11 fc8f7518e3

    Emily released this 2026-11-10 13:09:27 +01:00 | 6 commits to main since this release

    Universal Gaming 2.11.11

    Three fixes, no new screens.

    Sudoku playfields are sorted into a 3 × 3 block

    The five difficulty cards used to wrap 2 + 2 + 1 on a phone, leaving a hole in
    the menu. They now always lay out three across, with the short row centred
    underneath - three on top, two below - and switch to a compact type scale when
    three cards have to share a phone width, so nothing is cramped or truncated.

    While there: the hub advertised "4 difficulties" while there are five. It now
    reads the count from the difficulty list itself.

    Black chess figures are visible in dark mode

    Black figures are almost black, so on a dark surface - the move history, the
    captured-pieces row, the promotion dialog - they disappeared. In dark mode they
    now get a light rim, drawn exactly like the dark contour the white figures
    have always had.

    The board itself opts out: its squares are light in every theme, so a rim there
    would only read as a halo around every black piece.

    Online chess turns the board for black

    An online match knows which side you play. If you are black, the board now opens
    from your side, with your pieces at the bottom and the opponent's at the top.

    It happens once per match, so the Flip button keeps working and the two-second
    poll cannot undo your choice.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 313 tests pass
    • New tests: the three-across layout and the centred short row at phone and
      desktop widths, the rim in dark mode (and its absence in light mode and on the
      board), and the online board opening flipped for black while a manual flip
      survives the next poll.

    Downloads

    Platform File
    Android UniversalGaming-2.11.11-android.apk
    Android (Play) UniversalGaming-2.11.11-android.aab
    iOS (unsigned) UniversalGaming-2.11.11-ios-unsigned.ipa
    macOS UniversalGaming-2.11.11-macos.dmg
    Linux x86_64 UniversalGaming-2.11.11-linux-x86_64.AppImage
    Web UniversalGaming-2.11.11-web.zip

    SHA256SUMS-2.11.11.txt lists the checksums of every asset.

    Downloads
  • v2.11.10 11d346cacb

    Emily released this 2026-11-07 18:08:53 +01:00 | 7 commits to main since this release

    Universal Gaming 2.11.10

    The chess figures were cut off. This release fixes how they are drawn.

    What was wrong

    Two separate defects, both visible on the board:

    1. The figures came from different fonts. White pieces use the hollow
      Unicode set (U+2654-U+2659) and black pieces the filled one (U+265A-U+265F).
      On macOS the two sets resolved to different fonts with different metrics, so
      the white figures were drawn larger and lower than the black ones - and got
      shaved flat by the edge of their square.
    2. Every figure sat on a dark rectangle. The board drew a box shadow behind
      the glyph's layout box instead of behind the figure, so a blurred dark
      square appeared behind every piece.

    What changed

    • The figures now ship with the app: a 6 KB subset of Noto Sans Symbols 2
      containing exactly the twelve chess glyphs (OFL 1.1, licence included). One
      font for both colours means identical metrics on Android, iOS, macOS, Linux
      and the web - no fallback fonts, no colour emoji, no platform surprises.
    • tools/build_chess_font.py rebuilds that subset from the upstream font and
      centres the outlines on the baseline with symmetric ascent and descent, so no
      text engine can place the figures off-centre. Measured on the real renderers,
      the figures now sit within 1.5 px of the middle of their square.
    • The shadow follows the figure's outline instead of a rectangle.
    • Nothing clips a figure any more: Clip.none on the glyph stacks and on the
      board squares, visible text overflow everywhere.
    • Figures are drawn at 92% of a square; the small glyphs in the header, the
      move history, the captured-pieces row and the promotion dialog were scaled to
      match.
    • The VS15 presentation selector and the hollow-glyph workaround for white
      pawns are gone: with a bundled font that has no emoji, neither is needed.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 304 tests pass
    • Verified on the real renderers, not just in tests: a headless Chrome capture
      of the web build and a screenshot of the macOS build, plus pixel measurements
      of the figure bounds inside a square.

    Downloads

    Platform File
    Android UniversalGaming-2.11.10-android.apk
    Android (Play) UniversalGaming-2.11.10-android.aab
    iOS (unsigned) UniversalGaming-2.11.10-ios-unsigned.ipa
    macOS UniversalGaming-2.11.10-macos.dmg
    Linux x86_64 UniversalGaming-2.11.10-linux-x86_64.AppImage
    Web UniversalGaming-2.11.10-web.zip

    SHA256SUMS-2.11.10.txt lists the checksums of every asset.

    Downloads
  • v2.11.9 cd08ec07db

    Emily released this 2026-11-07 17:07:43 +01:00 | 8 commits to main since this release

    Universal Gaming 2.11.9

    A learning path for chess, patched into the Strategy section.

    What it is

    A guided course in eight short lessons that unlock one after another, ending in
    a full game against the computer:

    # Lesson You learn
    1 The pawn push two from home, capture diagonally
    2 The rook sliding along ranks and files, back-rank mate
    3 The bishop diagonals only, one colour forever
    4 The queen rook and bishop in one, Scholar's mate
    5 The knight the L-shaped jump and forks
    6 The king and check escaping check without stepping into danger
    7 Castling and promotion the two special moves
    8 Finishing the game queen mate and the two-rook ladder

    How it plays

    • Each lesson is a small board with a task: capture the rook, castle
      kingside
      , mate in one.
    • Tap a piece, tap a highlighted square. A wrong move is taken back and never
      counts against you; every step has a hint.
    • Solving a step shows the explanation, the last step finishes the lesson and
      unlocks the next one.
    • Progress is stored on the device (universal_gaming.chess.lessons.v1) and the
      hub card shows "3 of 8 lessons finished".
    • A restart action resets the path without touching saved games.
    • Open it from the new Learn chess card in the Strategy section or the school
      button in the chess header.

    Under the hood

    • Lesson content is data (lib/games/chess/chess_lessons.dart): a position by
      square names, side to move, castling rights, accepted moves in UCI form and an
      explanation. Mate puzzles accept any mate.
    • A test proves every position is legal (both kings present, the side not to
      move is not in check), every accepted move is playable and every mate puzzle
      really is mate.
    • The board moved into lib/widgets/chess_board.dart, shared by the game and
      the lessons.

    Also in this release (2.11.8)

    • The chess board grows with the window instead of stopping at 720 px, and the
      move history keeps a readable column next to it.
    • New full-screen button in the chess header: header, bottom bar and side
      panel disappear so the board fills the window; flip and close stay in the
      corner and Escape leaves the mode.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 300 tests pass

    Downloads

    Platform File
    Android UniversalGaming-2.11.9-android.apk
    Android (Play) UniversalGaming-2.11.9-android.aab
    iOS (unsigned) UniversalGaming-2.11.9-ios-unsigned.ipa
    macOS UniversalGaming-2.11.9-macos.dmg
    Linux x86_64 UniversalGaming-2.11.9-linux-x86_64.AppImage
    Web UniversalGaming-2.11.9-web.zip

    SHA256SUMS-2.11.9.txt lists the checksums of every asset.

    Downloads
  • v2.11.7 dca1178cc7

    Emily released this 2026-11-07 16:23:09 +01:00 | 10 commits to main since this release

    Universal Gaming 2.11.7

    Chess follow-up: the white figures are white now, and the board always fits.

    White figures were still black

    2.11.6 changed how the figures were painted, but the real cause was the
    character itself: U+265F (♟, the filled pawn) has Emoji_Presentation=Yes.
    Browsers and Android therefore drew it as a colour emoji, and a colour emoji
    ignores the fill colour - so the pawn stayed black no matter what was painted
    underneath. Reproduced with the web build in headless Chrome.

    • White figures now come from the hollow set (U+2654-U+2659), which is text
      by default on every platform, painted white with a dark contour stroke.
    • Black figures keep the filled set and additionally request text presentation
      with VS15 (U+FE0E).
    • The promotion dialog draws real ChessGlyph figures instead of a raw
      character, so it follows the same rules.
    • Verified by rendering all twelve figures in a real browser: the white pawn is
      white, the black pawn is black.

    The board was cut off

    The wide layout sized the board from the whole window (62 %) while the board only
    owned three fifths of the row, so the right-hand files were clipped.

    • The board is now sized from the window height and from the width left over once
      the move history keeps its 320 px minimum; the history panel takes the rest.
    • Checked at 1280x800, 1024x700, 880x420 and 430x900: the whole board is visible
      and nothing overflows.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 286 tests pass

    Downloads

    Platform File
    Android UniversalGaming-2.11.7-android.apk
    Android (Play) UniversalGaming-2.11.7-android.aab
    iOS (unsigned) UniversalGaming-2.11.7-ios-unsigned.ipa
    macOS UniversalGaming-2.11.7-macos.dmg
    Linux x86_64 UniversalGaming-2.11.7-linux-x86_64.AppImage
    Web UniversalGaming-2.11.7-web.zip

    SHA256SUMS-2.11.7.txt lists the checksums of every asset.

    Downloads
  • v2.11.6 a25cd8dbaa

    Emily released this 2026-11-07 11:31:49 +01:00 | 11 commits to main since this release

    Universal Gaming 2.11.6

    Bug-fix release for the chess board.

    Chess

    • White figures are white again. White pieces reused the filled (black)
      glyph set and were drawn as a white glyph with a dark stroke on top. On fonts
      whose filled glyphs are drawn with hairlines - the pawn most of all - the
      stroke was wider than the figure's thin parts, so the white body vanished and
      white pawns rendered as solid black shapes.
    • The outline is now a dark copy of the glyph scaled up by 9 % behind a
      full-size white body. Nothing is stroked, so every part of every figure stays
      white on every platform, while both sides keep sharing one glyph set.
    • This affects the board, the move history and the fallen figures.

    Checks

    • flutter analyze: clean
    • flutter test --concurrency=1: 282 tests pass

    Downloads

    Platform File
    Android UniversalGaming-2.11.6-android.apk
    Android (Play) UniversalGaming-2.11.6-android.aab
    iOS (unsigned) UniversalGaming-2.11.6-ios-unsigned.ipa
    macOS UniversalGaming-2.11.6-macos.dmg
    Linux x86_64 UniversalGaming-2.11.6-linux-x86_64.AppImage
    Web UniversalGaming-2.11.6-web.zip

    SHA256SUMS-2.11.6.txt lists the checksums of every asset.

    Downloads