Skip to content

Add Hindi (हिन्दी) as the eighth language (#856) - #869

Merged
margani merged 4 commits into
mainfrom
issue/856-hindi
Nov 12, 2026
Merged

margani merged 4 commits into
mainfrom
issue/856-hindi

Conversation

@margani

@margani margani commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Hindi speakers: please review before this is merged. The Hindi text here was machine-written, and the owner decided it must not reach players until a native Hindi speaker has read it. Reply on this pull request or on #856 with anything that reads wrong, unnatural or too long for a button. Where the strings live:

  • each game: the hi: { … } block in www/games/<id>/index.html (help, tutorial, buttons), and its name: { … hi: … }
  • menu and core: hi: { … } in www/index.html and in STR in www/lib/chogan.js
  • award titles and descriptions: hi: / dhi: on each line of the ACH list in www/lib/chogan.js
  • game names and one-line summaries: "hi" in www/games.json
  • Play Store listing: fastlane/metadata/android/hi-IN/
  • report form and issues page: worker/report/src/form.html, worker/issues/src/app.js

The pull request stays open and unmerged until that review is done.

Refs #856

What changed

  • Language: hi («हिन्दी», left to right) is the eighth entry of LOCALES; a hi/hi-* device opens in Hindi. Dates use hi-IN-u-nu-latn, numbers stay Western digits like the other left-to-right languages.
  • Strings: a hi block in the core, the menu and all 73 games (help, tutorials, buttons, aria labels), every game name and summary in games.json, every one of the 238 awards, the tower defence maps, the nonogram and jigsaw picture names, the manifest description, the privacy pages' title, and the report form and issues site.
  • Font: Vazirmatn and Nunito have no Devanagari, and Linux and ChromeOS often have no system font for it. So a subset of Noto Sans Devanagari (OFL) ships in www/fonts/noto-devanagari.woff2: the whole basic Devanagari block (U+0900–097F) with every conjunct, wdth fixed at 100, wght 400–800 (the app uses 400–800). It is 71,672 bytes; the full variable font is 642 KB. It is a third face of the Vazirmatn family with the same descriptors, so canvas games get it too, limited by unicode-range: U+0900-097F, U+25CC, and it borrows Vazirmatn's line metrics. The service worker precaches it, its licence is in www/fonts/OFL-NotoSansDevanagari.txt, and the APK check asks for it.
  • Profile cards: the palette and character cards are <button>s, which used the browser's own font; they now inherit the app font. Without this their Hindi names came from a system font (and would be boxes where there is none).
  • Search: the menu search drops the nukta, so «फुटबॉल» typed without it finds «बटन फ़ुटबॉल».
  • Language picker: two rows of four on a phone, one row of eight from 600px.
  • Store: a hi-IN listing (title, short and full description at 3,766 of 4,000 characters, eight screenshots from LANGS=hi tools/screenshots.sh). The other listings were at 3,989–3,999 characters, so their language line now says "eight languages, Hindi among them" instead of naming all of them (Persian and Chinese, with room, name them all).
  • Tests: tools/tests/lang-hi.js (new); testFontFaces moved to tools/tests/font-faces.js because tools/test.js is at its 1 MB guard, and now expects three faces; LOCALE_CODES and the per-language lists (device language, manifest, Way Out genre word, Chinese chess name, Backgammon "You start", Sums rings, store games, issues site) include Hindi; three Hillrider tests that hard-coded seven languages now compare with LOCALE_CODES; the Button Football award check reads the last field dhi. MIN_CHECKS is unchanged.

Proof

tools/tests/lang-hi.js, run alone (a small runner that loads one test file):

  • against origin/main: 160 failed of 239 (no hi in LOCALES, a hi-IN device opens in English, no Hindi dictionary anywhere, …)
  • against this branch: 0 failed of 541

tools/tests/font-faces.js: main 1 failed of 1 (two faces), branch 0 of 6.

Full suite on the branch, after merging current main (which added Minesweeper zoom #850 and the Sliding Puzzle arrow pad #854; their new strings got Hindi in the second commit, and minesweeper-zoom.js counts each key in every language):

$ node tools/test.js
همه‌ی 9772 بررسی سبز
test.js exit 0
$ PORT=8745 tools/browser-check.sh
ok  games/flood/index.html  (204422 bytes rendered)
All pages loaded without console errors (74 of 74)
browser-check exit 0

Font proof: Chrome DevTools CSS.getPlatformFontsForNode over the profile page in Hindi reports Noto Sans Devanagari (web) for every Devanagari glyph and no system Devanagari font. This laptop has Noto Sans Devanagari installed system-wide, so a screenshot alone would not have shown a missing web font; the first run did find system Devanagari on the profile cards, which is what the button fix above is for.

Screenshots

Playwright with Chrome, local server, Hindi, after document.fonts.ready, at 390×800 and 1280×800, light and dark: the menu, the four tabs, the language picker, Chess help, and Backgammon, Chess, Crazy Eights, 8-Ball Pool, Hillrider, Hokm, Ludo, Mahjong, Minesweeper, Spider, Storekeeper, Sudoku, Tanks and Way Out. No page errors. A few below.

Not tested / open

  • The translation itself: needs the native review above.
  • Android: no APK built here (CI builds it). Font rendering in a real Android WebView not seen.
  • Some game titles are cut with an ellipsis in the 390px bar beside counters (Mahjong «माहजोंग», Minesweeper «माइनस्वीपर»), the same way long titles are cut in other languages. Way Out is «निकास», a short word, so it fits.
  • The template in template/game/ has no Polish or French either and was not changed; new games need a hi block (see CONTRIBUTING.md, now "eight languages").
  • No changelog for past versions; the next release needs fastlane/metadata/android/hi-IN/changelogs/<code>.txt.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QY4t6rHpbsoE5aS15nw6Z7

Hindi, 390px light: Backgammon, Chess, Crazy Eights, 8-Ball, Hillrider, Hokm

Hindi, 390px dark

Language picker, 1280px

Menu in Hindi, 1280px

margani and others added 3 commits November 12, 2026 18:29
Hindi (hi, left to right, Western digits) joins LOCALES, with strings in
the core, the menu, all 73 games, games.json, the 238 awards, the
manifest, the privacy pages, the report form and the issues site, and a
hi-IN Play listing with screenshots.

Vazirmatn and Nunito have no Devanagari and many Linux/ChromeOS systems
have no font for it, so a subset of Noto Sans Devanagari (OFL, basic
block, wght 400-800, 71,672 bytes) ships as a third face of the
Vazirmatn family, precached by the service worker and checked in the
APK. Profile cards are buttons and used the browser font, so their
Hindi came from a system font; they now inherit the app font.

The menu search ignores the nukta, the language picker is 4+4 on
phones and 8 wide from 600px, and the other store listings name "eight
languages" to stay under 4000 characters. testFontFaces moved to
tools/tests/font-faces.js (test.js is at its size guard); new test
tools/tests/lang-hi.js.

Refs #856

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QY4t6rHpbsoE5aS15nw6Z7
main gained zoom buttons and a pinch hint in Minesweeper (#850) and an
arrow pad in Sliding Puzzle (#854) while this branch was open; their
new strings get Hindi too.

Refs #856

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QY4t6rHpbsoE5aS15nw6Z7
@margani margani added the needs-translation-review Waiting for a native speaker to review a translation label Nov 12, 2026
@margani

margani commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

Diff review

Why this shape. Hindi was added the same way French (#819) and Polish (#570) were. LOCALES stays the single list, and every per-language table that the tests can reach now reads LOCALE_CODES instead of a count. The one real design choice is the font. Vazirmatn and Nunito have no Devanagari, so without a bundled face Hindi would rely on the system: Android has Noto Devanagari, but many Linux/ChromeOS desktops show boxes. The bundled face is a 71.7 KB subset with the whole basic block, so a word a reviewer adds later still renders. It joins the Vazirmatn family with identical descriptors, the 2026-11-07 lesson from #684; tools/tests/font-faces.js guards that. testFontFaces had to move out of tools/test.js, which is at its 1 MB guard.

Side fixes that came from Hindi but touch every language:

  • button.ch-card { font-family: inherit }: the profile palette and character cards drew in the browser's default font in all languages. It was only visible in Hindi, through CDP's platform-font list.
  • The menu search drops the nukta.
  • The language picker grid is 4+4 / 8.
  • The other store listings' language line was shortened, because they had 1–11 characters of room left.

Tested

  • node tools/test.js: 9772 checks green.
  • tools/browser-check.sh: 74 of 74 pages, after merging current main.
  • tools/tests/lang-hi.js: 160 of 239 failing on origin/main, 0 of 541 on the branch.
  • tools/tests/font-faces.js: 1 of 1 failing on main, 0 of 6 on the branch.
  • CDP CSS.getPlatformFontsForNode on the Hindi profile page: only Noto Sans Devanagari (web) for Devanagari. This laptop has the font installed system-wide, so a screenshot alone could not prove it.
  • Playwright screenshots at 390×800 and 1280×800, light and dark: the menu, the tabs, the language picker, Chess help and 14 games. No clipping of matras or the headline, and no page errors.
  • LANGS=hi tools/screenshots.sh produced the hi-IN store shots. The en-US feature graphic it also rewrote was restored.

Not tested

  • The quality of the Hindi itself. It is machine-written: hence the label and the open PR.
  • An APK in a real Android WebView. CI builds the APK and checks that the font is inside it.
  • The report form and issues site Workers were not deployed; their tests run on the source.
  • The Minesweeper zoom and Sliding arrow strings added after the merge were not screenshotted. They are aria labels, tooltips and help rows, and add no visible text to the board.

Left out on purpose

  • MIN_CHECKS was not raised.
  • version.js and past changelogs were not touched.
  • No hi-IN changelog yet; the next release must add changelogs/<code>.txt there.
  • template/game/ still has no Polish, French or Hindi blocks.

Hindi for the games that arrived with Arabic (Fit Ten, Sudoku themes and
Killer, Football kick-off rule), nine-language picker and store texts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QY4t6nURUboWf82LgW2N4S
@margani
margani merged commit 6da420c into main Nov 12, 2026
4 checks passed
@margani
margani deleted the issue/856-hindi branch November 12, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-translation-review Waiting for a native speaker to review a translation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant