http://ifprint.org/articles/interview-asber/

Интервью: Александр Боричевский (ASBer)

Март 31, 2013 • Автор: Вадим Балашов •

Вашему вниманию представляется интервью с автором русскоязычной парсерной платформы для интерактивной литературы под названием «Текстовая основа миростроения» или, сокращенно, ТОМ. На настоящий момент в активной разработке находится вторая версия этого движка, ТОМ 2. Заранее извините за наивные вопросы. Человек, задающий их, совсем не в теме разработки парсеров. А человек, отвечающий на вопросы, в теме очень давно. Потому возможны какие-то «перекосы». Итак, поехали.

Как тебя зовут? Где живёшь? Сколько лет? Развиртуализируйся пожалуйста!

Александр Боричевский, живу в Москве, на жизнь зарабатываю программированием в 1С, C++ исключительно как хобби, 44 года.

С чего всё началось? Почему собственный движок? Чем не устроили RTADS и RInform? Чего в них не хватало?

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

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

В RTADS и RInform на некоторые вещи вообще нельзя ни как повлиять. Например, я не знаю способа заставить RTADS правильно выводить предлоги в сочетании со словами в случаях подобных «со стены», «во дворе», «со словами», а ТОМ обрабатывает вывод предлогов на автомате. Это конечно мелочь, но таких мелочей набирается прилично.

А еще RTADS и RInform не умеют говорить так же, как робот из мультика…

Что такое вообще парсер TOM 2 со структурной точки зрения? Анализатор введённой строки и библиотека слов? Как выглядит алгоритм работы парсера?

Больше всего это похоже на игру в шахматы, только по особым правилам.

На первой линии шахматной доски пишутся слова команды, по одному слову на клетку. К ним же в клетки ставятся фигуры. Каждая фигура соответствует некоторому смыслу слова. То есть в каждой клетке могут стоять от одной до нескольких шахматных фигур, в зависимости от многозначности слова.

В ходе игры к соседним клеткам на доске применяются правила (парсерные комбинаторы). Один ход – одно правило. Каждое правило описывает, какие фигуры должны быть в клетках на входе, и какая фигура — на выходе правила. В результате с каждым ходом количество занятых клеток на доске сокращается. Партия считается выигранной, если на доске остается одна фигура – однозначное решение. Если остаётся несколько фигур в одной клетке – это пат, строка не может быть разобрана однозначно. Если остаётся занято несколько клеток и ни одно правило к ним не подходит – партия проиграна, строка не разобрана. В этом случае производится откат и попытка применить другие правила, или изменить последовательность применения правил. В случае если ни одна комбинация правил не приводит к в выигрышу или пату – это окончательный проигрыш, команда не может быть разобрана.

А как решается проблема комбинаторного взрыва? Есть ли она вообще в случае ТОМ?

Нет никакого взрыва. ТОМ 2 как раз и задумывался, чтобы избежать проблемы, которую я сполна прочувствовал, когда писал игры под первый ТОМ.

Что вообще из себя представляет библиотека слов? Что она позволяет задавать? Род, число, склонение? Отзыв системы благодаря этой библиотеке может формироваться автоматически?

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

Описание словоформ содержит род, число, падеж, а также одушевлённость, время, лицо, наклонение, и много другое. При необходимости состав параметров легко расширяем.

Каков формат библиотеки? Собственной разработки? Или она совместима с какими-то известными или неизвестными иными парсерами?

Словарь, она же и стандартная библиотека, хранится и редактируется в базе mySQL. Разработка полностью собственная, создавалась специально для ТОМ с учетом его «фишек» и синтаксиса, поэтому эта библиотека ни с чем другим не совместима. Из SQL базы делается выгрузка в файл специального формата, с которым непосредственно работает парсер ТОМ.

Наполнение библиотеки производится автоматически? Или требуется ручная работа?

Наполнение полуавтоматическое. Есть загрузки из текстовых файлов, самая полезная из них – загрузка из словаря Зализняка. Также есть несколько инструментов и автоматических обработок, позволяющих существенно сократить ручную работу. Но часто встречаются слова, которые ни одной обработкой не распознаются, вот их только ручками. В базе одновременно содержатся слова находящиеся на различных этапах готовности, по сути это некий словарный конвейер. В файл же попадают только полностью готовые слова. В словаре сейчас около 4,5 тысяч обработанных слов.

Из интернета были скачаны несколько словарей в формате CSV, загружены в базу SQL, обработаны и выгружены в файловый словарь ТОМ.

Структуру базы не рисовал, надо бы этим заняться. Там всего 3 таблицы с данными и 5 вспомогательных таблиц для формирования файлового словаря.

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

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

Библиотека всегда идёт в комплекте с ТОМ вне зависимости от того, какие слова используются в конкретной игре? В INSTEAD при использовании метапарсера возможно создавать словарь, в котором будут только те слова, которые используются в игре. Какой из подходов лучше? Единый словарь для всех или персональный словарь для каждой конкретной игры?

Единый словарь однозначно лучше.

Словарь весит меньше 1,5 мегабайта, смешная цифра на сегодняшний день. Других контраргументов кроме веса я не вижу. Даже если слово не используется в игре, всегда приятно получить осмысленный ответ на это слово. Но самое главное — это синонимы. Практика показывает, что ни один автор не может предусмотреть все синонимы ко всем словам своей собственной игры. Зато игрок может легко применить упущенный синоним и наткнуться на непонимание.

Словарь ТОМ позволяет указывать синонимические связи между словами. Правда, сейчас работа по наполнению словаря синонимами только в самом начале.

Что касается INSTEAD, то там несколько другая ситуация, предполагающая, что игрок видит набор слов для конструирования команды. ТОМ же как классический парсер работает вслепую, поэтому для него важен максимально широкий лексикон распознаваемых слов.

Почему словарь весит всего 1.5 МБ? Если слов несколько тысяч, для каждого нужно хранить много дополнительной информации… Или это пока он весит 1.5 МБ, а в дальнейшем он существенно вырастет в размерах?

Словарь растёт по мере наполнения, но большая его часть — это текст с хорошей возможностью сжатия. 1.5 МБ текста — это довольно толстая книга. Вряд ли размер словаря существенно вырастет в ближайшее время, так как основной словарный запас уже находится в нём.

Каким образом выполняется добавление собственных слов в словарь? Скажем, мне нужно ввести слово «вампироуловитель». Мне нужно прописать как-то его в игре? Прописать для него возможные падежные варианты? Или это оформляется в виде дополнительного словаря?

Слова для игры — это такие же объектные значение как, например, локации или классы.

Существуют конструкторы для описания слов. При желании можно вообще отключить словарь и описать все необходимые слова самостоятельно, но это уже будет весьма существенный объём работы. Для «вампироуловителя» описание выглядит примерно так:

Код:
Слово вампироуловитель
{ 
  Ключ = МрНд 
  //мужской род, неодушевлённое
  Ключ_по_умолчанию = ИпЕч 
  //по умолчанию используется 
  //именительный падеж ед. числа
  Форма ИпЕч = вампироуловитель
  Форма РпЕч = вампироуловителя
  Форма ДпЕч = вампироуловителю
  Форма ВпЕч = вампироуловитель
  Форма ТпЕч = вампироуловителем
  Форма ПпЕч = вампироуловителе
  Форма ИпМч = вампироуловители
  Форма РпМч = вампироуловителей
  Форма ДпМч = вампироуловителям
  Форма ВпМч = вампироуловители
  Форма ТпМч = вампироуловителями
  Форма ПпМч = вампироуловителях
}

Как указать, что слово «вампироуловитель» — оружие и является синонимом «упыреловки» и «дракулосканера»?

При условии, что слова «вампироуловитель», «упыреловка» и «дракулосканер» и класс «оружие» описаны выше, это будет так:

Код:
объект вампироуловитель
{ //конструктор объекта
  это оружие
}
//переменная - синоним
var упыреловка = вампироуловитель
//переменная - синоним
var дракулосканер = вампироуловитель

*пример с синонимами устарел, с тех пор появился новый формат для синонимов.
Игрок оперирует объектами, а слова лишь указывают на объекты и переменные с совпадающими именами. При этом объект один — вампироуловитель. Упыреловка — это переменная, указывающая на объект вампироуловитель.
То есть совершенно не важно, как мы назовем объект в команде — вампироуловитель или упыреловка.

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

Как добавить объект в группу «оружие» понятно. А, скажем, мне нужно удалить его из группы? Например, в моей игре копьё не считается «оружием»? Можно ли принудительно удалять объект из группы? Для этого придётся описывать его полностью «с нуля»? или достаточно указать НЕ принадлежность его к одной из групп?

В терминах ООП «группы» называются классами, в ТОМ ООП несколько специфично, но тем не менее классы там есть. В словаре уже есть класс «копьё», унаследованный от класса «оружие».

Если создать объект с именем «копьё», то этот объект автоматически станет наследником одноименного класса (имена слов, классов и объектов лежат в разных именных пространствах, поэтому имена могут совпадать). Чтобы наше копьё не было оружием, ему при создании надо задать составное имя — «копьё:111», «копьё:моё», «копьё:не_оружие». В этом случае объект будет откликаться на слово «копьё» благодаря префиксу «копьё:», но не будет привязан ни к одному классу. Классы этому объекту нужно будет указать отдельно: «копьё:моё это торт».

Как обстоит дело с моей любимой буквой «ё»? Нужно ли создавать «копье» и «копьё»? И как обрабатывается ввод? Введённая фраза «бросить копьё» переводится в «бросить копье», а только потом запускается алгоритм? Или в базе хранятся все варианты слов?

Я тоже люблю «ё». Имена «копьё», «копье» и «КоПьЁ» для ТОМ 2 эквивалентны. С преобразованием там немного сложнее, команда может содержать строки, для которых регистр и буква «ё» имеют значение, поэтому подмена «ё» на «е» происходит не целиком для всей команды, а уже после её токенизации, там, где это нужно.

В словаре используются группы слов? Для каждого слова указывается принадлежность к группе, синонимы и пр.? Как это выглядит?

Сами слова никак не группируются. Но помимо слов в словаре есть классы, которые соответствуют значениям слов. Классы образуют семантическое классовое дерево. При этом классы соответствующие различным значениям одного слова, оказываются на разных ветвях классового дерева.

Синоним – это значение слова, привязанное к классу другого слова. Синонимы также отображаются на классовом дереве. Навигация по словарю возможна как по алфавитному списку слов, так и по дереву.

В парсерной игре «The Hobbit» возможно давать сложные команды, типа «THORIN, GO NORTH AND GET THE KEY». Возможно ли такое в ТОМ?

Возможно. Даже в предыдущем ТОМ это работало (в текущей версии ТОМ 2 пока не реализовано).

Какие возможности описания NPC существуют в TOM?

На текущий момент NPC можно описать как объект и не более. Будут ли для NPC какие-либо специальные фишки пока сказать не могу, может быть, и будут. Для начала надо с ними поиграться и понять, что именно еще нужно. Хотелось бы видеть NPC более самостоятельными и активными.

Возможны ли команды типа «ВЗЯТЬ ВСЁ ОРУЖИЕ КРОМЕ МЕЧА»?

В принципе возможны, но сейчас я не могу сказать, буду ли усложнять дальше «ВЗЯТЬ ВСЁ».

Скажем, мне нравится INSTEAD. Нравится его мультиплатформенность и относительная лёгкость написания кода игр на LUA. Возможен ли перенос алгоритма ТОМ на INSTEAD? Для этого нужно переписать его на LUA? Или ТОМ сам по себе мультиплатформенная система? Или чтобы использовать на INSTEAD парсер, проще взять в качестве заготовки систему 6-DAYS?

Первый путь – подключение ТОМ как DLL. Насколько это применимо к INSTEAD, сказать не могу, но с другими платформами опыт такого использования есть.

Второй путь – использование исходников ТОМ на C++ для портирования на другую платформу. Ничего специфичного ТОМ не использует, исходники будут опубликованы. Остаётся только найти человека, который захочет в этом ковыряться :)

В возможность переписать ТОМ на LUA мне верится с трудом, тут действительно лучше смотреть в сторону 6-DAYS, но боюсь, что и в этом случае будет легче написать свой парсер, чем скрестить 2 неродственные системы, хотя тут я не эксперт, LUA не знаю, советовать не вправе.

Сейчас код ТОМ выложен где-то? он будет open source?

Код первого ТОМ выложен под «The zlib/libpng License», код ТОМ 2 будет опубликован под этой же лицензией одновременно с релизом. Сейчас там всё пока еще сыро, не имеет смысла публиковать.

Пока на движке нет игр, движок мёртв. Более того, многочисленные нюансы могут вылезти только в процессе разработки игр под него. И, в большей степени, сторонними разработчиками. Ведь они видят процесс со стороны. Автор движка часто инкапсулирован в своих идеях. Сейчас ситуация с играми под ТОМ крайне тяжёлая. Есть 4 игры. И всё обостряется тем, что отсутствует документация для разработчиков игр. Планируется ли разработка качественной документации после выхода ТОМ 2? Или сработает старая отговорка любого разработчика, дескать «пока не отладится всё, документацию писать бесполезно»? Тогда снова будет замкнутый круг — игр нет, потому что нет документации и пр…

Написание документации сопоставимо по объёму и трудоёмкости с написанием самого движка. Для первого ТОМ документация разрабатывалась, там есть уроки, описание языка. Их можно найти на форумах (Прим. редактора — есть отдельный форум ТОМ и форум ТОМ на IFiction.ru) и на IFwiki.

Вся эта работа была свёрнута вместе с разработкой самой платформы. ТОМ 2 сейчас находится на стадии поздней альфа-версии. Документацию к нему планирую начать писать и публиковать сразу после выхода беты. Помощь сторонних разработчиков бесценна! Они мне очень помогли с первым ТОМ, со вторым, надеюсь, будет так же.

Какие игры нравятся тебе? Какие любимые? Какие парсерные игры любимые?

В последнее время зависаю в «Minecraft» на сервере greencubes.org, иногда катаюсь на танчиках в WoT. В парсерные игры на английском играть, к сожалению, не могу из-за незнания языка. Из любимых парсерных — это однозначно «Дримор» от Гранда и все игры Корвина — «Оружие Ли Гуана», «Башня между мирами». Особо надо отметить «Супрематизм» — эти две «игры» как нельзя лучше показывают влияние парсера на воображение игрока.

А менюшные квесты?

Литературный уровень большинства «менюшек» ниже плинтуса, а с технической стороны там для меня мало интересного. Но у квестов есть авторы и есть АВТОРЫ. Практически все квесты от Корвина интересны: «Джин из машины», «Баллада о рыцаре слова и его невесте» — просто шедевры. Аджента хорошо пишет, игра «В тени сумрачного леса» понравилась. «Возвращение квантового кота» от Петра тоже шедевр. Но я в «менюшки» очень мало играю, вполне мог пропустить что-то ценное.

Какие у тебя увлечения помимо парсеров и прочих игр?

Люблю жену и хороший коньяк, а все остальные интересы находятся исключительно по ту сторону экрана монитора.

Спасибо за интервью! Ждём ТОМ 2 и парсерных игр на нём!