Сервер (Game.hpp/cpp):
- coop-режим: AI-противники (волна 8, до 3 одновременно), простое
преследование базы с рандомизацией, база с укрытием из кирпича.
- Комната стартует соло (1 игрок), второй может подключиться позже.
- Fix: хитбокс пули по базе брал радиус танка вместо пули.
- Fix: AI при столкновении со стеной теперь сразу перерешает направление,
а не долбит в одну точку до 3с — без этого база падала за секунды.
Клиент:
- Танк: гусеницы, башня, заметный ствол (было — незаметный нубик).
- Рендер базы (укрытие/флаг), AI-танки — отдельным оттенком зелёного.
- Экран победы/поражения — крупный glitch-текст на весь оверлей вместо
строки текста; кнопки "играть ещё" (без reload) и "в лобби".
- Блок кнопок управления (D-pad + огонь) справа от игрового поля.
- Лобби: coop стартует по кнопке "готов" в одиночку.
nginx: try_files с fallback на .html — чистые URL (/projects, /game)
без расширения, старые /projects.html и т.п. продолжают работать.
Сервер: Game — authoritative-тик 20 Гц через uSockets timer, движение/коллизии
танков и пуль, разрушаемые кирпичные стены, respawn, победа/поражение/ничья,
технический проигрыш при дисконнекте. game.ready запускает матч, когда оба
игрока в pvp-комнате готовы.
Клиент: заведён Quintus.js (MIT, vendored) — Tank/Bullet/Wall спрайты,
рендер по снапшотам game.state, keyboard-инпут (WASD/стрелки/space),
экран результата матча.
Найден и исправлен use-after-free: колбэк onFinished_ синхронно удалял
Game изнутри его же метода — перенесено на uWS::Loop::defer.
.gitea/workflows/deploy.yml: пуш в main -> build+up прямо на runner'е
(docker.sock смонтирован, registry и SSH не нужны).
docker-compose.prod.yml: внешняя сеть caddy_net, container_name cactoz-nginx
для reverse_proxy из Caddy.
gameserver/Dockerfile: зависимости (uSockets/json) вынесены в отдельный
кэшируемый слой — пересборка после правки src/ упала с ~6.5 мин до ~9 сек.