menu-settings called openSettings('screen-menu') without the name arg —
input always came up blank even though the name was already saved
server-side. Track myName client-side (set on bootstrap + after a
successful save) and pass it through.
- playBestSolution() called bestSolution() (now async, hits the server)
without await/async — got a Promise object back, .moves was undefined,
autoPlayStep() bailed on its first tick. G silently did nothing.
- No way back to the menu from gameplay — add 🏠 HUD button + M key,
cancels any in-flight search/autoplay before switching screens.
- settings-save button now shows "Сохраняю…" and disables itself during
the request — previously gave no feedback while the fetch was in
flight, looked like a dead button even though it worked (confirmed via
server logs/DB — the save itself was never broken).
R/N/P/F/G/W/A/S/D and arrows all preventDefault()'d unconditionally,
even with focus in #settings-name-input — swallowed those letters
mid-typing (very noticeable for English names). Skip the hotkey handler
entirely when an <input> is focused.
- Favicon: 🚀 emoji via inline SVG data URI, both sokoban.html and php/index.php
- api.php: mb_substr() -> substr() (mbstring not enabled on the server)
- api.php: MariaDB rejects LIMIT directly inside NOT IN(...) (error 1235) —
wrap the top-5 subquery in an extra derived-table SELECT
Verified live against the deployed MySQL/MariaDB DB: whoami, set_name,
submit (insert + dedup + trim-to-5), top all round-trip correctly.
- php/: MySQL-backed (via config.php, gitignored) top-5 solutions per
level, cookie identity with rename, server-side progress for "Продолжить"
- Menu screens: Играть / Продолжить / Предыстория / Настройки, plus
placeholder start/end screens for a future intro/outro
- Lore screen: EXO:GRID backstory text (6 epochs, no gameplay changes yet)
- levels.js/solver.js copied in as-is
- sokoban.html: canvas game, entrance/exit door mechanic (level completes
by walking to the exit after all boxes are placed, not an alert popup),
solution search UI (modal with timer, cancel, "Решение найдено!" button)
- solver.js: A* with binary heap, true-distance heuristic, static
deadlock cells, freeze-deadlock detection, tunnel macro-moves,
chunked step() API for non-blocking search in the UI
- localStorage-backed solution leaderboard per level (fewest moves wins),
fed by both solver finds and manual player completions; G replays the
best recorded solution
- BACKLOG.md: known follow-ups (dead files, room/corral pruning, undo, etc.)