feat(variants): default a registered account to Erudit + Russian Scrabble
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 22s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s

New Game opened on a single variant for everyone, which reads poorly on VK
where Russian Scrabble is the familiar game. A registered account now starts
with both Russian-alphabet games, so the picker offers a real choice with no
pre-selection.

A guest stays on Erudit alone and is invited to register for the rest: the
device-local guest has no profile at all, so the client-side fallback has to
keep matching the server. Registering promotes the set, but only while the
guest still carries the untouched guest default. Existing accounts are not
backfilled — the set they carry may be a deliberate choice.

The Telegram promo start-param becomes additive rather than a replacement,
with English Scrabble withheld from a Russian-speaking arrival; otherwise the
English campaign link would have taken Russian Scrabble away from every
account it onboarded.
This commit is contained in:
Ilia Denisov
2026-07-27 20:38:09 +02:00
parent 69b1a50644
commit b6d88da78c
19 changed files with 338 additions and 56 deletions
+23 -4
View File
@@ -245,9 +245,15 @@ arrive from a platform rather than completing a mandatory registration).
than stranding a user who never opened Settings on the creation-time seed.
- **Variant preferences (New Game gating).** Which variants a player may be matched into is a
per-user **profile** setting — `variant_preferences`, a set of `engine.Variant` labels
(`scrabble_en`, `scrabble_ru`, `erudit_ru`) edited on the Settings/Profile screen. New
accounts default to **Erudit only** (a DB column default); at least one variant must stay
selected. The picker is ordered **Erudit-first** everywhere. The preference gates the New
(`scrabble_en`, `scrabble_ru`, `erudit_ru`) edited on the Settings/Profile screen. A newly
**registered** account defaults to the two Russian-alphabet games — **Erudit + Russian
Scrabble** (a DB column default); a **guest** is deliberately narrower and starts on
**Erudit only** (`account.ProvisionGuest` writes the set explicitly), with New Game inviting
the guest to register for the rest. Registering promotes the set to the registered default
(`account.ClearGuest`), but only while the guest still carries the untouched guest set —
a player who chose their own set is never overruled, and **existing accounts are not
backfilled** when the default moves. At least one variant must stay selected. The picker is
ordered **Erudit-first** everywhere. The preference gates the New
Game picker on every create path the player **initiates** — auto-match, vs-AI and a friend
invitation the player **creates** — and the backend **enforces** it on those paths (a chosen
variant outside the caller's preferences is rejected with HTTP 400). An **invited** friend
@@ -316,6 +322,18 @@ arrive from a platform rather than completing a mandatory registration).
> `service_language`/`supported_languages` and the push `language` routing field, and
> gained `variant_preferences` on Profile/UpdateProfile.
> **Decision (2026-07-27) — registered accounts start on both Russian games.** The
> Erudit-only default was too narrow a first impression on VK, where Russian Scrabble is the
> familiar game: a **registered** account is now created with `erudit_ru + scrabble_ru`, so
> New Game opens with a real choice (and therefore no pre-selected variant). A **guest**
> stays on Erudit alone and is invited to register for the rest, which keeps the offline
> device-local guest — who has no profile at all — matching the server. **Existing accounts
> are not backfilled**: the set a player already carries may be a deliberate choice, and the
> two are indistinguishable in the data. The Telegram promo `start_param` correspondingly
> became **additive** rather than a replacement (it can only widen a set), with English
> Scrabble withheld from a Russian-speaking arrival — otherwise the English campaign link
> would have quietly taken Russian Scrabble away from every account it onboarded.
## 4. Accounts, identities, linking & merge
- One internal account may carry several **platform identities**
@@ -883,7 +901,8 @@ in either direction (the enqueue excludes the caller's `BlockedWith` set);
- **Profile**: `preferred_language` (en/ru; tracks the interface language — §4), display name, email
(confirm-code binding, see §4), **timezone**, the daily **away window**, the
**variant preferences** (`variant_preferences`, the matchable-variant set that gates New
Game — §3, defaulting to Erudit only, at least one enforced) and the
Game — §3, defaulting to Erudit + Russian Scrabble for a registered account and Erudit
alone for a guest, at least one enforced) and the
block toggles — all editable through `account.UpdateProfile`, which validates them:
a display name is Unicode letters joined by single ` `/`.`/`_`
separators (no leading/trailing/adjacent separators, ≤ 32 runes); the timezone is a
+7 -3
View File
@@ -174,7 +174,8 @@ resigning or by letting it lapse to the 7-day timeout — drops from your *finis
automatically, with no swipe needed; a normally finished AI game stays until you remove it, and
no other game type is auto-removed. The game types offered on **New Game** are
limited to the player's chosen **variant preferences** (see *Profile & settings*) —
Erudite-first, defaulting to Erudite only. Variants are shown by their **display name** — both Scrabble variants read
Erudite-first, defaulting to Erudite + Russian Scrabble for a registered player and to Erudite
alone for a guest. Variants are shown by their **display name** — both Scrabble variants read
"Scrabble"/"Скрэббл" and Erudit reads "Erudite"/"Эрудит" (by the interface language), and
the same name titles the in-game screen. This gates only **starting** a new game you initiate —
auto-match, a vs-AI game and a friend invitation **you create** — so a player still sees and plays
@@ -451,8 +452,11 @@ per-device preference and is hidden on desktop, where the board already fits and
**Preferences (which variants you can be matched into).** A profile setting picks the game
variants — Erudite, Russian Scrabble and English Scrabble, shown **Erudite-first** — you allow
yourself to be matched into; a **new account starts with Erudite only** — unless it was created
through the **promo bot's deep link**, which also enables **English Scrabble** — and you must keep
yourself to be matched into; a **newly registered account starts with Erudite + Russian
Scrabble**, and arriving through the **promo bot's deep link** also enables **English Scrabble**
when your Telegram language is not Russian. A **guest** starts with **Erudite only** and New Game
invites them to register for the rest; registering widens the account to the registered default.
Changing the defaults never rewrites accounts that already exist. You must keep
**at least one** selected. This list is exactly what **New Game** offers when you start a game
(auto-match, an AI game, or a friend invitation you create) — a variant you have not enabled is
not offered, and the server refuses it. It does not restrict games you are **invited** to: an
+8 -4
View File
@@ -177,7 +177,8 @@ e-mail) либо ввод фразы. Активные игры форфейтя
уберёшь её, и никакие другие типы партий автоматически не убираются. Типы партий
на экране **Новая игра**
ограничены выбранными игроком **предпочтениями вариантов** (см. «Профиль и
настройки») — сначала Эрудит, по умолчанию только Эрудит. Варианты показываются под **отображаемым именем** — оба варианта Scrabble
настройки») — сначала Эрудит, по умолчанию Эрудит и русский Scrabble у зарегистрированного игрока
и только Эрудит у гостя. Варианты показываются под **отображаемым именем** — оба варианта Scrabble
читаются как «Scrabble»/«Скрэббл», а Erudit — «Erudite»/«Эрудит» (по языку интерфейса),
и это же имя выносится в заголовок экрана игры. Это ограничивает только **старт** игры, которую ты
инициируешь, — авто-подбор, игру с ИИ и приглашение друга, которое ты **создаёшь**, — поэтому игрок
@@ -458,9 +459,12 @@ Telegram. Внутри VK Mini App те же настройки — и язык
**Предпочтения (в какие варианты тебя можно подбирать).** Настройка профиля задаёт варианты
игры — Эрудит, русский Scrabble и английский Scrabble, показанные **сначала Эрудит**, — в
которые ты разрешаешь себя подбирать; **новый аккаунт стартует только с Эрудитом** — если только
он не создан по **диплинку промо-бота**, который дополнительно включает **английский Scrabble**, —
и нужно оставить выбранным **хотя бы один**. Именно этот список предлагает **Новая игра**, когда ты
которые ты разрешаешь себя подбирать; **новый зарегистрированный аккаунт стартует с Эрудитом и
русским Scrabble**, а вход по **диплинку промо-бота** дополнительно включает **английский
Scrabble**, если язык Telegram не русский. **Гость** стартует **только с Эрудитом**, и «Новая игра»
предлагает ему зарегистрироваться ради остальных; регистрация расширяет аккаунт до набора
зарегистрированного. Смена набора по умолчанию никогда не переписывает уже существующие аккаунты.
Нужно оставить выбранным **хотя бы один**. Именно этот список предлагает **Новая игра**, когда ты
запускаешь партию (авто-подбор, игра с ИИ или приглашение друга, которое ты создаёшь), — не
включённый вариант не предлагается, и сервер его отклоняет. На партии, в которые тебя
**приглашают**, это не влияет: приглашённый друг может принять приглашение в **любом** варианте,