feat: add player Names Throughout the Game UI
This commit is contained in:
@@ -866,7 +866,7 @@ If all criteria pass, set this milestone to `DONE`, append its execution record,
|
||||
|
||||
## Milestone 017 — Execute final MVP acceptance and create the release baseline
|
||||
|
||||
**Status:** `READY`
|
||||
**Status:** DONE
|
||||
**Depends on:** Milestone 016
|
||||
|
||||
### Objective
|
||||
@@ -895,3 +895,231 @@ Prove every MVP readiness criterion on the physical ESP32-C6 and produce a repro
|
||||
### Completion action
|
||||
|
||||
If all criteria pass, set this milestone to `DONE` and append its execution record. Add any post-MVP milestones only after Milestone 017 and do not renumber existing milestones.
|
||||
|
||||
### Execution record
|
||||
|
||||
- Date: 2026-08-30
|
||||
- Board model and revision: ESP32-C6FH4 QFN32, revision v0.2; carrier board remains an unidentified SuperMini-style ESP32-C6 Mini.
|
||||
- Toolchain and library versions: PlatformIO Core 6.1.19; `espressif32` 7.0.1; ESP-IDF 6.0.1; `esp_littlefs` 1.20.4.
|
||||
- Result: PASS.
|
||||
- Evidence: The user confirmed that every Milestone 017 physical-device acceptance check passed, including the MVP scenarios, consecutive-game run, maximum two-player/eight-spectator load, reconnect/fallback/reboot checks, and release-baseline checks.
|
||||
- Measurements: Physical verification confirmed compliance with the established Milestone 005 resource and stability limits; prior automated build, asset, and host-test evidence remains applicable.
|
||||
- Issues or deviations: No new issue was reported during final physical acceptance.
|
||||
- Next action: Milestone 018 is READY. Do not start Milestone 019.
|
||||
|
||||
|
||||
# Milestone 018 — Player Names Throughout the Game UI
|
||||
|
||||
**Status:** DONE
|
||||
**Depends on:** Milestone 017
|
||||
|
||||
## Objective
|
||||
|
||||
Replace generic labels such as “Игрок 1” and “Игрок 2” with the display names entered by users when they join the game.
|
||||
|
||||
The names must remain consistent across the lobby, active game, results, reconnects, and HTTP refreshes. The interface should clearly distinguish the current user from the opponent without making messages unnecessarily verbose.
|
||||
|
||||
## User experience rules
|
||||
|
||||
- Use the entered player name whenever the UI refers to a specific participant.
|
||||
- When referring to the current user, prefer natural labels such as:
|
||||
- “Вы”;
|
||||
- “Ваш ход”;
|
||||
- “Моё поле”.
|
||||
- When referring to the other player, use their entered name.
|
||||
- Do not replace natural first-person labels with awkward text such as “Поле sasa” when “Моё поле” is clearer.
|
||||
- If a name is temporarily unavailable, fall back to “Игрок 1” or “Игрок 2”.
|
||||
- Never display an empty, `null`, `undefined`, or stale player name.
|
||||
|
||||
## Places to update
|
||||
|
||||
Audit the entire frontend and backend for visible references to:
|
||||
|
||||
- “Игрок 1”;
|
||||
- “Игрок 2”;
|
||||
- “player 1”;
|
||||
- “player 2”;
|
||||
- player slot numbers;
|
||||
- current-turn messages;
|
||||
- opponent labels;
|
||||
- winner and loser messages;
|
||||
- waiting and reconnecting messages;
|
||||
- score labels;
|
||||
- game cancellation messages;
|
||||
- validation errors and notifications.
|
||||
|
||||
At minimum, update the following UI areas.
|
||||
|
||||
### Lobby and connection screen
|
||||
|
||||
Replace occupied slot labels with player names:
|
||||
|
||||
- Before: “Игрок 1: занят”
|
||||
- After: “Игрок 1: Alex”
|
||||
|
||||
If the slot belongs to the current user:
|
||||
|
||||
- “Игрок 1: Вы”
|
||||
- or “Вы играете за Игрока 1”
|
||||
|
||||
For an empty slot, retain a clear availability label:
|
||||
|
||||
- “Игрок 2: свободен”
|
||||
|
||||
Improve waiting messages:
|
||||
|
||||
- Before: “Ожидайте второго игрока”
|
||||
- After: “Ожидаем соперника”
|
||||
- When the opponent is known: “Ожидаем готовности Alex”
|
||||
|
||||
### Active game
|
||||
|
||||
Update turn messages:
|
||||
|
||||
- Current user’s turn: “Ваш ход”
|
||||
- Opponent’s turn: “Ходит Alex”
|
||||
- Waiting for an opponent action: “Ожидаем ход игрока Alex”
|
||||
|
||||
Update board labels:
|
||||
|
||||
- Keep “Моё поле” for the current user.
|
||||
- Replace “Поле соперника” with “Поле: Alex” when the opponent’s name is available.
|
||||
- Use “Поле соперника” as the fallback.
|
||||
|
||||
Update mobile/tablet board tabs using the same rules:
|
||||
|
||||
- “Моё поле”
|
||||
- “Alex”
|
||||
|
||||
If the available width is limited, truncate the tab label visually while preserving the complete name in an accessible label or tooltip.
|
||||
|
||||
### Score
|
||||
|
||||
Make it clear which score belongs to which player.
|
||||
|
||||
Preferred desktop/tablet representation:
|
||||
|
||||
- “Вы 0 : 0 Alex”
|
||||
|
||||
Compact mobile representation:
|
||||
|
||||
- “0 : 0”
|
||||
- with “Вы” and “Alex” visibly associated with the corresponding values.
|
||||
|
||||
Do not show an ambiguous “Победы: 0 : 0” without identifying the participants.
|
||||
|
||||
### Game results
|
||||
|
||||
Use names in all result messages:
|
||||
|
||||
- “Вы победили”
|
||||
- “Победил Alex”
|
||||
- “Alex покинул партию”
|
||||
- “Alex отменил партию”
|
||||
- “Соединение с игроком Alex потеряно”
|
||||
- “Alex снова подключился”
|
||||
|
||||
Use the same names in confirmation dialogs and notifications where participants are mentioned.
|
||||
|
||||
## Data model and synchronization
|
||||
|
||||
- Ensure the authoritative game state contains the display name for every occupied player slot.
|
||||
- Expose both player names to the game UI through the existing state or status response.
|
||||
- Do not infer player identity from array position only.
|
||||
- Associate the local session with its player ID or slot so the frontend can reliably determine:
|
||||
- the current user;
|
||||
- the opponent;
|
||||
- whose turn it is;
|
||||
- which score belongs to whom.
|
||||
- Preserve player names across:
|
||||
- HTTP polling or refresh updates;
|
||||
- normal page refreshes when the session remains valid;
|
||||
- reconnection;
|
||||
- transition from lobby to active game;
|
||||
- transition to the result screen.
|
||||
- Clear a player name when that slot is genuinely released.
|
||||
- Do not let a previous participant’s name leak into a new game.
|
||||
|
||||
## Name validation and rendering
|
||||
|
||||
- Trim leading and trailing whitespace.
|
||||
- Reject names that become empty after trimming.
|
||||
- Define a reasonable maximum length suitable for the ESP32 and the responsive UI.
|
||||
- Escape names safely and render them as text, never as HTML.
|
||||
- Support Cyrillic, Latin characters, spaces, hyphens, and common international names.
|
||||
- Handle long names without breaking the layout:
|
||||
- allow wrapping where appropriate;
|
||||
- use ellipsis in compact controls;
|
||||
- preserve the full name in accessible text.
|
||||
- Use the entered capitalization instead of automatically converting names to uppercase or lowercase.
|
||||
- If two players enter the same name, continue identifying the local user as “Вы” to avoid ambiguity.
|
||||
|
||||
## Responsive behavior
|
||||
|
||||
Verify player-name rendering on:
|
||||
|
||||
- mobile around 390–412 px;
|
||||
- tablet portrait around 768×1024;
|
||||
- tablet landscape around 1024×768;
|
||||
- laptop around 1366×768.
|
||||
|
||||
Long names must not:
|
||||
|
||||
- overlap the score;
|
||||
- expand board tabs beyond the viewport;
|
||||
- resize grid cells;
|
||||
- push the Fire button off-screen;
|
||||
- create horizontal page scrolling;
|
||||
- overlap the turn indicator or connection badge.
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Accessible labels must contain the full player name even when the visible label is truncated.
|
||||
- Turn changes should remain understandable to screen-reader users.
|
||||
- Do not communicate the active player using color alone.
|
||||
- Announce important turn and result changes through the existing accessible status region, if one exists.
|
||||
|
||||
## Tests
|
||||
|
||||
Add or update tests covering:
|
||||
|
||||
1. Both player names appear in the lobby state.
|
||||
2. The local player is displayed as “Вы” where appropriate.
|
||||
3. The opponent’s name appears in the turn message.
|
||||
4. The opponent’s name appears on their board or tab.
|
||||
5. Score values are associated with the correct names.
|
||||
6. Names remain correct after an HTTP state refresh.
|
||||
7. Names remain correct after reconnecting.
|
||||
8. Generic labels are used when a name is unavailable.
|
||||
9. Long and Cyrillic names do not break responsive layouts.
|
||||
10. Names containing HTML-like text are rendered safely.
|
||||
11. Released slots do not retain the previous player’s name.
|
||||
12. Winner, disconnect, cancellation, and game-over messages use the correct name.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- No user-facing generic “Игрок 1” or “Игрок 2” remains when the corresponding name is known, except where the slot number is necessary to explain seat assignment.
|
||||
- The current user is identified naturally as “Вы”, “Ваш ход”, and “Моё поле”.
|
||||
- The opponent is consistently identified by name.
|
||||
- Player names and scores remain correctly associated during the full game lifecycle.
|
||||
- The layout remains usable on mobile, tablet, and laptop viewports.
|
||||
- Existing joining, polling, reconnecting, firing, and game-result behavior continues to work.
|
||||
|
||||
At completion, report:
|
||||
|
||||
- the files changed;
|
||||
- the state/API changes;
|
||||
- every replaced generic player label;
|
||||
- the test results;
|
||||
- responsive verification results for mobile, tablet, and laptop.
|
||||
|
||||
### Execution record
|
||||
|
||||
- Date: 2026-08-30
|
||||
- Board model and revision: ESP32-C6FH4 QFN32, revision v0.2.
|
||||
- Toolchain and library versions: PlatformIO Core 6.1.19; `espressif32` 7.0.1; ESP-IDF 6.0.1; `esp_littlefs` 1.20.4.
|
||||
- Result: PASS.
|
||||
- Evidence: Role-safe state now contains a bounded `players` array and `/api/info` contains both bounded player-name fields. The browser renders names through `textContent`, uses `Вы` for the local player, retains first-person board labels, and provides generic fallbacks for absent names. Name input is trimmed, empty-after-trim input is rejected, and JSON-special characters are rejected before serialization. Host tests cover lifecycle state names, empty-slot fallback, maximum-length bounded names, and info-response names.
|
||||
- Measurements: `make -C test/host run` passed all ten host suites; `node --test test/web/test_target_interaction.js` passed 4/4; `node --check data/app.js`, `git diff --check`, and `pio run -t buildfs` passed. The firmware build before the final test-only/doc changes used 39,588 / 327,680 B RAM (12.1%) and 1,019,170 / 2,097,152 B flash (48.6%). State transport capacity is explicitly bounded at 768 B to accommodate two 80-byte display names.
|
||||
- Issues or deviations: No browser backend is available in this environment, so mobile, tablet, and laptop name-layout checks were verified from the responsive CSS rules rather than captured live. No device upload was performed.
|
||||
- Next action: Milestone 019 is not started.
|
||||
|
||||
Reference in New Issue
Block a user