Документация Nyxtale

Платформа NyxtaleЯзык Nyx

Флаги и выражения

Типы флагов, flags_schema, приоритеты операторов, целочисленная арифметика.

Флаги — состояние прохождения: взял ли читатель ключ, солгал ли смотрителю, сколько раз посмотрел в зеркало. Всё, что должно иметь последствия, хранится в них; узлы и сцены состояния не держат.

Четыре типа

Тип Что хранит Пример значения
int целое число 0, -3, 100
bool истина/ложь true, false
str строку "Марк"
set набор строк без повторов key, letter, photo

int и bool закрывают пороги, счётчики и «было или не было». str приходит от читателя через @input и обычно подставляется обратно в реплику. set — коллекции: улики, знамения, найденные комнаты; хранит порядок добавления, дубли не создаёт — повторное добавление того же элемента ничего не меняет.

Объявление: flags_schema

Схема флагов перечисляет, какие флаги существуют, какого они типа, в каких границах и с каким стартовым значением:

sanity   int   0…100   по умолчанию 100
has_key  bool          по умолчанию false
clues    set
hero     str           по умолчанию ""

Что она даёт:

Схема редактируется в Studio, в тексте сцены она не пишется.

Присваивание

@set fear = 0
@set fear += 2
@set fear -= 1
движок принял set×3

Операторы присваивания: =, +=, -=. Справа может стоять любое выражение:

@set fear = 0
@set roll = 0
@set fear = clamp(fear + roll * 2, 0, 100)
движок принял set×3

Для набора += добавляет элемент, -= убирает:

@set clues = 0
@set clues += "photo"
@set clues -= "photo"
движок принял set×3

Выражения

Приоритет операций, от самого слабого к самому сильному:

or  <  and  <  not  <  сравнения (== != < <= > >=)  <  + -  <  * / %  <  унарный -  <  скобки и значения

Операция слева связывает слабее и выполняется позже: fear > 5 and has_key читается как (fear > 5) and has_key.

and, or, not имеют синонимы &&, ||, !.

Значением может быть целое число, true/false, имя флага, выражение в скобках или функция:

Функция Что делает
rand(a, b) случайное целое от a до b включительно
min(a, b) меньшее из двух
max(a, b) большее из двух
clamp(v, lo, hi) v, зажатое в границы
abs(v) модуль
@set fear = 0
@set has_key = 0
@set roll = rand(1, 6)
@if roll + fear / 2 > 5 and not has_key -> panic
движок принял branchset×3jump

Только целые числа

Арифметика целочисленная. Деление отбрасывает дробную часть в сторону нуля (7 / 2 = 3, -7 / 2 = -3), деление на ноль даёт 0.

Причина — детерминизм: историю считают три разных места (превью в браузере, приложение читателя, повтор по сохранению), и дробные числа округляются в них по-разному. На сотом сложении расхождение доходит до сравнения и уводит в другую ветку.

Деление на ноль не роняет сцену — обработайте случай веткой:

@set survivors = 0
@set morale = 0
@if survivors == 0 -> nobody_left
@set share = morale / survivors
движок принял set×3branchjump

Чтение до записи

NSX_READ_BEFORE_WRITE — есть маршрут, на котором флаг читают раньше, чем задают. Проверка обходит все маршруты, поэтому достаточно одной ветки, где читатель прошёл мимо @set.

Два способа починить: задать флаг в начале сцены или объявить значение по умолчанию в схеме. Второй подходит для сквозного состояния (рассудок, репутация), первый — для того, что живёт внутри сцены.

Что дальше