# Разбор сценария — `story_script.js`

Чистый разбор текста истории в структуру, с которой работает `$.story`. Отдельный
модуль, потому что разбор не касается ни узлов, ни отрисовки — его проверяет
юнит-тест, и он же используется инструментами (валидация сценария без запуска).

```js
import { parseStory, checkCondition, applySet } from './story_script.js';

const story = parseStory(`Готовимся:
    say "Привет" at hero
    choice "Идти" -> go | "Стоять" -> stay
label go:
    set flag = 1
`);
```

---

## 1. Что экспортирует

| Функция | Смысл |
|---|---|
| `parseStory(text)` | текст → структура: метки, шаги, выборы |
| `parseSay(line)` | разбор строки `say` (кто, что, куда) |
| `parseChoice(line)` | разбор ветвления на варианты |
| `parseSet(line)` | разбор присваивания |
| `parseValue(text)` | разбор значения (число, строка, флаг) |
| `checkCondition(cond, flags)` | проверка условия |
| `applySet(flags, name, value)` | применить присваивание |
| `isTruthy(value)` | приведение к истине в терминах сценария |
| `labelIndex(story, name)` | найти метку в разобранной истории |

## 2. Формат

* **метка** — `label имя:` задаёт точку перехода;
* **реплика** — `say "текст" at герой`;
* **выбор** — `choice "вариант" -> метка | "другой" -> метка2`;
* **присваивание** — `set флаг = 1`;
* **условие** — проверяется `checkCondition` (флаги, числа, равенство).

## 3. Ограничения

* **нет выражений**: условия и значения простые (флаг, число, строка), арифметики
  и вызовов функций нет;
* **нет ветвления по времени и счётчикам** без явных флагов: всё, что нужно для
  условия, игра выставляет через `$.story.set`;
* **нет вложенных историй**: подключать другую историю из середины нельзя;
* **ошибки разбора молчаливы**: непонятная строка пропускается; для валидации
  полагайтесь на `$.story.parse` и проверку результата в тесте.
