
Twine 2 — один из простых «движков» для создания интерактивных текстовых новелл с разветвлённым сюжетом. Для нарративного дизайнера может быть как инструментом создания сюжетной игры, так и прототипирования вариативности сюжета.
Новеллы, созданные на Twine

Различаются жанром, масштабом и использованием визуального оформления:
This book is a dungeon RPG-новелла с исследованием подземелья.
Depression quest социальная игра, знакомящая игрока с опытом проживания депрессии.
Wayfarer фэнтези-RPG.
Boat Prom или Crown of Ashes and Flames романтические новеллы.
Nanopesos менеджмент с анимированными спрайтами.
Insert Rich Family Name новелла расследование.
The Temple of NO шуточная деконструкция жанра новелл на Твайне.
Можно делать новеллы/прототипы и проще — например в рамках 2 курса геймдизайна, студенты создают свои новеллы на Twine, в короткой форме без оформления, с упором на сюжет:
Звёздочка, Фёдор Килин Извините, Вы не могли бы..., Валерия Белогузова Слушай внимательно, Динара Гафина Ритуал перемены дат, Ари Дунаева
(именно такую короткую новеллу на 3-5 минут мы будем рады видеть в качестве демонстрации сюжета/части сюжета вашей игры для вступительных экзаменов на геймдизайн!)
Прочие примеры можно поискать на itch.io, куда часто выкладывают HTML-игры.
Вы определились, Twine подходит для разработки вашей идеи.
Будем разбираться, как работать.
Работать в Twine можно в браузере (рекомендуется chrome) или в приложении. Разница невелика, весь функционал работы над историей бесплатен, сохранения работают одинаково. Единственное различие: с шорткатами комфортнее работать в приложении.
У Twine 2 есть несколько форматов. По дефолту используется Harlowe, именно им мы и будем пользоваться.
Заходим в Twine и попадаем в…
Главное меню
Story Работа с историями: создание новой истории, редактирование выбранной, тегирование выбранной (например для обозначения версий/глав одной истории), изменение название, копирование и удаление истории.
Library Сохранение работы в файл: архивирование всего меню истории или импортирование своего архива. Именно в этом разделе вы будете создавать резервные копии рабочих файлов игры.
Build Для нас здесь важно тестирование выбранной истории (демонстрирует инструменты разработчика), игра в историю (как её увидит игрок)и публикация (создать файл, который при открытии дает игроку нашу готовую историю).
В этом разделе вы можете собрать вашу игру в HTML-файл и выложить для игры например на сайты itch.io или textadventures. Или просто отправить кому-нибудь сыграть!
View Сортировка для удобства работы по предварительно сделанным тегам.
Twine Ваши предпочтения по настройкам движка, форматы истории (вариации синтаксиса — мы работаем на Harlowe), общая информация о твайн и возможность оставить сообщение об ошибке
Passage: из чего состоит история?
С главным меню разобрались! Далее нас интересует сама история. Кликаем Story —> New, называем историю и попадаем в её редактирование.
N.B.: В процессе изучения материала пробуйте копировать код в Twine и смотреть, как он работает интерактивно, а также пробовать писать свой код!
Начнём с раздела Passage.
Passage, параграф — один экран истории. Вся наша история — набор параграфов, экранов.
У параграфа есть имя — Name (его не видит игрок, но видите вы при работе с историей) и его содержание — Body (здесь мы можем писать текст, который увидит игрок, и код, который будет от него скрыт).
Кстати этот параграф — стартовый, с него начнется ваша история. Чтобы поменять начальный параграф истории нужно кликнуть на параграф и нажать Start story here.
Чтобы сделать новый параграф, кликаем New.
Или можно написать ссылку на следующий параграф и он появится автоматически.
Links: ссылки между параграфами
Чтобы связать один параграф с другим, внутри body мы можем написать базовую ссылку: [[Имя параграфа]].
Теперь игрок может кликать на ссылку и переходить в следующий параграф. В редакторе параграфы визуально соединятся стрелкой.


Что видим в редакторе/что видим в игре
При таком переходе есть минус — игрок видит название вашего следующего параграфа. И если один параграф называется "Успех", а второй "Провал", довольно сложно будет не дать игроку понять итог действия сразу.
Поэтому мы можем использовать синтаксис сложнее:
[[То, что игрок видит|Название параграфа]]
[[То, что игрок видит->Название параграфа]]


Также, если мы не хотим, чтобы в нашей рабочей среде было много лишних стрелок, мы можем использовать ещё один вид синтаксиса:
(link-goto: "Текст для игрока", "Название параграфа")


Памятка по ссылкам
Итого, памятка по ссылкам между параграфами:
[[Имя параграфа]]
[[То, что игрок видит|Название параграфа]]
[[То, что игрок видит->Название параграфа]]
(link-goto: "Текст для игрока", "Название параграфа")
N.B.: имя параграфа должно до символа совпадать с тем, что вы напишете в скобках. Самая частая ошибка: параграф назван "Ааа", а в ссылке написано "ааа".
Как проверить, что всё работает
На этом этапе уже пора пробовать запускать наш код и смотреть, что получается.
Способ #1: Test from here из параграфа
Способ #2: Тестируем из меню с выбранного параграфа
Сейчас вы уже можете создать сюжетную игру с разветвлённой структурой и значимыми для игрока выборами и протестировать её. Рассмотрим логику посложнее: как создавать открывающийся текст внутри экранов, задавать и пользоваться переменными.
Click: действия внутри экрана по клику
Иногда вам не нужно, чтобы игрок видел всё происходящее в экране сразу, вы хотите дать больше динамики, скрыть часть информации и открывать текст постепенно. В таком случае помогут функции «click-». Эти функции позволяют нам по клику на слова/символы открывать следующие строчки текста.


Как работают эти конструкции?
Конструкция содержит
• команду click-replace:
• указание, что будет кликабельной ссылкой
"какой-то текст/символ"
• крючок, Hook [что появится в тексте по нажатию]
Команда и ссылка оформляются в скобки, к ним подставляется Hook.
(click-append: "ссылка")[Открывающийся текст]
Код из примера выше:
Вы осторожны. Подбираете палку и аккуратно касаетесь сундука. (click-replace: "сундука.")[...мимика! Хорошо, что не может до вас дотянуться.]
Вы вслушиваетесь. (click-append: "вслушиваетесь")[ сундук пытается с вами поговорить, уговаривает его коснуться..]
Конечно же вы трогаете сундук. (click-prepend: "трогаете сундук.")[ не ]
NB #1
Важно, что эта команда работает только с существующим текстом.
Вот так будет работать: Был чудесный день! (click-replace: "день!")[вечер! Время пролетело совсем незаметно]
А так, нет: Был чудесный (click-replace: "день!")[вечер! Время пролетело совсем незаметно]. Не хватает слова «день!», твайн не может отобразить ссылку, когда отображаемого текста не существует.
NB #2
Click-и можно наслаивать и комбинировать с ссылками между параграфами.
Был чудесный день! (click-append: "день!")
[В саду уже расцвели маки. (click-append: "маки.")
[Трудно было поверить, что только началась весна. (click-append: "весна.")[
[[Хотелось прогуляться]]
]]]


NB #3 Самое важное в последовательно открывающихся click-ах — не запутаться в количестве скобочек. Помните, что каждая открытая квадратная скобка должна закрыться. Тестируйте сразу!
Если видите такую ошибку, значит скобки потерялись.


Памятка по click
Заменяемый текст (click-replace: "Заменяемый текст")[Текст, который добавится по клику вместо заменяемого]
Дополняемый текст (click-append: "Дополняемый текст")[Текст, который добавится по клику после дополняемого]
Дополняемый текст (click-prepend: "Дополняемый текст")[Текст, который добавится по клику до дополняемого]
$Variable: переменные
То, что позволяет нам учитывать выборы игрока даже в «линейном» отрезке сюжета и показывать игроку разный текст в зависимости от предыдущих выборов. Переменная обозначается значком $variableName и выводится для игрока текстом.
Переменную всегда называем латиницей, если хотим, чтобы код работал :)
Базовые типы переменных
boolean значения: true/false
number значения: числовые 1, 2, 3
string значения: любые, в том числе текст, но они всегда выделяются в коде кавычками " ".
Типов переменных конечно гораздо больше, но если у вас нет опыта в программировании, сначала разберитесь с ребятами выше. Без остального можно обойтись, пока вы не работаете со сложным массивом данных, картами уровня и большим инвентарём.
Для того, чтобы в переменную что-то положить, нам нужен код с set.
Складываем в переменную текст
Для этого мы после «to» пишем в кавычках нужное нам текстовое значение.
Если в кавычках написать число — оно будет отображаться только как текст, никаких числовых операций с ним не получится.
(set: $scream to "ааа")
Складываем в переменную true/false
В переменную такого типа мы можем положить только два значения
(set: $isMade to true)
Складываем в переменную число
Для этого мы после «to» пишем число без кавычек.
(set: $HP to 3)
Складываем комбинацию значений переменных и текста
(set: $myproverb to "Actions speak" + $adjective+ "than words!")
Для удобства работы при создании переменной можно ограничить переменную типом.
(set: num-type $funds to 0)
(set: str-type $words to "hi")
(set: bool-type $truth to true)
Памятка по $Variables
Имя переменной только на английском и только буквами.
$переменная
Задать переменную — написать код со складыванием в неё значения
(set: $имя переменной to значение переменной)
Если значение — текст, то нужны кавычки " "
NB #1 Чтобы показать переменную игроку, достаточно просто написать её в тексте $variableName NB #2 Если просто написать имя переменной, предварительно ничего в неё не положив, она гордо покажет 0!
If, Else, Either: условия или зачем нам переменные
Показать текст
(if: $переменная is значение)[То, что увидит игрок]
Показать разные выборы
(if: $переменная is true)[[Ссылка 1]] (if: $переменная is false)[[Ссылка 2]]
(if: $переменная is значение)[[Ссылка 1]] (if: $переменная is значение)[[Ссылка 2]]
Показывать определенный блок информации
$переменная — будет отражаться значение переменной
Заниматься математикой!
В случае сложного сложного подсчета статов, вероятностей и прочего красивого математика вам пригодится.
(set: $переменная to $переменная+число)
Памятка по условиям
Условие с переменной:
Показать текст (if: $переменная is значение)[То, что увидит игрок]
Двойное условие:
(if: $переменная1 is значение1 and $переменная2 is значение2)[То, что увидит игрок]
NB #1 Нельзя сочетать разные типы переменных в операциях. Если вы попытаетесь вычесть из числа утверждение, получите ошибку ;) NB #2 Ваш код всегда работает в порядке сверху вниз слева направо. Соответственно если вы пишете выражение, то оно считается «случившимся» только после его окончания.
(set: $A to 5)
$A
(set: $A to $A +10)
$A


Display: оптимизация копий
Не все события вашей истории уникальны: некоторые описания мест/действий не несут в себе вариативности выбора, но должны ждать игрока в любой из веток в одном виде. Для того, чтобы не страдать ctrl+c ctrl+v — есть полезная функция display.
Display показывает внутри одного параграфа всё содержимое другого.
(display: "название параграфа, который нужно подставить")
Типичные ошибки
• количество скобок лишняя, забытая и т. д.
• качество скобок где-то нужны " ", а где-то и () []
• строчная/заглавная в переменной/в ссылке
• буква на другом языке: а-английская и а-русская — разные буквы
• опечатки: cllck-replace и click-replace это разные вещи
• лишние и недостающие пробелы и переносы
Как выложить свою историю?
Выйти в главное меню, зайти в категорию Build и нажать Publish to file! Полученную HTML можно запускать в браузере, и выложить её на itch.io или textadventures.com :)
Ещё возможности!
Твайн умеет анимировать текст, включать таймер, менять цвета, вставлять картинки и так далее. Мы рассмотрели только базовый функционал, позволяющий удобно работать с сюжетом и ветвлением истории. В этом туториале мы остановимся на базовых функциях.
Форматирование кратко описано здесь и позднее перекочует в новую часть туториала.
Где и как искать ещё информацию? Вы можете посмотреть официальную документацию Twine. Рекомендую смотреть: Cookbook с примерами Полную документацию harlowe-версии Twine