ITSP — прототип сюжетного кооператива, версия 0.10.0

Новое в 0.10.0
---------------
Сюжетные флаги передаются во время игры. Завершение лаборатории у хоста
больше не оставляет гостя с остановленным скриптом наружной области.
Передаются входы в сюжетные триггеры, сканирование, переключение, захват,
подбор инструмента и окончание церемонии получения. Гость запускает
собственные штатные скрипты сцены, включая обвал и удар по турели.
События привязаны к постоянным идентификаторам объектов уровня;
при запоздавшей загрузке объекта/ожидающего скрипта событие сохраняется.
Повторная доставка не повторяет сцену. Вход в область бластера собирает
напарника по действующему правилу родной планеты, независимо от расстояния.

Выстрел по L0_NPC_GunGate запускает у напарника родное втягивание
щупальца, его звук, отключение столкновений и последующее отрастание.
Передаются координаты и поворот переносимых клешнёй объектов, которые
не обслуживаются штатной сетевой физикой. Инструмент получает только
подобравший: второй игрок продолжает сцену без выдачи дубликата и без
требования пройти обучение назначению отсутствующего бластера.

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

Это частичная синхронизация взаимодействий. Полная сетевая симуляция
всех врагов, боссов, произвольных физических головоломок не реализована.
Установить 0.10.0 и полностью перезапустить игру нужно НА ОБОИХ ПК.
Сохранения сохраняются. Перед передачей проверяются размеры строк,
включая прежний предел нативного сетевого буфера в 511 байт.

Новое в 0.9.2
--------------
Устранена запись за границей памяти карты при запуске новой сетевой
кампании и восстановлении разведки у гостя. Дамп хоста 0.9.1 показал
падение внутри распределителя памяти. Проверка кода движка выявила:
для карты 75x75 выделяются строки 0–74, но setMapGrid ошибочно принимает
также строку 75. Мод обходил строки 1–75 и обнулял память после массива.
Теперь очистка охватывает только 0–74; снимок и обмен разведкой также
не обращаются к несуществующим клеткам. Позиции битов сети сохранены.

Проверки учитывают реальные границы выделенного массива: старая 0.9.1
нарушает их, исправленная версия проходит. Проверены очистка старой
локальной разведки, передача крайних допустимых клеток и отсечение
неверных клеток в сообщениях. Сетевой запуск на двух ПК ещё нужно
подтвердить. Обновить и полностью перезапустить ITSP нужно НА ОБОИХ ПК.
Существующие сохранения при обновлении не сбрасываются.

Новое в 0.9.1
--------------
Исправлен вылет при передаче сейва хоста и ожидание на чёрном экране
у оставшегося клиента. В 0.9.0 часть сетевого сообщения с заголовком
занимала около 798 байт, а штатный обработчик строк выделяет 512 байт.
Дамп показал аварийное завершение в memcpy_s при копировании этой строки.
Теперь полезная часть — 384 байта, а вся строка вместе с заголовком
проверяется до отправки: не больше 511 байт плюс завершающий ноль.
Большой снимок передаётся несколькими частями с подтверждением доставки.

Тестовый сетевой адаптер теперь учитывает реальный предел движка:
на 0.9.0 проверки воспроизводят переполнение, на 0.9.1 проходят.
Дополнительно проверена передача большого снимка с потерями и повторами.
Изменён сетевой маркер: новый гость не запрашивает опасные длинные строки
у старого хоста. Обновить до 0.9.1 и полностью перезапустить ITSP нужно
НА ОБОИХ ПК. Сейвы при обновлении не сбрасываются.

Новое в 0.9.0
--------------
Сетевое прохождение хранится у хоста в ITSPCoop.Host.v1.save.
При первом запуске это отдельная новая кампания. Старый одиночный
тестовый ITSPCoop.v1.save остаётся для Local Game и не импортируется.
Гость вообще не читает и не перезаписывает свой тестовый сейв в сети:
он получает мир, разведку, общую статистику и точку появления от хоста.
Первый вход гостя — со сканером; последующие входы восстанавливают его
инвентарь из сейва хоста по сетевому идентификатору, независимо от слота.
Во время игры инвентарь гостя передаётся хосту, включая личный бластер.

С карты удалено переключение на статистику по R/LB. Колёсико и LB/RB
снова используют штатное масштабирование. Статистика остаётся в паузе;
выбор корпуса через Tab -> F / Y сохранён.

При сюжетном телепорте, переходе в соседнюю область, входе к боссу
и начале ледяного побега напарник переносится к инициатору, если
расстояние не больше 25 игровых единиц. Далёкий игрок остаётся на месте.
На РОДНОЙ ПЛАНЕТЕ (L8, вступление) расстояние не проверяется:
переносится любой напарник. Его активная катсцена сначала завершается.
Повторные сообщения и ответные переносы подавляются. Простая фоновая
подгрузка геометрии и возрождение не собирают игроков вместе.

Сюжетные ВИДЕОРОЛИКИ запускаются на обоих ПК, независимо от расстояния:
вступление, звезда, перелёт, финал и титры. Запрос отправляется до
штатной паузы движка. Одинаковые запросы двух сюжетных скриптов не
проигрывают видео дважды. Пропуск ролика остаётся локальным.
Точная синхронизация анимационных сцен на движке и ИИ боссов пока
не реализована; перенос в область запускает её местные сюжетные скрипты.

Установить текущую 0.10.0 и полностью перезапустить игру нужно НА ОБОИХ ПК.
Старые версии не понимают передачу сейва и будут ждать при загрузке.
Новые переносы и ролики проверены на двух изолированных Lua-клиентах;
проверка этой версии через Steam с двумя компьютерами ещё необходима.

Новое в 0.8.1
--------------
Исправлен порядок сетевого запуска: карта, броня и статистика начинают
передаваться только после готовности всех участников. Раньше хост мог
отправить сообщение гостю до появления его обработчика. Обработчики
теперь также регистрируются до ожидания сигнала хоста; ранние сообщения
безопасно пропускаются, затем данные восстанавливаются из повторных
снимков. После готовности отправляется полная разведка, в том числе
загруженная из сейва. Журнал показывает роль клиента и получение
сигнала хоста. Установить 0.8.1 и полностью перезапустить ITSP нужно
НА ОБОИХ ПК. Одного обновления гостя недостаточно.
Три проверки порядка запуска воспроизводят ошибку в 0.8.0 и проходят
с исправлением. Пользователь подтвердил запуск второго клиента через Steam;
обнаруженное затем чтение чужого локального сейва исправляется в 0.9.0.

Новое в 0.8.0
--------------
У корпусов 2–4 восстановлены блики и освещение по нормалям поверхности.
Собственный материал сохраняет нейтральный тёмный корпус, белые фонари
и отверстия. Цвет лобби влияет на свечение позади корабля.
Исправлена упаковка материала: новый шейдер регистрируется из отдельного
ресурсного архива. После исправления пользователь подтвердил загрузку
прежнего сейва без вылета, блики на корпусах 3–4 и белые фонари.

При игре на разных компьютерах камера учитывает только локального
игрока: удалённый корабль не сдвигает центр, не отдаляет камеру и не
ограничивает движение общими границами экрана. Каждый компьютер
загружает участки карты вокруг своего корабля. Сюжетные цели камеры,
катсцены, переходы и возврат после возрождения сохраняются.
Это отдельная камера на каждом ПК, не разделение одного экрана.
Синхронизация состояния сюжетного мира по-прежнему не завершена;
прохождение разных концов планеты на двух ПК ещё требует сетевой проверки.

Новое в 0.7.3
--------------
Детали текстур корпусов 2–4 стали ярче. Белые фонари и нижние отверстия
сохраняют исходную яркость независимо от тёмной окраски голубых панелей.
Свечение позади корабля по-прежнему соответствует цвету лобби.
Для дополнительных моделей сохранён штатный непрозрачный материал,
чтобы поверхности корпуса правильно перекрывали друг друга при наклоне.
Пользователь подтвердил белые фонари и нижние отверстия. У моделей
с первым улучшением брони гладкие части днища корпуса 3 и диска корпуса 4
привязаны к чёрным участкам исходной текстуры без рисунка. Нейтральный
материал пока не воспроизводит блики штатного материала Shadow Hunters,
поэтому эти поверхности выглядят плоскими; яркость текстуры это не меняет.

Новое в 0.7.2
--------------
Яркость текстур дополнительных корпусов увеличена на 50% относительно
0.7.1, чтобы линии и панели лучше читались. Чёрные участки остаются
чёрными; свечение позади корабля использует цвет лобби.

Новое в 0.7.1
--------------
Исправлено восстановление личных улучшений бластера. Старые версии
могли сохранить флаг подбора, но потерять уровень, хранившийся только
на корабле. При загрузке старого сейва с единственным владельцем бластера
такие находки восстанавливаются ему. В новых сейвах идентификаторы
улучшений записываются отдельно для каждого владельца и сохраняются
при возрождении. Общая статистика не выдаёт улучшения второму игроку.
Пороги прежние: 1/4/9 находок; штатные очереди — 2/3/5 выстрелов.

Дополнительные корпуса 2–4 сохраняют линии и панели исходной текстуры.
Исправлено преобразование цвета, которое брало только красный канал
и теряло голубые детали. Теперь учитываются все три канала с тёмной
нейтральной окраской. Прозрачность и геометрия модели сохраняются.
Первый корпус использует настоящую сюжетную модель; свечение позади
НЛО сохраняет выбранный в лобби цвет. В 0.7.1 пользователь подтвердил
восстановление очереди бластера и появление деталей текстур;
яркость деталей дополнительно увеличена в 0.7.2.

Новое в 0.7.0
--------------
В 0.7.0 сюжетная статистика была добавлена в паузу и личную карту.
Начиная с 0.9.0 она доступна только в паузе. Масштаб карты меняется
колёсиком, LB/RB или правым стиком без переключения интерфейса.
Показаны родные значки и шкалы улучшений, артефакты 0/18,
концепт-арты 0/24, процент разведки и процент прохождения.
Счётчики общие: каждый предмет учитывается по уникальному имени,
инструменты обоих игроков входят в общий процент. Улучшения бластера
видны в общей статистике, но усиливают только его владельца.
Формула прохождения повторяет сюжетку: артефакты 10%, сюжет 50%,
инструменты 25%, улучшения 15%. Разведка и концепт-арты показаны отдельно.
Полученные сведения сохраняются в кооп-сейве, в том числе после
отключения напарника. Обмен статистикой не синхронизирует боссов и мир.
Артефакты и концепт-арты не засчитываются повторно; открытые материалы
сохраняются внутри кооп-сейва без записи в обычные настройки.

Первый корпус использует настоящую сюжетную модель. Остальные три
сохраняют форму Shadow Hunters, но получают тёмную окраску
вместо базовой голубой текстуры. Цвет лобби задаёт только
свечение позади НЛО. Во вступлении остаётся родной сюжетный облик.
Старый кооп-сейв и выбор корпуса сохраняются при обновлении.

Новое в 0.6.0
--------------
На личной сюжетной карте видны оба корабля. Свой маркер белый, напарник
выделен цветом. Маркеры двигаются и масштабируются вместе с картой,
скрываются при смерти/отключении и возвращаются после появления корабля.
Клиенты обмениваются разведанными клетками: области объединяются,
уже открытая карта не стирается. Периодическая повторная передача
восстанавливает потерянные сообщения. Полученная разведка попадает
в кооп-сейв при следующем сохранении контрольной точки.

Улучшения БРОНИ общие. Каждая сюжетная находка учитывается один раз
по постоянному идентификатору. Родные пороги: 1/4/9 находок для уровней
1/2/3. Более сильная броня старого сейва не понижается. После смерти
корабль сохраняет улучшение.
Улучшения БЛАСТЕРА личные: их может подобрать локальный корабль,
которому доступен бластер. Второму игроку они не передаются.
Сам бластер и остальные инструменты общей бронёй не выдаются.

При двух участниках теперь по ПЯТЬ слотов. Второму игроку добавлен
сканер, закреплённый в пятом секторе; остальные четыре заполняются
подобранными инструментами. У первого сканер остаётся сюжетным
инструментом в его пяти слотах. Случайной выдачи сканера нет.
В одиночной игре доступны девять слотов. Номера игроков определяются
сетевыми слотами, а не номером контроллера на отдельном компьютере.
Старый сейв не сбрасывается. Лишние предметы прежнего одиночного сейва
сохраняются, но в коопе доступны только предметы в пределах пяти слотов.
Полное колесо не поглощает новый инструмент.

Выбор четырёх штатных корпусов Shadow Hunters: откройте карту по Tab
или Back/View и нажимайте F на клавиатуре либо Y на геймпаде.
Вверху карты показан номер HULL 1/4 ... 4/4. Закройте карту, чтобы
осмотреть корабль. Корпус меняется только у вызвавшего карту игрока;
выбор передаётся через штатное поле сетевого игрока и сохраняется.
Во время сцен домашней планеты используется предусмотренный сюжетом
корпус; выбранная модель применяется после сюжетной смены облика.
Это выбор через личную карту, а не интерфейс стартового лобби.

Tab / Back / View открывает и закрывает карту только на компьютере
вызвавшего её игрока. Закрыть её также можно Escape/B/Start.
Мир не ставится на паузу: корабль остаётся уязвимым. Открытие карты
не отправляется по сети. Карта закрывается при смерти или катсцене.
Для двух игроков перед одним монитором отдельных экранов пока нет.

Проверки и ограничения
---------------------
Пройдены 74 автоматические проверки, включая установку и удаление.
Родной скрипт камеры проверен в двух независимых Lua-клиентах:
удалённый корабль не двигает камеру, не меняет масштаб и не тормозит
свой корабль на границе экрана; сюжетные цели камеры сохраняются.
Проверки Lua 5.1 выполняют код мода и установленные
родные скрипты карты, колеса, корпусов и предметов. Два изолированных
Lua-клиента проверяют обмен разведкой, бронёй и статистикой с повторениями
и перестановкой сообщений; для разведки проверены потери пакетов.
Проверены сохранение общего прогресса, достижимость 100% в модели данных,
родной экран статистики и обработчики подбора. Эти проверки не заменяют запуск двух копий
игры через Steam. В 0.8.1 проверен вход гостя; возможности 0.9.0 ещё
требуют повторной сетевой проверки на двух компьютерах.

В прошлых версиях пользователь проверил сюжетную загрузку, сканер,
освобождение корабля, катсцены, получение клешни и сдвигание камня,
сохранение контрольной точки, возрождение, открытие карты и разведку.
В 0.6.0 загружен прежний сейв; пользователь подтвердил смену корпуса
и выбрал модель. Обычные сюжетные сейвы и настройки не изменились.
В 0.7.0 на прежнем сейве визуально проверены тёмный корпус и родная
статистика в меню паузы: шкалы, счётчики и проценты отображаются.
Концепт-арты, открытые в прежнем профиле, игра учитывает как в сюжетке.
В 0.7.1 в изолированном Lua-процессе проверена копия текущего кооп-сейва:
восстановлены первое улучшение и очередь из двух выстрелов штатного
бластера. Оригинал сейва при этой проверке не редактировался.
Новые сетевые возможности требуют проверки в игре с напарником.

Это исследовательский прототип, а не готовая совместная кампания.
Нет общей синхронизации врагов, физики предметов, головоломок, боссов,
анимационных сцен и большинства сюжетных флагов. Уникальность подбора инструментов
между двумя копиями мира пока НЕ обеспечена. Броня и разведка имеют
собственный обмен данными; это не синхронизация всего сюжетного мира.
Сетевой сейв хранится у хоста; при входе передаётся снимок мира.
Изменения большинства сюжетных флагов во время раздельной игры
по-прежнему не передаются непрерывно и могут расходиться.
Совместное прохождение всей кампании пока не гарантируется.

Установка на каждом компьютере
-----------------------------
1. Полностью закройте ITSP.
2. Распакуйте весь архив в отдельную папку. Не запускайте из ZIP.
3. Запустите Install.cmd. Python и дополнительные программы не нужны.
   Установщик найдёт игру в Steam либо запросит папку с fcengine.exe.
   Неизвестные модификации он не перезаписывает.
4. Status.cmd проверяет состояние установки.
5. Для нового начала LOCAL GAME при закрытой игре запустите NewGame.cmd.
   Прежний одиночный тестовый сейв переименуется в резервную копию .bak.
   Отдельный сетевой сейв хоста эта команда не затрагивает.
   При обычном обновлении NewGame.cmd запускать НЕ нужно.

Мод запускается через Lantern Run -> Local Game или закрытое сетевое
лобби Lantern Run. При новом начале показываются домашняя планета,
Mothership, вступительный ролик и обучение. При продолжении загружается
последняя сохранённая точка. Публичные матчи не переключаются в сюжетку.

Проверка с напарником
--------------------
1. Установите одинаковую версию мода на оба компьютера.
2. Хозяин создаёт ЗАКРЫТОЕ лобби Lantern Run. Друг входит до старта.
   Проверки совместимости мода в лобби пока нет.
3. Начните матч и сравните положение обоих кораблей.
4. Откройте карту только на одном ПК: у другого она открываться не должна.
   Разведайте разные соседние области, сравните карты, дождитесь обмена.
5. Проверьте пять слотов у каждого и сканер в пятом секторе второго.
6. Выберите разные корпуса через карту; сравните их на обоих ПК.
7. Подберите броню, проверьте улучшение у обоих. Предмет улучшения
   бластера должен оставаться для владельца бластера и усиливать его.
8. Активируйте контрольную точку, перезапустите игру и проверьте
   разведку, броню, инструменты и корпус. Затем проверьте возрождение.
При ошибках сохраните itsp-coop.log из папки игры на обоих компьютерах.

Сохранения и удаление
--------------------
Local Game пишет ITSPCoop.v1.save, а сетевой хост — ITSPCoop.Host.v1.save в
%LOCALAPPDATA%\Insanely Twisted Shadow Planet.
Обычные сюжетные сохранения и настройки после входа в тест защищены
от записи до ПОЛНОГО перезапуска игры. Перед обычной одиночной игрой
перезапустите ITSP. Повреждённый кооп-сейв автоматически не затирается.

Restore.cmd при закрытой игре восстанавливает исходный Lua-файл
и удаляет собственные модули, шейдеры и их ресурсный архив после проверки
контрольных сумм.
Сохранения не откатываются; кооп-сейв остаётся. Установщик создаёт
копии сохранений в itsp-coop-backup/saves внутри папки игры.
Он заменяет data/levels/MP_LanternRun/postload.MP_LanternRun.lua
и добавляет там собственные itsp_session.lua, itsp_events.lua и itsp_world.lua.
Дополнительно устанавливает собственный itsp_coop_hull_v1.pso в
data/shaders/Win32/ps_2_0 и ps_3_0 и архив itsp_coop_hull_v1.7z
в data/shaders/Win32. Движок регистрирует шейдеры из этого отдельного
архива. Штатные шейдеры и win32.7z не заменяются.
EXE и основной архив игры не изменяются. Исходный postload сохранён
в itsp-coop-backup/postload.MP_LanternRun.lua.original.

Поддерживаемая Steam-версия, SHA-256:
fcengine.exe:
bb1504944d0bd8da08d416f719f2dbe8ab87293bd09e7f68e845d0b0f4826fc4
data/script/scripts.7z:
e6b2267691fff3f2bd81e9b68b531a5ae27d4c1fab878cece1f25d6cdb8d85de

Ручное указание папки в PowerShell:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\Manage-ITSPCoop.ps1 -Action Install -GamePath "D:\SteamLibrary\steamapps\common\Insanely Twisted Shadow Planet"

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