SYNAPSE
EN
Гайды

Как отлаживать веб-настолку с ИИ: пошаговый гайд

Практический гайд по вайб-дебагу браузерной карточной игры: от воспроизведения бага до проверки синхронизации. Без магии, только проверяемые шаги.

Как отлаживать веб-настолку с ИИ: пошаговый гайд

Вайб-дебаг — это отладка по внешним симптомам, когда код сгенерирован моделью и не до конца понятен. Ниже — набор действий, которые помогают находить причины багов в браузерной настолке. Гайд не про конкретный движок, а про метод.

Что понадобится

  • Браузер с DevTools (Chrome, Firefox или Edge).
  • Доступ к репозиторию и возможность запускать проект локально.
  • Консоль с логами сервера и клиента.
  • Два окна браузера или два устройства для проверки синхронизации.
  • Список известных багов с шагами воспроизведения.
  • Терпение: один баг — один эксперимент.

Шаг 1. Зафиксируйте баг в виде сценария

Открывайте DevTools (F12) и записывайте каждое действие. Пример сценария:

  1. Открыть игру в двух окнах.
  2. В окне A выбрать карту в руке.
  3. Перетащить её на стол.
  4. Отпустить.
  5. Проверить, появилась ли карта в окне B.

Если баг плавающий, добавьте в код временные логи. Например, в обработчик броска карты:

function onCardDrop(cardId, x, y) {
  console.log('[drop]', { cardId, x, y, t: Date.now() });
  sendMove({ type: 'playCard', cardId, x, y });
}

Логи должны быть с метками времени. Без них вы не отличите задержку сети от ошибки рендера.

Шаг 2. Отделите визуальную часть от сетевой

Проблема может быть в отрисовке, в передаче данных или в правилах. Проверяйте по очереди.

Сначала проверьте, приходит ли событие на сервер. В консоли сервера добавьте лог входящих сообщений:

ws.on('message', (raw) => {
  const msg = JSON.parse(raw);
  console.log('[ws in]', msg.type, msg);
});

Если сообщение приходит, но карта не появляется у соперника — ищите ошибку в рассылке или в клиентском обработчике. Если сообщение не приходит — смотрите клиентский код отправки.

Шаг 2. Отделите визуальную часть от сетевой

Шаг 3. Проверьте состояние доски до и после хода

Сделайте снимок состояния (state) до и после действия. В клиенте можно вывести его в консоль:

function dumpState(label) {
  console.log(label, JSON.stringify(gameState, null, 2));
}

Вызывайте dumpState('before') перед ходом и dumpState('after') после. Сравнивайте поля: позиция карты, чей ход, счёт. Если состояние меняется не там, где ожидалось, — баг в логике правил.

Шаг 4. Воспроизведите ход вручную через консоль

Если баг не повторяется мышью, отправьте событие напрямую. Это помогает отделить UI от логики. Пример для WebSocket-соединения:

const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => {
  ws.send(JSON.stringify({ type: 'playCard', cardId: 'card-1', x: 100, y: 200 }));
};

Адрес и формат сообщения возьмите из кода клиента. Если при ручной отправке всё работает, проблема в обработчике мыши или в вычислении координат.

Шаг 4. Воспроизведите ход вручную через консоль

Шаг 5. Проверьте синхронизацию двух клиентов

Откройте два окна. В каждом выполните в консоли:

console.log('client id', window.clientId);

Если clientId не определён, добавьте его при подключении. Затем сравните состояние после одного и того же хода. Рассинхрон часто вызван тем, что один клиент применяет ход локально, а второй ждёт сервер. Проверьте, не дублируется ли применение.

Шаг 6. Изолируйте правила игры в отдельную функцию

Правила должны быть чистыми функциями: на входе состояние и ход, на выходе новое состояние. Пример:

function applyMove(state, move) {
  if (move.type !== 'playCard') return state;
  const next = structuredClone(state);
  next.table.push({ cardId: move.cardId, x: move.x, y: move.y });
  next.turn = state.turn === 'A' ? 'B' : 'A';
  return next;
}

Такую функцию легко тестировать без браузера. Напишите несколько вызовов в консоли и проверьте результат. Если правила работают в изоляции, но ломаются в игре — ищите, где состояние мутируется вне функции.

Шаг 7. Смотрите на швы между движениями

В статье автор замечает, что видит не карту, а швы между движениями. Это признак того, что анимация и логика живут отдельно. Проверьте, не запускается ли анимация до подтверждения сервера. Если да, возможны рывки при откате. Решение — оптимистичное обновление с откатом по ответу сервера. Но сначала убедитесь, что ответ приходит.

Типичные ошибки и как их узнать

  • Логи без меток времени. Вы не отличите задержку сети от медленного рендера. Добавьте Date.now() в каждый лог.
  • Проверка только на одном клиенте. Синхронизация не проверена. Всегда открывайте два окна.
  • Мутация состояния в обработчике. Симптом: после отмены хода состояние не возвращается. Ищите прямые присваивания вместо создания копии.
  • Смешение UI и правил. Симптом: баг воспроизводится только при определённом размере окна. Вынесите правила в отдельные функции.
  • Игнорирование порядка сообщений. Симптом: карта появляется у одного игрока раньше, чем у другого. Проверьте, не отправляются ли события параллельно без очереди.

Если данных о конкретной причине нет, не гадайте. Сначала соберите логи, потом меняйте код. Один эксперимент — одна гипотеза.

↗ Первоисточник: Habr