chip-gameV3/CONTEXT_DUMP_2026-09-16.md

22 KiB
Raw Permalink Blame History

Дамп контекста проекта chip-gameV3

Дата формирования: 2026-09-16
Часовой пояс: Europe/Moscow
Назначение: восстановление рабочего контекста в новом чате Codex.

1. Быстрый старт для нового чата

Проект находится в:

C:\Users\bondars\UnityProjects\chip-gameV3 WORK

Перед любой задачей:

  1. Полностью прочитать AGENTS.md в корне проекта.
  2. Запросить релевантный контекст через MCP-сервер agentmemory.
  3. Проверить git status --short --branch, текущую ветку и чужие незакоммиченные изменения.
  4. Если задача касается Unity, обязательно сначала прочитать состояние и релевантные ресурсы через unityMCP.
  5. После Unity-изменений проверить через unityMCP компиляцию, Console, тесты и визуальный результат, когда он применим.
  6. Не считать Unity-задачу завершённой без этой проверки. Если unityMCP недоступен — прямо сообщить пользователю.

Основной язык общения и сообщений коммитов — русский.

2. Состояние Git на момент дампа

  • Активная ветка: master.
  • HEAD: 70c4dbd081fc602a6fa54ca66f92347667d85442.
  • Коммит: Унифицировать работу с контроллером и улучшить загрузку персонажей.
  • master, chip-gameV3-remote/master, feature/redesign-sega и chip-gameV3-remote/feature/redesign-sega указывают на 70c4dbd.
  • Перед созданием этого файла рабочее дерево было чистым.
  • Remote: chip-gameV3-remote → http://172.11.0.14:3000/Robotail/chip-gameV3.
  • Старое состояние master пользователю не требуется; текущая версия уже опубликована в удалённый master fast-forward push.
  • Сам этот дамп создан после синхронизации и на момент создания ещё не закоммичен.

Последние значимые коммиты:

70c4dbd Унифицировать работу с контроллером и улучшить загрузку персонажей
ca42cf5 Усильте авторизацию плат и восстановление COM-соединения
ded80f0 Обновить игровые системы и интерфейс
826ff57 Доработать игровые режимы, призы и настройки
16847fe Обновить игровые системы и удалить устаревший код
a656816 Удалить устаревший код и упростить структуру проекта
f86eed2 Улучшить PvP-аватары, цвета поля и настройку таймеров
16ab9e4 Добавить оплату повторов в PvE и PvP
ebc47a8 Доработать PvP и ранний выход из игры

3. Unity и зависимости

  • Unity: 6000.4.8f1 (f8b72d3d7343).
  • Основная сцена: Assets/Scenes/GameScene3D.unity.
  • Render Pipeline: URP 17.4.0.
  • Addressables: 2.9.1.
  • uGUI: 2.0.0.
  • В проекте используются DOTween, UniTask, Newtonsoft.Json, SQLite, QRCoder и NuGetForUnity.
  • MCP for Unity подключён пакетом com.coplaydev.unity-mcp.

Последняя подтверждённая Unity-проверка перед дампом:

  • компиляция завершалась без ошибок;
  • Unity Console: 0 ошибок;
  • короткий Play Mode smoke test: 0 ошибок;
  • EditMode: 1/1 существующий тест успешно;
  • тест независимого чтения COM-осей: horizontal=-1, затем vertical=1, success=True.

Важно: непосредственно при создании дампа unityMCP был недоступен на http://127.0.0.1:8080/mcp, поэтому текущее состояние Editor повторно не считано. Это нужно перепроверить в новом чате после запуска/подключения сервера.

4. Обязательные соглашения проекта

DOTween

Новые Tween и Sequence в этом проекте автоматически не запускаются. После создания обязательно вызывать PlayForward() или Play(). Если метод только возвращает анимацию, запуск делает вызывающий код.

Структура C#-скриптов

Строгий порядок:

  1. public event;
  2. public поля;
  3. [SerializeField] private поля;
  4. private поля;
  5. свойства;
  6. Unity-методы в стандартном порядке;
  7. публичные методы;
  8. приватные методы.

Именование:

  • публичные поля — camelCase;
  • публичные события — PascalCase;
  • сериализованные приватные и обычные приватные поля — _camelCase;
  • свойства — PascalCase;
  • параметры — camelCase.

Не добавлять /// <summary>. Комментарии использовать только для сложной или неочевидной логики.

Работа с файлами и Git

  • Сохранять чужие и несвязанные изменения.
  • Для ручных правок файлов использовать apply_patch.
  • Не применять git reset --hard или git checkout -- без прямого запроса.
  • Сообщения коммитов писать только по-русски.

5. Основная архитектура

Ключевые каталоги Assets/Scripts:

  • Core — bootstrap и порядок инициализации;
  • Common — GameManager и общие сервисы;
  • Gameplay — поле, игроки, боты, ходы, таймеры, level bar, результаты;
  • Characters — PvE-персонажи, определения и Addressables-загрузка;
  • Input — единый ввод, COM, клавиатура, конфиг пинов;
  • Payment — баланс, цены входа и реванша;
  • PrizeSystem и Vitrina — призы, TakeOrRisk, QR, витрина, остатки;
  • UI — меню, переходы, модальные панели;
  • Settings — настройки, пароль, тесты, счётчики, остатки;
  • Statistics и Leaderboard — статистика и рейтинг;
  • Audio — музыка и SFX;
  • Media — видеофоны и связанная логика.

Ключевые точки входа:

  • Assets/Scripts/Core/Bootstrap.cs
  • Assets/Scripts/Common/GameManager.cs
  • Assets/Scripts/Gameplay/TurnManager.cs
  • Assets/Scripts/Gameplay/Player.cs
  • Assets/Scripts/Characters/CharactersController.cs
  • Assets/Scripts/Characters/CharacterDefinition.cs
  • Assets/Scripts/Input/In.cs
  • Assets/Scripts/Input/COMinput.cs
  • Assets/Scripts/Input/ComInputConfiguration.cs
  • Assets/Scripts/Input/ComSystem/ComWrapper.cs
  • Assets/Scripts/Input/ComSystem/ComPortScanner.cs
  • Assets/Scripts/Input/ComSystem/BoardAuthentication.cs
  • Assets/Scripts/Payment/System/PaymentSystem.cs

6. Актуальная система ввода и COM

Физический ввод

  • Контроллер сам присылает строки INPUT<decimal> при изменениях входа. Опрос ввода командой не нужен.
  • Десятичная маска преобразуется в строго 26-битную строку с ведущими нулями и разворотом порядка битов.
  • Некорректные, нечисловые и выходящие за 26 бит пакеты отклоняются.
  • COMinput дополнительно защищён от пустых и коротких пакетов; прежний Substring больше не вызывает ArgumentOutOfRangeException.
  • Логические входы active-low: символ 0 означает нажатое состояние.

Конфиг управления загружается из:

Assets/StreamingAssets/ComInputConfig.json

Актуальная конфигурация в репозитории:

{
  "leftJoystick": {
    "up": 0,
    "right": 2,
    "down": 3,
    "left": 1,
    "action": 8
  },
  "rightJoystick": {
    "up": 4,
    "right": 7,
    "down": 6,
    "left": 5,
    "action": 9
  },
  "serviceButton": 10
}

Не заменять эту схему на первоначально предполагавшиеся последовательные индексы без повторной проверки реального контроллера: текущая схема получена после диагностики фактических сообщений платы.

Независимое чтение осей

In.GetAxis(..., Discrete) исторически потреблял события обеих осей, даже если вызывающий код использовал только .x или .y. Это ломало:

  • перемещение первой фишки до первого хода, потому что BackToMenuController съедал горизонталь;
  • вертикальную прокрутку левой панели меню, потому что Menu съедал вертикаль.

Исправление:

  • добавлены In.GetHorizontalAxis(...) и In.GetVerticalAxis(...);
  • BackToMenuController, Player, Menu и MenuPanelsScroll читают только нужную ось;
  • при JoystickSide.Both оба физических события опрашиваются без short-circuit, чтобы второе одновременное нажатие не оставалось в буфере.

Режимы управления

  • PvE: первый игрок управляется обоими джойстиками (Player.ControlSide = JoystickSide.Both).
  • PvP: игрок 1 — левый джойстик, игрок 2 — правый.

Инициализация и авторизация платы

  • При подключении сначала отправляется команда перезагрузки 00.
  • Нужно дождаться сообщения с префиксом ver_; оно означает готовность контроллера после перезагрузки.
  • Затем компьютер отправляет 07 + 32 HEX-символа.
  • Контроллер отвечает CHAL + 32 HEX-символа.
  • Компьютер отвечает 08 + AES-256 результат, используя существующий обфусцированный ключ в BoardAuthentication.cs.
  • RAES, AUTH_PC_OK и промежуточные статусы не означают завершение авторизации.
  • Авторизация завершена только после отдельной точной строки READY!.
  • При длительном отсутствии сообщений выполняется ping, затем переподключение.
  • При запуске приложения отправляется 856001 для включения подсветки.
  • При выходе отправляется 856000 для выключения подсветки.
  • Используется один тип периферийного контроллера: DeviceType.Controller.
  • PrizeShowcase остаётся отдельным устройством витрины, а не вторым типом контроллера.

7. Персонажи и Addressables

  • Тяжёлые prefab-персонажи и их видеофоны вынесены в Addressables.
  • Лёгкие данные хранятся в CharacterDefinition/ScriptableObject и доступны без загрузки prefab.
  • В меню предварительно загружается первый PvE-персонаж — Куб — и его видеофон.
  • Для текущего PvE-персонажа поддерживается окно соседей, доступных для следующего перехода.
  • CharactersController.ShowCharacter теперь ожидает только целевого персонажа и его видеофон через PrepareTargetAsync.
  • Остаток окна подгружается асинхронно через PreloadWindowRemainderAsync и не задерживает начало раунда или переход, если нужный персонаж уже готов.
  • При смене окна ненужные экземпляры персонажей и video handles освобождаются.
  • При переходе в PvP PvE-окно приостанавливается; PvP-персонажи 6 и 7 обслуживаются DualAvatarController.

8. Игровые режимы и оплата

  • Вход в PvE и PvP требует успешного списания через PaymentSystem.
  • Неуспешная оплата воспроизводит звук и показывает мигающий NotEnough в CoinCounter.
  • Реванши PvE и PvP имеют отдельные цены и также выполняют попытку списания.
  • Ранний выход до первого хода доступен только после подготовки первой фишки.
  • При раннем выходе первая подготовленная фишка возвращается в пул.
  • Стоимость входа возвращается на баланс при раннем выходе из PvE/PvP; возврат не попадает в счётчики выручки.
  • Игра считается запущенной для статистики только после первого фактического хода.

PvE:

  • учитываются только время размышлений игрока и его ходы;
  • паузы и время бота не включаются;
  • результат показывается с задержкой 3 секунды;
  • GameplayLevelBar отражает пройденных/текущего бота, наличие приза и таймер;
  • на одного бота выделяется 2 минуты, истечение времени считается поражением;
  • после победы над последним ботом показывается Victory/NameInput с русскими буквами и цифрами.

PvP:

  • раунд показывает Win PvP, победителя и кнопки меню/повтора;
  • матч идёт до 5 очков;
  • после полной победы повтор сбрасывает очки;
  • используются персонажи 6 слева и 7 справа;
  • при входе: Sleep → перемещение в кадр → Appear;
  • победителю отправляется Win, Lose отсутствует;
  • при выходе персонажи уводятся на скрытые позиции, Animator отключается;
  • поле окрашивается в три настраиваемых цвета;
  • на ход даётся 30 секунд; по таймауту текущая фишка автоматически сбрасывается;
  • подписи таймеров упрощены до Игрок 1 и Игрок 2.

9. Призы, настройки и статистика

Реализованный функциональный контекст:

  • несколько призов на одного персонажа;
  • таблица призов в меню использует IconSmall визуального модуля персонажа;
  • модальное окно призов открывается действием на левой панели и закрывается повторным действием или через 20 секунд бездействия;
  • модальное окно рейтинга показывает последние 100 записей, последнюю запись внизу и ускоренную прокрутку обоими джойстиками;
  • в меню показывается топ-3 рейтинга;
  • TakeOrRisk: взять приз и выйти либо пропустить и продолжить к более ценному призу;
  • QR-приз показывает QR-панель с таймаутом 5 минут;
  • витринный приз сверяет физически доступные ячейки, предлагает выбор и ждёт подтверждение выдачи;
  • Countable-приз уменьшает остаток только после успешной выдачи; QR и Vitrina не уменьшают этот счётчик;
  • контроль остатков содержит включатель, добавление, установку количества и ускоренное перелистывание;
  • надпись об окончании маленьких призов показывается только при включённом контроле и нулевом остатке;
  • реализованы экранный RGB-тест, тест управления, тест звука;
  • пароль настроек — комбинация из 6 движений джойстика, хранится отдельным файлом в persistentDataPath;
  • панель счётчиков содержит сбрасываемые и несбрасываемые показатели игр, выручки, призов, времени и результатов по каждому боту/сложности;
  • статистика побед/поражений ведётся по каждому из 5 ботов и каждой сложности.

10. Звук и визуальные эффекты

  • SoundManager использует два AudioSource: музыка и SFX.
  • SFX проигрываются через PlayOneShot с передачей AudioClip вызывающей стороной.
  • Лишний пул дочерних AudioSource удалён.
  • Очистка поля проигрывает звук только если поле действительно было непустым.
  • WinDots на победных фишках использует синхронную покадровую анимацию blik со скоростью 40 FPS.
  • Анимированный объект WinDots не перемещается по диагонали: локальная позиция (0, 0), scale 1.
  • Для Robowolf перед Appear должен вызываться триггер Sleep как сброс Animator.

11. Известные условия и проверки для следующей задачи

  • Реальный COM-контроллер периодически подключался к COM3, но в последней проверке ввода был отключён. Перед аппаратной задачей сначала проверить доступность порта и не считать программную симуляцию полной аппаратной проверкой.
  • При работе с COM не возвращать активный polling ввода: плата сама присылает INPUT.
  • При работе с Addressables не заставлять старт раунда ждать всё окно соседей.
  • При работе с дискретным вводом не использовать чтение полной оси там, где нужна только .x или .y, если рядом есть второй потребитель ввода.
  • Любые новые DOTween-анимации запускать явно.
  • Не менять Assets/StreamingAssets/ComInputConfig.json без фактической проверки сигналов платы.
  • Перед следующим изменением повторно проверить git status: сам файл дампа делает рабочее дерево изменённым, пока не будет закоммичен или удалён пользователем.

12. Что считать источником истины

При расхождении этого дампа с проектом приоритет такой:

  1. актуальные файлы и сериализованные данные текущего master;
  2. состояние Unity Editor, прочитанное через unityMCP;
  3. AGENTS.md;
  4. свежий контекст из agentmemory;
  5. этот дамп.

Этот файл описывает рабочий контекст, но не заменяет чтение кода и проверку сцены перед изменениями.