## Описание языка urql

### Содержание

Пояснения к доке

Что такое urq квест?

Системные конструкции

Системные переменные

Операторы

Предметы

Комментарии

Математические и логические операторы

Примеры

Режимы urq_mode

Плагины

Файл manifest.json

### Пояснения к доке

скобки [] - обязательный параметр

скобки {} - необязательный параметр

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

### Что такое urq квест?

urq-квест состоит из текстового файла с расширением ".qst", и, при необходимости, файлов ресурсов: таких как картинки, музыка. Для удобства все файлы лучше запаковать в zip архив.

Если квест большой, то для удобства можно разделить qst файл на несколько файлов. Например, был один big.qst, и мы решили разделить его на три файла: glava1.qst, glava2.qst, glava3.qst, это будет работать. Но какой файл загрузится первым? Это ведь важно, в таких вещах нельзя полагаться на случайность! Поставьте символ "_" перед названием файла чтобы гарантированно сделать его главным. В нашем примере это будет _glava1.qst

Для редактирования qst файлов используйте любой текстовый редактор на ваш вкус.

### Системные конструкции:

#[переменная]$ - вывод переменной

#%[переменная]$ - вывод переменной

`яблок = 4
pln У меня #яблок$ яблока!
`

Результат:

`У меня 4 яблока!`

##[код символа]$ - вывод экранированного символа. Экранированный символ пригоден только для вывода на экран, он не может быть частью оператора. Например, ##59$ это экранированный символ ";" в режимах ripurq, dosurq и akurq не будет считаться комментарием. Можно использовать ##44$ (экранированный символ ",") чтобы вывести строку с запятой в операторе btn

#/$ - заменяется на перенос строки

#%/$ - заменяется на перенос строки

#$ - заменяется на пробел

#%$ - заменяется на пробел

& - склеивает операторы между собой (исполнение слева направо)

`a = 1 & goto castle`

_ - если является первым символом в строке, то сам символ отбрасывается, а остальная часть строки интерпретируется как продолжение предыдущей.

Может использоваться для более удобного форматирования исходного кода:

    if key = 1
    	_ then door = 0
    	_ else door = 1

### Системные переменные

urq_mode - флаг, указывающий на особенности в проигрывании данного квеста (подробности ниже) нужен для проигрывания старых квестов, написанных под другие интерпретаторы. Значение можно задать как из кода игры, так и при помощи файла manifest.json.

urqw_title - заголовок страницы UrqW (контейнер title), на которой отображается интерфейс игры. Если присвоить новое значение, то заголовок страницы будет изменён. Значение можно задать как из кода игры, так и при помощи файла manifest.json.

urqw_game_ifid - идентификатор интерактивной литературы, который служит уникальным универсальным идентификатором для игры. Значение задаётся при помощи файла manifest.json.

urqw_game_lang - язык областей интерфейса UrqW (атрибут lang), в которых отображается контент игры. По умолчанию - язык общего интерфейса UrqW. Если присвоить новое значение, то изменится язык только области инвентаря, текстовой выдачи, кнопок выбора и поля ввода текста. Значение можно задать как из кода игры, так и при помощи файла manifest.json.

urqw_version - версия UrqW, в которой проигрывается urq-квест.

count_[локация] - счётчик заходов на локацию, меняется от операторов btn, proc, goto

music - если присвоить этой переменной файл с музыкой, то она начнёт проигрываться циклично (будет бесконечно повторяться по окончанию) (путь необходимо указывать относительно qst файла)

`music="music/fon.mp3"` `music="fon.mp3"`

А если присвоить переменной music значение в виде пустой строки, то это остановит текущее воспроизведение зацикленного аудиофайла.

`music=""`

common - изменение этой переменной приведёт к тому, что оператор btn станет вызывать локацию не :common, а :common_{значение} при переходах

current_loc - название текущей локации. Меняется при btn и goto переходах

previous_loc - название предыдущей локации. Меняется при btn и goto переходах

last_btn_caption - название последней активированной кнопки выбора или ссылки в тексте.

style_dos_textcolor - число от 0 до 15. Меняет цвет текста на DOS-цвета. Вот они:

`0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15`

style_textcolor - меняет текста на указанный (в шестнадцатеричном формате с префиксом #)

style_backcolor - меняет цвет фона (в шестнадцатеричном формате с префиксом #)

`style_backcolor = "#000" /* цвет фона теперь черный */`

image - выводит указанную картинку на экран (путь необходимо указывать относительно qst файла) в формате png, jpg, gif, и других

`image="images/battleship.jpg"` `image="battleship.jpg"`

Картинке можно задать альтернативный текст, описывающий её содержимое для игроков, которые по различным причинам не могут воспринять изображение напрямую. Для этого текст описания надо добавить после пути к файлу через вертикальную черту. Если описание для картинки не задано, то у неё будет описание по умолчанию: "Изображение".

`image="images/battleship.jpg|Линкор"`

image_caption - задаёт видимый текст с описанием картинки. Если эта переменная имеет непустое значение, то все картинки, выводимые при помощи переменной или оператора image, будут показываться в рамке с добавлением внизу значения переменной image_caption.

inv_[предмет] - возвращает количество [предмета] в инвентаре. Если присвоить этой переменной числовое значение, то количество предметов в инвентаре станет равным этому значению.

`inv_Яблоко = 4
if inv_Яблоко > 0 then pln у меня есть как минимум одно яблоко!`

[предмет] - возвращает количество [предмета] в инвентаре

`inv+ 4, Яблоко
if яблоко then pln у меня есть как минимум одно яблоко!`

rnd - при каждом обращении возвращает случайное число от 0 до 1, исключая 1

rnd[число] - при каждом обращении возвращает случайное число от 1 и до указанного числа

`a = rnd5
b = rnd15
pln число a - #a$.
pln число b - #b$.
pln Первое число от 1 до 5, второе от 1 до 15. Вероятно они разные. Хотя кто их знает.`

Результат:

`число a - 3.
число b - 14.
Первое число от 1 до 5, второе от 1 до 15. Вероятно они разные. Хотя кто их знает.`

time - при каждом обращении возвращает число секунд, прошедших с полуночи

`pln #time$
`

Результат для вызова в 10 часов 11 минут 4 секунды до полудня:

`36664`

date - при каждом обращении возвращает число дней, прошедших с 1 января 1970 г.

`pln #date$
`

Результат для вызова 13 марта 2025 г.:

`20160`

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

`hello="Привет, мир!"
javascript="'" + hello + "'.toUpperCase();"
pln #javascript$`

Результат:

`ПРИВЕТ, МИР!`

file_content - если присвоить этой переменной строку в виде внутреннего пути к файлу из пакета игры, то этот файл будет прочитан как текст в кодировке UTF-8, а полученное содержимое станет новым значением этой переменной.

`file_content="LICENSE.txt"
pln <div style="white-space: pre-wrap;">#file_content$</div>`

file_url - если присвоить этой переменной строку в виде внутреннего пути к файлу из пакета игры, то новым значением этой переменной станет относительный URL данного файла.

`file_url="video.mp4"
pln <video width="640" height="360" controls>
_<source src="#file_url$" type="video/mp4">
_Ваш браузер не поддерживает тег ##60$video##62$.
_</video>`

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

instr_leave_spc - позволяет включить сохранение пробелов при инициализации строковой переменной с помощью оператора instr. Если значение этой системной переменной отлично от нуля, то в instr-присваиваниях сохраняются пробелы, иначе нет. Имеет смысл для совместимости со старыми играми. В новых использование оператора instr в целом не рекомендуется.

### Операторы

end - оператор окончания выполнения. Управление отдаётся игроку, он может нажать на кнопки, использовать инвентарь, и вообще. Обычно ставится в конце локации.

p {текст} или print {текст} - выводит указанный текст на экран. Можно использовать html. Строка не будет перенесена.

`p Рыцарь с <b>мечом на поясе</b> громко рассмеялся.
p Похоже, он был навеселе.`

Результат:

`Рыцарь с мечом на поясе громко рассмеялся. Похоже, он был навеселе.`

pln {текст} или println {текст} - выводит указанный текст на экран и переносит строку. Можно использовать html.

`pln Рыцарь с <b>мечом на поясе</b> громко рассмеялся.
pln Похоже он был навеселе.`

Результат:

`Рыцарь с мечом на поясе громко рассмеялся.
Похоже он был навеселе.`

[[ текст {| действия или локация }]] - эта конструкция вставит ссылку в оператор p или pln. При нажатии на ссылку. Может произойти переход на локацию или любое другой действие. Ссылками так же могут быть html элементы, например картинки.

#### Примеры:

`pln Рыцарь с [[ мечом на поясе ]] громко рассмеялся.`

Результатом будет ссылка, при нажатии на которую совершится переход на локацию мечом на поясе:

`Рыцарь с мечом на поясе громко рассмеялся.`

Или так:

`pln Рыцарь с [[ мечом на поясе | осмотреть_меч ]] громко рассмеялся.`

Результатом будет ссылка, при нажатии на которую совершится переход на локацию осмотреть_меч:

`Рыцарь с мечом на поясе громко рассмеялся.`

Или так:

`pln Рыцарь с [[ мечом на поясе | внимательность = внимательность + 1 & goto осмотреть_меч ]] громко рассмеялся.`

Результатом будет ссылка, при нажатии на которую внимательность увеличится на единицу, и совершится переход на локацию осмотреть_меч:

`Рыцарь с мечом на поясе громко рассмеялся.`

btn [метка], {текст перехода} - нарисует кнопку с указанным текстом. При нажатии игроком на неё, совершится переход на указанную метку (подробнее ниже)

`btn castle, Идти к замку /* При нажатии на эту кнопку совершится переход на метку castle */`

btn [оператор {& оператор...}], {текст перехода} нарисует кнопку с указанным текстом. При нажатии игроком на неё, выполнятся указанные операторы (подробнее ниже)

`btn денег = 14 & goto castle, Идти к замку /* При нажатии на эту кнопку переменная денег станет равно 14 и совершится переход на метку castle */`

:[метка] - метка, на которую можно перейти с помощью операторов goto, proc, btn. Обычно метка - это локация. Для примера создадим локацию рынок. Если это первая локация в игре, то квест начинается сразу с неё.

`:рынок /* обозначение локации */
pln Вы находитесь на шумном рынке. /* выводим игроку текст */
btn vendor, Подойти к торговцу /* добавляем на локацию кнопку с действием */
end /* отдаём управление игроку */`

if [условие] then [тогда]{&тогда...} {else [иначе]{&иначе...}} - оператор условия

`if Яблок >= 4 then pln У меня достаточно яблок else pln У не хватает яблок, возьму-ка я ещё одно! & inv+ Яблоко
/* Если яблок у игрока 4 или больше то выведет "У меня достаточно яблок", иначе выведет "У не хватает яблок, возьму-ка я ещё одно!" и добавит яблоко */`

goto [метка] - переход на указанную метку (увеличит счётчик заходов на локацию, переменная count_[метка])

`pln телепортируемся!
goto castle /* При встрече этой строчки интерпретатор немедленно совершит переход на метку castle */`

cls - принудительно очищает экран от текста и кнопок

clsb - принудительно очищает экран от кнопок

clsb - принудительно очищает текст от ссылок (превращает в текст)

clst - принудительно очищает экран от текста

music [файл] - проигрывает указанный файл один раз, останавливает предыдущий играющий файл вызванный через music. Воспроизведение идёт в том же аудиоканале, что и зацикленное воспроизведение файла из переменной music.

`music 2.mp3`

play [файл] - проигрывает указанный файл один раз, останавливает предыдущий играющий файл вызванный через play. Воспроизведение идёт в отдельном канале и может быть параллельным с аудио, воспроизводимым при помощи оператора или переменной music.

`play Slash.wav`

image [файл] - выводит указанное изображение

`image picture.jpg` `image picture.jpg|Описание картинки`

proc [метка] - переход на указанную локацию и выполнение квеста до оператора end, после чего возврат на изначальную позицию (на позицию, следующую после вызова proc [метка]) (увеличит счётчик заходов на локацию, переменная count_[метка])

forget_procs - "забыть" о переходе через proc, возврата при встрече end не будет

anykey {переменная} - просит игрока нажать на любую клавишу или щёлкнуть мышкой. После этого выполнение квеста продолжится если указана "переменная", то код нажатой клавиши запишется в эту переменную

`pln Нажмите любую кнопку, чтобы принять лицензионное соглашение.
anykey x /* выполнение прерывается, просим нажать на клавишу. Переменная x станет равна коду нажатой клавиши */`

pause [время в миллисекундах] оператор прерывает выполнение квеста на указанное количество миллисекунд
Важно: в это время игра не заблокирована, игрок может использовать инвентарь и нажимать на btn-кнопки (если есть) Если игрок что-то сделал, то пауза прерывается.

`pln - Теперь подождём пока зелье сварится - сказал волшебник.
pln Мы сели и начали ждать.
pause 5000 /* Пауза в пять секунд */
pln - Готово! Забирай.
inv+ Зелье`

input [переменная] - оператор заставляет игрока ввести что-нибудь с клавиатуры. Введённая строка попадает в переданную переменную

`pln Введите пароль, я не подглядываю
input text_perem
pln Ага! Ваш пароль #text_perem$`

quit - конец квеста. Больше делать ничего нельзя. Никак.

`pln К сожалению, вас съел дракон, вы проиграли.
quit`

perkill - Обнуляет переменные, в том числе и системные (кроме urqw_title, urqw_game_lang и urq_mode). Не используйте без крайней необходимости.

`pln Начинается вторая часть игры. Она совсем никак не связана с первой!
perkill /* Очистить все переменные, они больше не нужны */`

save - Сохраняет игру для пользователя в быстрый слот сохранения.

varkill - Аналогично perkill.

### Предметы

inv+ {Количество,} Предмет - добавляет в инвентарь игроку указанное количество предметов (или один)

`pln - Держи килограмм отличных яблок - сказал торговец.
inv+ 10, Яблоко /* в инвентарь добавилось 10 штук предмета Яблоко */`

inv- {Количество,} Предмет - Отнимает у игрока указанное количество предметов (или один)

`pln - Телепорт стоит 5 яблок! - сказал волшебник. Делать нечего, с половиной яблок придётся расстаться.
inv- 5, Яблоко /* из инвентаря пропало 5 штук предмета Яблоко */`

invkill {Предмет} - Если предмет указан, то обнуляет количество этого предмета у игрока (станет 0). Если предмет не указан, то обнуляет инвентарь игрока (все предметы исчезнут)

`pln Вы проиграли все свои вещи в покер.
invkill`

### Комментарии

`/*
это комментарий
*/`

### Математические и логические операторы в порядке убывания приоритета

( -

) -

not - "не"

`if not Лук then pln У вас нет лука!`

* - умножение

/ - деление

+ - сложение

- - вычитание

< - меньше

<= - меньше или равно

> - больше

>= - больше или равно

= - равно

== - сравнение строк по маске, * заменяется 0 и более любых символов, ? заменяется на один любой символ

`pln Что вы хотите спросить у торговца?
input question
if question == "*алмаз*" then pln - Какие алмазы? - неожиданно рассердился торговец. - Я торгую фруктами!`

!= - не равно

<> - не равно

&& - и

and - и

|| - или

or - или

### Примеры

btn

`btn location, текст перехода /* кнопка перехода на метку location */`

Произойдёт следующее (если метка существует):

1. очистится экран и все кнопки
2. вызовется метка :common или :common_[значение переменной common]
3. изменятся системные переменные previous_loc и current_loc
4. переменная count_location увеличится на 1
5. совершится переход на локацию location

xbtn

Это особенная кнопка с одним или несколькими действиями связанными через &, выполнение которых не обязательно должно приводить к переходу на другие локации. Исторически сохранилось название xbtn, но оператор используется тот же, - btn. Немного меняется синтаксис.

`btn a=a+1 & goto location, текст перехода /* кнопка инкремент переменной "a" и переход на location */
btn goto location, текст перехода /* переход на метку location без очистки экрана и прочего */`

### Режимы urq_mode

Режим urq_mode можно задать как из кода игры через соответствующую переменную, так и при помощи файла manifest.json.

##### urq_mode="ripurq"

системные переменные вида count_метка теперь выглядят как просто "метка", т.е. count_ опускается

очищаются кнопки при переходе goto

Символы разметки HTML экранируются и отображаются вместе с остальным текстом

нет системных переменных common и date

; - однострочный комментарий

##### urq_mode="dosurq"

меняет цвет фона на черный

Значения переменных current_loc и previous_loc меняются только при переходах с помощью оператора btn.

Символы разметки HTML экранируются и отображаются вместе с остальным текстом

нет системной переменной date

; - однострочный комментарий

##### urq_mode="akurq"

Обрабатывается разметка HTML в блоках <html>...</html>

Обрабатываются ссылки перехода на метки вида <a href="btn:метка">название</a>

системная переменная location содержит имя текущей локации, вне зависимости от того, каким образом осуществлён переход в текущую локацию (через proc, goto, btn и т.д.)

системная переменная quest_path всегда равна пустой строке: "" (не эквивалентно AkURQ, но оптимально для совместимости игр без их специальной адаптации)

системная переменная urq_type всегда равна 1

Значения переменных current_loc и previous_loc меняются только при переходах с помощью оператора btn.

нет системной переменной date

; - однострочный комментарий

### Плагины

Плагины расширяют возможности движка или меняют его внешний вид. Примеры плагинов можно найти в отдельном репозитории https://github.com/urqw/plugins.

UrqW в качестве плагинов подгружает два файла:

##### Файл script.js

Содержит код на языке javascript

##### Файл style.css

Описание стилей на языке css

### Файл manifest.json

Файлы игры могут быть дополнены специальным файлом manifest.json, который даёт возможность задать метаданные игры и присвоить начальные значения некоторым системным переменным.

Это файл в стандартном формате JSON и кодировке UTF-8, поддерживающий следующие ключи:

urqw_title - задаёт значение системной переменной urqw_title перед запуском игры.

urqw_game_ifid - задаёт значение IFID для игры, которое потом добавляется в метаданные страницы, отображающей игру, в соответствии с Договором Бабеля. Для каждой игры должен быть сгенерирован свой собственный IFID, например, при помощи инструмента на сайте TADS.

urqw_game_lang - задаёт значение системной переменной urqw_game_lang перед запуском игры.

urq_mode - задаёт значение системной переменной urq_mode перед запуском игры. Переопределяет режим urq_mode, выбранный в интерфейсе плеера.

game_encoding - задаёт кодовую страницу для работы с текстовыми файлами игры. Переопределяет кодировку игры, выбранную в интерфейсе плеера.

html_support - определяет поддержку HTML в тексте и названиях кнопок выбора. допустимые значения true или false. Если явно не задан, то для режимов urq_mode="ripurq" и urq_mode="dosurq" устанавливается значение false, а для остальных - true. Последующие изменения urq_mode после старта игры на поддержку HTML влияния не оказывают.

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

Пример содержимого файла manifest.json:

`{
"urqw_title": "Название игры",
"urqw_game_ifid": "A212F39A-A096-447C-9D83-C0D924599C83",
"urqw_game_lang": "ru",
"urq_mode": "dosurq",
"game_encoding": "UTF-8",
"html_support": true,
"manifest_version": 1
}`