Skip to content

Зона 65 «Сказка для охотника»: гнездо (6505) недетерминированно кладётся не в ту комнату — квест «не работает» #3371

@kvirund

Description

@kvirund

Симптом

В квесте «Сказка для охотника» (зона 65) гнездо с птенцами (obj 6505) на ресете зоны кладётся не всегда в ту комнату. Квест ожидает гнездо в дереве в комнате 6510 («На краю оврага»), но фактически оно попадает в одно из четырёх одинаковых сухих деревьев (obj 6503): комнаты 6510 / 6530 / 6532 / 6534.

Когда гнездо легло не в 6510, игрок приходит на правильную клетку, видит сухое дерево, но осмотреть дерево → «Внутри ничего нет», взять гнездо дерево → «не видите гнезд». Квест «не работает». Раз на раз — то работает, то нет.

Воспроизведение

zreset 65 несколько раз подряд, и после каждого где гнездо (иммом):

zreset комната, куда легло гнездо 6505
1 6532 «В гуще леса» ← НЕ та
2 6510 «На краю оврага» ← верно
3 6510 «На краю оврага» ← верно

Выдержка из лога игрока (Ивета), попавшего на «плохой» ресет, — она на правильной клетке 6510:

На краю оврага [6510]
...
Высокое сухое дерево, кажется, готово вот-вот упасть.
рубить дерево
Вы начали усердно рубить сухое дерево коротким топориком.
Откуда ни возьмись, выскочила птичка-невеличка и стала вокруг Вас летать.
вз гнезд дер
Вы не видите 'гнезд' в сухом дереве.
ос дер
Давно погибшее, но еще не упавшее дерево ... крупное дупло.
Состояние: идеально. сухое дерево(на земле)
 Внутри ничего нет.

Доказательство из логов движка

[Extract obj] при ресете печатает комнату, где лежал старый экземпляр гнезда. Видно, что гнездо реально жило то в 6510, то в 6532:

2026-05-30 19:31:11  [Extract obj] Start for: хрупкое гнездо с птенцами vnum == 6505 room = 6532
2026-05-30 19:44:48  [Extract obj] Start for: хрупкое гнездо с птенцами vnum == 6505 room = 6510
2026-05-31 00:51:18  [Extract obj] Start for: хрупкое гнездо с птенцами vnum == 6505 room = 6532

То есть игрок смотрел в правильной комнате — гнездо просто оказалось в другом дереве.

Причина (код)

В zon/65.zon:

P 0 6505 0 6503 -1     (хрупкое гнездо с птенцами)
        ^ arg2 = 0  → искать контейнер по всему миру

При arg2 == 0 движок (ResetZoneEssential, case 'P', src/engine/db/db.cpp) ищет контейнер глобально: SearchObjByRnum(arg3)WorldObjects::find_first_by_rnum (src/engine/core/handler.cpp, src/engine/db/world_objects.cpp). А find_first_by_rnum возвращает первый элемент std::unordered_set (m_rnum_to_object_ptr). Порядок в этом сете определяется хешами указателей (адресами в куче), то есть какое из четырёх деревьев 6503 окажется «первым» — не определено.

Почему проявилось после перехода на YAML

Данные зоны 65 (zon/obj/trg/wld) не менялись (сверял world.20260516world.20260530 — идентичны). Баг латентный, был всегда. На legacy-загрузке раскладка кучи стабильно ставила дерево 6510 «первым» (квест казался рабочим). YAML-бутстрап (другой парс-путь, тред-пул, другой порядок аллокаций прототипов) сдвинул порядок в unordered_set — и «плохие» исходы стали частыми. Отсюда ощущение «вдруг сломалось после перехода на Ямл».

Как починить — данные (быстро, от формата не зависит)

Привязать раскладку гнезда к комнате 6510 (тогда движок идёт по ветке GetObjByRnumInContent(arg3, world[6510]->contents)):

- P 0 6505 0    6503 -1
+ P 0 6505 6510 6503 -1

Дерево 6510 грузится строкой выше (O 0 6503 -1 6510), контейнер на месте.

YAML (zones/65/zone.yaml):

- - PUT 0 6505 0 6503 -1
+ - PUT 0 6505 6510 6503 -1

OLC (zedit), на работающем сервере:

  1. zedit 65
  2. F — показать все команды
  3. найти строку поместить 6505 [...] в 6503 [...] (в комнате 0 [везде]), запомнить её номер
  4. E, ввести этот номер
  5. промпты: предмет → 6505, Комната → 6510, контейнер → 6503, вероятность → -1
  6. X, сохранить зону

Как починить — движок (рекомендуется)

Сделать выбор контейнера в P при arg2 == 0 детерминированным: искать по списку мира / в порядке создания, а не брать «первый из unordered_set». Иначе любой квест с несколькими одинаковыми контейнерами-целями так же будет лотереей.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions