Что из себя представляет парсер игры «Остров Клайда»?

Понемногу собираю и анализирую отзывы, пожелания и критику по «Острову Клайда». В этой заметке хотелось немного коснуться темы используемого в этой игре парсера.

Когда люди говорят о парсере, то на самом деле (иногда мне кажется, что неосознанно) охватывают целый комплекс функций и модулей движка, ведь между «игрок написал» и «игра отреагировала» работают несколько уровней обработки данных.

Перечень уровней обработки, разумеется, упрощён — я оставил лишь основные, потому как, например, уровень уточнений команд игрока в контексте данной заметки не столь важен.

На первом уровне, конечно же, производится «синтаксический разбор» введённой игроком команды. Тут важно правильно разложить команду на составляющие: выделить глагол и отдельные слова, которые полезно расставить по смысловому значению относительно найденного глагола. И этот уровень в «Острове Клайда» есть и работает — было интересно реализовать свои давние идеи.

А вот дальше в правильной парсерной платформе происходит упрощение всех языковых потуг игрока до некоторого ограниченного набора событий, которые могут произойти с игровыми объектами. Неважно, какие нюансы речи использовал игрок — это всё сводится к определённому набору. И тут, увы, речь идёт не только о синонимах. Очень показателен отзыв uux’а: как опытный игрок, автор и переводчик документации к RTADS, он хорошо знает внутреннюю кухню серьёзных парсерных движков, поэтому сразу идёт напрямик:

Потом я пытался побороть пистолет. Сразу пришедшее в голову «Открыть пистолет» не сработало … В итоге подошло совершенно нестандартное по меркам «классических» парсерных платформ «достать порох из пистолета».

На самом деле можно было ещё «разобрать пистолет» и «высыпать порох из пистолета», ну да ладно.

Так вот, этого уровня в парсере «Острова Клайда» нет. Вообще нет. То есть никакого упрощения, группировки, повышения уровня абстракции команд в парсере этой игры нет. Есть синонимы отдельных слов, которые схлопываются в одно, но группировки различных по смыслу слов в одно событие нет.

Я сознательно сразу перескочил на обеспечение работы третьего уровня: привязка реакций игры к словам и объектам. Но поскольку у меня не было событий и их параметров (получаемых на втором уровне), мне пришлось привязывать глаголы и слова к объектам напрямую. То есть, чтобы прописать реакцию на попытку осмотреться на острове, мне нужно было самому учитывать все варианты:

ПодПальмой.Действие([
    {А:'вокруг'},
    {глагол: 'осмотреть', А: [null, 'вокруг']},
    {глагол: [null, 'осмотреть'], Б: {предлоги:'по', слова:'сторонам'}},
    //----------
    ], function() {
        ПодПальмой.ВывестиОписание();
    }
);

В этом случае срабатывают варианты команд «вокруг», «осмотреть» (плюс все предусмотренные синонимы этого глагола), «осмотреть вокруг», «по сторонам», «посмотреть по сторонам».

А вот так выглядит запись вызова инвентаря:

ИГРОК.Действие('инвентарь', [
    {А:'инвентарь'},
    {глагол:'осмотреть', А:'инвентарь'},
    //----------
    ], function() {
        ВывестиИнвентарь();
    }
);

Ну и вот почему получение следующей порции длинного текста работает именно как ввод команды, то есть через ввод «далее»:

Вступление.Действие(
    {А: 'далее'},
    //----------
    function() {
        Вступление.Далее()
    }
);

Потому что он описывается как привязанная к тексту команда. Это попросту оказалось быстрее сделать, чем дорабатывать интерфейс на переключение в режим вывода текста с кнопкой «далее» и обратно.

Слишком рутинно? Да. Слишком многое нужно прописывать автору? Конечно. И я это прекрасно осознавал, когда шёл по такому пути (хотя Нафанин и высказывал сомнения). Тем не менее, какая-никакая система. И кроме банальной нехватки времени, мне было интересно собрать низкоуровневую «статистику», выступая именно как автор: как мне захочется описать действия с объектами, какие обороты я захочу/смогу/успею использовать. Что из этого будет востребовано игроками. И в итоге — как мне потом всё сделать проще и удобнее.

выбрать модель для подражания есть из чего, и это, на мой взгляд, тот самый случай, когда изобретение велосипеда неоправданно

Разумеется, второй уровень (со всеми этими упрощениями, событиями и способами обхода автором этого) со временем появится и у меня, его отсутствие — это больше компромисс между желаниями/возможностями и временем, а вовсе не попытка изобрести что-то заново.

Посмотрим, что получится сделать в следующий раз.

  • uux

    Приятно, когда твой фидбэк не остается незамеченным. Спасибо, Олегус! Очень интересно было читать про внутреннюю жизнь парсера — надеюсь, он дорастет-таки до полноценного движка!