Порядок работы интерпретатора
Несмотря на то, что эта статья обросла некоторыми подробностями, она всё ещё требует серьёзной редактуры, упрощения и расширения. Так что пока что это всё ещё черновой вариант.
Эта статья подробно рассказывает о порядке работы интерпретатора (плеера) QSP. Она может показаться вам довольно сложной, но читать её всю не обязательно. Вернитесь к ней, когда у вас возникнут сложности в понимании того, как ведёт себя плеер. А пока достаточно ознакомиться с общими принципами:
- При запуске игры автоматически воспроизводится только самая первая в игре локация. На остальные локации нужно осуществлять переходы с помощью
GOTOилиXGOTO, или вызывать их с помощьюGOSUB,FUNC, или иным предусмотренным плеером способом. - Код действий "прикрепляется" к действию и не выполняется, пока игрок не нажмёт на действие.
- Все команды выполняются последовательно одна за другой, и никогда не выполняются одновременно.
Ниже по тексту будут использоваться следующие определения:
- Переход на локацию — это событие в игре, которое происходит при обращении к локации с помощью операторов
GOTOилиXGOTO. При этом локация становится "активной", или "текущей". Функция$CURLOCвозвращает название локации, на которую был совершён переход, а массивARGS[]этой локации сохраняет свои значения, пока снова не будет осуществлён переход на локацию (другую, или ту же самую). После добавления текста из поля "Базовое описание" в Окно основного описания, действий из поля "Базовые действия" в Окно действий, и выполнения кода из поля "Выполнить при посещении", плеер "останавливается" и ожидает участия игрока, при этом локация, на которую был осуществлён переход, остаётся "активной" ("текущей"), т.е. функция$CURLOCв любой момент может вернуть название этой локации, а массивARGS[]сохраняет значения.
Для переходов существуют только два оператора (подробнее см. статью "Переходы"):GOTO— осуществляет переход на указанную локацию с автоматической очисткой Окна основного описания и Окна действий.XGOTO— осуществляет переход на указанную локацию с автоматической очисткой Окна действий. Окно основного описания НЕ очищается.
- Вызов локации — это событие в игре, которое происходит при обращении к локации с помощью оператора
GOSUB, функцииFUNC, или в связи с выполнением другого события (например, "Выделение предмета", "Загрузка сохранения", "Ввод в поле ввода", "Выбор пункта меню"). В отличие от перехода на локацию, при вызове локация не становится "активной" ("текущей"), т.е. функция$CURLOCне возвращает название этой локации, а массивARGS[]сохраняет свои значения только пока выполняется код локации. После выполнения кода локации, продолжается выполнение того блока кода, который выполнялся до вызова. Например, если локация была вызвана из действия, то после выполнения её кода, продолжится выполнение кода действия, при этом в массивARGS[]внутри действия не попадут значения массиваARGS[]из вызванной локации. При вызове локации в Окно основного описания добавляется текст из поля "Базовое описание" локации, в Окно действий добавляются действия из поля "Базовые действия" локации, и выполняется код из поля "Выполнить при посещении" локации. Очистка окон при вызове локации НЕ ПРОИСХОДИТ.Вызвать локацию можно разными способами:act "Действие с вызовом локации":
*pl "Выводим текст до выз ова"
gosub 'foo' & ! вызываем локацию foo
*pl "Продолжаем выполнять код после вызова локации foo"
end- Оператор
GOSUBвызывает локацию без возвращения результата (подробнее в статье "Пользовательские функции и процедуры"). - Оператор FUNC вызывает локацию с возвращением результата (подробнее в статье "Пользовательские функции и процедуры").
- Нажатием пункта всплывающего меню (см. статью "Всплывающее меню")
- Выполнением какого-либо события в игре, как то: "Выделение предмета", "Выделение действия", "Загрузка сохранения", "Ввод текста в поле ввода" и т.д. (подробнее в статье "Служебные локации").
- Оператор
- Блок кода — это выделенный в отдельное целое фрагмент кода игры. Отдельными блоками кода в QSP являются:
Запуск игры
Каждая игра на QSP структурно представляет собой набор локаций, последовательно записанных в файл.
Когда мы открываем игру в плеере (интерпретаторе), автоматически запускается чтение самой первой локации в файле (далее Стартовая локация), как если бы на неё был совершён переход с помощью оператора GOTO. То есть:
- В Окно основного описания добавляется текст из поля "Базовое описание" локации (поле "Описание" в Quest Generator).
- В Окно действий добавляются действия из поля "Базовые действия" локации (поле "Базовые действия" в Quest Generator).
- Выполняется код из поля "Выполнить при посещении" локации.
- Если на Стартовой локации в переменную
$ONNEWLOCбыло помещено название локации-обработчика события "Переход на новую локацию", произойдёт автоматический вызов этой самой локации-обработчика события "Переход на новую локацию" (см. "Служебные локации"). - После того, как Стартовая локация была прочитана, плеер "останавливается" и ожидает действий от игрока. При этом локация остаётся "активной", т.е. функция
$CURLOCв любой момент может вернуть её название, а в массивеARGS[]данной локации сохраняются значения, которые на ней были выставлены, и эти значения могут использоваться, например, в действиях, выведенных в Окно действий.
Если на Стартовой локации в переменную $COUNTER было помещено название локации-счётчика, примерно через равные промежутки времени (по умолчанию раз в пол секунды) плеер будет вызывать локацию-счётчик (см. "Служебные локации").
Выполнение кода
Код в QSP всегда выполняется последовательно, команда за командой. Чтение команд происходит сверху вниз и справа налево:
*pl "Первая команда"
*pl "Вторая команда"
*pl "Третья команда"
*pl "Четвёртая команда" & *pl "Пятая команда" & *pl "Шестая команда"
QSP не способен выполнить две команды одновременно, или случайно выполнить вторую команду раньше первой. Поэтому в большинстве случаев, если вам кажется, что плеер "забывает" выполнить какую-либо команду, скорее всего эта команда написана в таком месте, где плеер просто не может до неё добраться.
Например, если написано невыполнимое условие, команда никогда не будет выполнена:
if 5>6:
*pl "Данная команда никогда не будет выполнена"
end
Команды, стоящие после GOTO или XGOTO, так же никогда не будут выполнены:
*pl "Текст на локации" & ! этот текст будет виден на локации всегда
act "Переход по XGOTO":
*pl "Этот текст виден благодаря тому, что вы перешли с помощью XGOTO"
xgoto $curloc & ! переходим на текущую локацию
*pl "А эта команда никогда не будет выполнена"
end
act "Переход по GOTO":
*pl "Эта команда будет выполнена"
! но при переходе по GOTO Окно основного описания очистится,
! так что эту строчку вы всё равно не увидите.
goto $curloc & ! переходим на текущую локацию
*pl "А эта команда никогда не будет выполнена"
end
Код действий (ACT) не выполняется сразу, а "прикрепляется" к этим действиям. Он будет выполнен только тогда, когда игрок нажмёт на соответствующее действие.
example=12 & ! присваиваем переменной число 12
! создаём действие
act "Вывести значение переменной example":
*pl example
end
example=37 & ! меняем значение в переменной
То же самое происходит с кодом в гиперссылках. Он не выполняется сразу, когда мы создаём гиперссылку, он выполняется только тогда, когда мы на гиперссылку нажимаем:
usehtml=1 & ! включаем режим распознавание HTML
example=12
! выводим на экран гиперссылку с кодом
*pl "<a href='EXEC:*pl example'>Вывести значение переменной example</a>"
example=37
При выполнени и команды, которая содержит строки с вложенными выражениями, сначала раскрываются вложенные выражения, и только затем происходит работа со строкой, например, передача её оператору для вывода на экран:
яблоки = 23
! Сначала в строку подставится значение,
! потом строка выведется на экран:
*pl "Яблок в кармане: <<яблоки>>."
Переход на новую локацию
Переход на новую локацию может осуществляться с помощью двух операторов GOTO и XGOTO. Различие в их работе заключается в следующем:
- При переходе с помощью оператора
GOTOочищаются Окно основного описания и Окно действий. - При переходе с помощью оператора
XGOTOочищается только Окно действий. Окно основного описания не очищается.
В остальном работа этих операторов схожа:
- В Окно основного описания добавляется текст из поля "Базовое описание" локации (поле "Описание" в Quest Generator).
- В Окно действий добавляются действия из поля "Базовые действия" локации (поле "Базовые действия" в Quest Generator).
- Выполняется код из поля "Выполнить при посещении" локации.
- Если в переменную
$ONNEWLOCбыло помещено название локации-обработчика события "Переход на новую локацию", произойдёт автоматический вызов этой самой локации-обработчика соб ытия "Переход на новую локацию" (см. "Служебные локации"). - После этого плеер "останавливается" и ожидает действий от игрока. При этом локация остаётся "активной", т.е. функция
$CURLOCв любой момент может вернуть её название, а в массивеARGS[]данной локации сохраняются значения, которые на ней были выставлены, и эти значения могут использоваться, например, в действиях, выведенных в Окно действий.
Если в переменную $COUNTER было помещено название локации-счётчика, примерно через равные промежутки времени (по умолчанию раз в пол секунды) плеер будет вызывать локацию-счётчик (см. "Служебные локации").
P.S.: "Переход на новую локацию" — это устоявшееся название события. Технически более правильно называть такие переходы просто "Переход на локацию", поскольку мы можем переходить не только на новые, но и на текущую локацию:
"Счёт: <<count>>"
act "Обновить":
count+=1
goto $curloc & ! перезаходим на текущую локацию
end
Поэтому, столкнувшись с выражением "Переход на новую локацию" помните, что оно может значить в том числе и переход на текущую локацию.