FishVsHunters
Asymmetric Fish vs Hunters mode: play as a fish that eats prey, levels up and evolves via skins and mutations (Primal or Intelligence path), or hunt fish as a human. Round system, per-save persistent progress, full multiplayer support.
| Last updated | 8 hours ago |
| Total downloads | 32 |
| Total rating | 0 |
| Categories | Mods |
| Dependency string | ShchetnikovMods-FishVsHunters-0.8.8 |
| Dependants | 0 other packages depend on this package |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2305README
Fish vs Hunters 0.8.8
0.8.8: совместимость с How to Fish 1.1.3. Точки появления игроков и лодки теперь берутся из нового API SpawnManager; восстановление точки появления текущего острова обновляет ссылки на объекты вместо удалённых полей координат.
Мод должен быть одной версии у хоста и всех участников. После обновления DLL перезапустите игру.
- F6 — сменить роль. Погибший участник активного раунда не может обойти ожидание сменой роли.
- F11 у хоста — переключить режим. Есть также кнопка в меню паузы справа сверху.
- Победы и новый раунд: когда погибает вся команда рыб или охотников, все видят победителя. Через 3 секунды начинается следующий раунд. Команды сохраняются, развитие рыб сбрасывается, здоровье восстанавливается, игроки и лодка возвращаются к точкам появления текущего острова. Это перезапуск раунда мода, а не сброс игрового сохранения, денег или открытых островов.
- Без побед / постоянный респавн: нет объявлений победы и сброса раунда. Погибшие возрождаются примерно через 3 секунды. Рыбы сохраняют форму, уровень, опыт и мутации.
Прогресс рыб, их роль, ожидающие выборы, смерть участников, номер раунда и режим сохраняются
хостом отдельно для каждого названия игрового сохранения. Идентификатор игрока — Steam ID.
Файлы лежат в BepInEx/config/FishVsHunters/saves/*.json, рядом — резервные .bak.
Сохранение происходит каждые 5 секунд, при сохранении игры и штатном выходе. При повторном
входе нужно загрузить то же игровое сохранение у того же хоста. Если прежний остров уже не
загружен, рыба появляется в воде возле текущего острова с сохранением развития.
Улов охотников исключается из автоматического удаления дикой добычи после зацепа удочкой или подбора. Он остаётся защищённым после броска и смерти, а сохранённые игрой тушки получают защиту при загрузке. Продажа, поедание и обычные ограничения сохранения предметов самой игры не меняются. Автоматически удаляются трупы оставшейся ничейной добычи, которую создаёт мод.
Сетевая роль восстанавливается по полным снимкам хоста; старое тело не требуется для смены формы или возврата человека. Числовые характеристики рыб передаёт хост. При выходе очищаются камеры, очереди сообщений и состояние островов; при смене сетевых менеджеров обработчики переподключаются без накопления подписок.
0.8.1: убрана мгновенная и неслышимая потеря роли рыбы при кратковременном сетевом сбое.
Раньше NetworkConnection.IsActive, моргнувший false на один тик (лаг, переход между
сценами) без реального дисконнекта, тут же и без единой строки в лог снимал роль и возвращал
камеру игроку-человеку. Теперь перед снятием роли даётся 10 секунд на восстановление
соединения (как и для выгрузки острова), а само снятие роли по этой причине пишется в лог.
0.8.2: нашёл вероятную причину случайной потери камеры у друга. В логе хоста прошлая сессия показала 9 подряд циклов "leave"+"become-fish" от его подключения — это не тихий баг движка, а реальные сетевые запросы, которые шлёт F6. Но у мода были ЗАНЯТЫ ВСЕ клавиши F1-F12 под дебаг-хоткеи, включённые по умолчанию для КАЖДОГО игрока, а не только у хоста: F5 мгновенно и необратимо выбирает эволюционный путь INTELLIGENCE, F7/F9/F10 мгновенно повышают уровень/форму, F4 мгновенно выбирает PRIMAL — всё это на ходу пересоздаёт тело и камеру рыбы. Один случайный тычок соседней клавишей рядом с F6 во время боя выглядит как необъяснимая потеря камеры. Плюс F11 у DebugHealKey совпадал с хостовым ToggleRestartKey — оба срабатывали одним нажатием. Дебаг-хоткеи теперь выключены по умолчанию (можно включить в конфиге для тестов), клавиша лечения переехала на F2.
0.8.3: нашёл в логе хоста прямое доказательство реальной сетевой гонки. Ровно в момент захода друга сервер дважды залогировал предупреждение FishNet "One or more broadcast did not send to a client because they were not authenticated" — это не наш баг напрямую, а поведение самой сетевой библиотеки: если разослать сообщение в момент, когда подключение ещё не считается аутентифицированным, оно молча пропадает для этого клиента без единой ошибки и без повтора. Наш код рассылал ростер (кто сейчас рыба) и приватное состояние рыбы именно так — один раз, без подтверждения доставки. Если это совпадает по времени с тем, что игрок только что стал рыбой, его собственный клиент мог никогда не узнать об этом: сервер считает его рыбой, а на его экране роль и камера не переключаются, и никакого следа в логах при этом не остаётся. Теперь при событии FishNet «подключение прошло аутентификацию» сервер сам обязательно досылает этому клиенту его актуальный ростер и приватное состояние рыбы — окно гонки закрыто независимо от того, что могло потеряться в момент подключения.
0.8.4: уточнил симптом — друг видит рыбу, но не может кусать и двигаться. Это конкретно означает, что тело и камера переключились нормально, а вот отдельное сетевое сообщение с характеристиками рыбы (host private state) либо не дошло, либо было отброшено раньше, чем успело примениться — движение и укус у нас программно заблокированы до его получения. При частых переключениях F6 туда-обратно это сообщение адресовано телу с конкретным ID, и более новый ростер (например, от следующего переключения) мог отбросить ещё не применённое сообщение как устаревшее. Логов для проверки этой гипотезы вживую пока не было — добавил точечное диагностическое логирование: когда тело рыбы подключается локально, когда оно реально получает host-состояние и разблокирует управление (с задержкой в секундах), сторожа "пять секунд без состояния" и отдельное предупреждение, если новый ростер отбросил ещё не применённое собственное состояние. В следующий раз в логе будет видно, где именно потерялось.
0.8.5: подтверждено, что это не про повторные нажатия F6 - один чистый заход и одно нажатие уже давали полную потерю управления (не двигается, не кусает). Раз мод шлёт полное состояние рыбы заново каждую секунду (это уже было и раньше), простая потеря одного сетевого сообщения не объясняет зависание на десятки секунд - значит дело не в потерянном пакете, а в том, что подключение локальных компонентов рыбы (тело+камера+управление) у этого клиента вообще ни разу не срабатывает. Он завязан на два независимых условия: сервер прислал ростер "ты рыба", и NetworkObject.IsOwner для этого тела стало true именно на клиенте владельца. Если второе не успевает - человек остаётся скрытым (невидимым, замороженным), а тело рыбы, камеру и управление клиент так и не получает, и это нигде не логируется. Добавил предупреждение, которое прямо покажет, если ростер говорит "ты владеешь этим телом", а IsOwner на клиенте всё ещё false - это и укажет на точную причину при следующем повторении.
0.8.6: НАШЁЛ настоящую причину, доказано декомпиляцией самой игры, а не логами. Дело было не
в сети и не в F6. У игры есть свой ванильный механизм: когда игрок кого-то бьёт/атакует,
на клиенте АТАКУЮЩЕГО происходит RigidbodySync.StartSimulateLocal(), который забирает право
"симулировать" физику этого существа себе. Для дикой рыбы это безобидно, но у нас рыбой
управляет её собственный игрок именно через этот же флаг (IsSimulatedLocal) - без него бит и
движение у нас программно заблокированы. То есть один-единственный удар охотника по игроку-рыбе
буквально забирает право управления у рыбы и отдаёт его атакующему - без ошибок, без дисконнекта,
камера при этом продолжает работать (она на этот флаг не завязана), а движение и укус пропадают.
Именно поэтому баг воспроизводился каждый раз, когда кто-то реально бил/стрелял в рыбу.
Теперь хост каждый такт откатывает право симуляции обратно владельцу рыбы, если игру
кто-то у него забрал - одного удара больше не хватит, чтобы выключить игроку управление.
Проверено: Release-сборка без предупреждений, 70 автономных проверок логики, сериализации,
сохранений и совместимости патчей с установленной DLL. Живой мультиплеер версии 0.8.6
ещё не проверен. Сценарии ручной проверки записаны в research/FINDINGS.md.
0.8.7: баланс укуса и прокачки по фидбеку. Дальность укуса (ComputeBiteRadius в
FishController) считается как (BiteRange скина + Bite.Radius) * Scale, а плоская
составляющая Bite.Radius не уменьшалась для мелкой рыбы — на 10 уровне радиус укуса уже
доходил до ~5.8м, а к 18-27 уровню формула упиралась в абсолютный потолок 8м (тот самый фикс
от бага с укусом на 194м у левиафана — сам потолок не трогали). Bite.Radius снижен с 4 до 2:
на 10 уровне радиус падает примерно до 4м, на 1 уровне — до ~2.2м. Отдельно XpCurveLinear
поднят с 60 до 90 — прокачка на низких уровнях (примерно до 10-20) ощутимо замедлена,
на позднюю игру влияет слабо (там доминирует степенной член кривой).