Twine 2. Обзор и руководство для начинающих
По просьбам трудящихся и своей инициативе – разбор Twine 2, инструмента для написания Интерактивной литературы и текстовых квестов.
Дисклеймер: в тексте много технических подробностей, мыслей в слух и мелочей, которые можно пропустить при первом знакомстве с инструментов. Оно все убрано под спойлеры.
Об Twine
Twine 2 – это идейный потомок проекта Twee/TweeBox. В свое время существовал проект Twee, написанный на языке Python. Его внутренняя система разметки/макросов больше всего напоминала Wiki-разметку. Насчет популярности не скажу, но своя армия фанатов у него была. Достаточно большой проблемой Twee была ее скорость работы. Поскольку движок был написан на Python, для сборки десктопных приложений использовалась библиотека wxWidgets, известная своей невысокой скоростью работы.
Позже был создан TweeBox — порт, переписанный на JavaScript. А потом Twee был переименован в Twine. Возможно, в то время и отпочковался коммерческий проект AXMA, более известный у нас, нежели ее прародитель. Потому что сделан и продвигается отечественной командой разработчиков.
К слову, AXMA сохранила тормознутость предшественника. Кто-то говорит. что все нормально, но у меня она всегда тормозит. А еще меня отталкивает жопоголизм разработчиков: за 1000 рублей нам предлагают сохранение HTML-файла, отсутствие копирайта AXMA в файле и (sic!) лицензия на редактирование файла. Это как если бы Adobe требовали ставить копирайт «powered by PhotoShop» в каждой отфотошопленной фотке. И меня пугает внутренний язык разметки/макросов. Но тут кому как.
Сейчас Twine полностью переписан на JavaScript (jQuery/Backbone/Underscore), вместо wxWidgets использует среду исполнения node-webkit. Это дало ей преимущество в скорости. И возможность делать самые разные вещи, которые мы рассмотрим, когда будем собирать готовое приложение для публикации.
Внутри Twine 2 есть такие языки как Harlowe и SugarCube (старый wiki-образный код + чорное оформление). Так же присутствует SnowMan, который предлагает использовать вместо макросов чистый JS внутри тэгов вида <%= %>.В целом, для людей, работавших с AXMA или писавших свою IF-книгу на чистом HTML, проблем возникнуть не должно.
Об Harlowe
Harlowe – достаточно простой и логичный язык макросов, встроенный в Twine 2. Писать на нем лично мне оказалось гораздо проще, удобнее и понятнее, чем в AXMA. Я «верующий» программист, и верую в то, что язык должен отвечать задачам. А писать скрипты в Wiki-разметке это содомия. Прочитайте про философию MVC на досуге.
Внешне Harlowe выглядит совместным потомством языков Clojure и Python. От первого ему достались команды, обернутые в круглые скобочки и минимальный набор используемых знаков пунктуации; а от второго он получил наименование переменных через $variable, три вида массивов и отсутствие «логических скобок» в некоторых макросах. Хотя лично я бы сделал Harlowe более питонообразным. Потому что макрос вида (if (a>b): (print «a>b»)) выглядит изящнее чем (if: (a>b))[(print: «a>b»)]. Как минимум, меньше вложенных скобочек, и в первом случае я лучше вижу логику.
Самое простое в Twine это создание ссылок на параграфы. Это делается так: [[текст ссылки->имя параграфа]] или [[имя параграфа<-текст ссылки]] или просто [[имя параграфа]]. Пробелы вокруг имени параграфа старайтесь не ставить, потому что может начаться всякая неожиданная хрень.
Еще в Harlowe есть inline-оператор {}. Фигурные скобки позволяют превратить несколько абзацев текста в одну строку и убрать лишние пробелы. Очень удобно, потому что Twine понимает переносы строк внутри составных макросов как переносы в тексте.
Из разметки полезно запомнить *Наклонный текст*, **Жирный текст** и ^^Верхний индекс^^.
(set: $variable to value) – устанавливает некоторое значение в переменной. Имя переменной начинается на $.
(print:) – выводит некоторый текст или результат вычислений. Например (print: 5 + 5) выведет 10.
(display: «имя параграфа») – выводит содержимое параграфа.
(if:)[](else-if:)[](else:)[] – стандартная логическая цепочка if-else. В квадратных скобках пишутся действия, которые выполняются при условиях. В (if:) и (else-if:) после двоеточия пишется условие, в(else:) — нет. конструкций (else-if:) может быть несколько. В целом, такая структура соответствует операторам switch-case-dafault в том же JavaScript.
(a:) – создает нумерованный массив. Элементы массива указываются после двоеточия через запятую: (a: 1,2,3,4,5).
(datamap:) — создает именованный массив вида ключ-значение. Т.е. (datamap: «Name1», Value1, «Name2», Value2) вернет массив строк Name1 и Name2, которым соответствуют значения Value1 и Value2.
Макрос (datanames:) вернет массив имен в datamap, а (datavalues:) — список значений.
(current-date:), (current-time:), (monthday:) и (weekday:) возвращают Текущую дату, Текущее время, Число месяца и День недели.
(link: «text»)[New text] — создает интерактивную ссылку, после нажатия на которую текст ссылки подменяется на содержимое квадратных скобок.
(link-reveal: «text»)[after text] — создает ссылку, по нажатию на которую текст ссылки дополняется текстом из квадратных скобок.
(link-goto: «text», «passage») — полный аналог [[text->passage]].
(link-goto: «passage») аналогичен [[passage]].
(go-to: «passage») – безусловный переход на блок passage.
(alert: «Message») — выводит сообщение.
(confirm: «Message») — выводит сообщение с кнопками ОК и ОТМЕНА. Возвращает true или false. Использует Python-подобный принцип: (set: $wantCake to (confirm: «Do you want a cake?»)) – и позволяет напрямую забирать ответ пользователя.
(prompt: «Message») — выводит сообщение и поле для ввода. Можно использовать для запроса пользовательского имени: (set: $name to (prompt: «Your name, please:»)).
Это самые основные макросы, которые понадобятся в самом начале. Остальное есть в документации по Harlowe.
Интерфейс Twine довольно прост. Его можно разделить на главное окно и окно истории. На главном окне вы видите список своих историй, открываются они двойным кликом. В меню справа полезные кнопки это + История, Форматы, и Язык. В меню Форматы можно выбрать между форматами Harlowe, Snowman и SugarCube и выставить его по умолчанию. Harlowe стоит по умолчанию, собственно о нем и идет здесь речь.
После нажатия на + История нам предлагают ввести имя истории и Добавить ее или Отменить решение. История появится в левом верхнем углу списка. На самом блоке истории отображается миниатюра истории. В правом верхнем углу миниатюры под значком шестеренки скрываются подменю: Запустить историю, Тестировать историю, Опубликовать в файл, Переименовать историю, Сделать дубликат истории. Чтобы открыть историю для редактирования по ней нужно кликнуть два раза.
В окне истории вы видите синее размеченное поле и меню внизу. Там расположены кнопки Домой в виде домика, Кнопка с названием истории, поисковая строка, кнопки масштаба,Тестировать, Запустить и +Параграф. В меню с названием истории есть разделы Редактировать JavaScript, Редактировать таблицу стилей, Сменить формат истории, Переименовать историю, Привязать к сетке, Статистика истории, Получить копию для вычитки и Опубликовать в файл. Лично для меня полезными были Редактировать JavaScript (учтите, скрипт загрузится в самом начале, до того, как загрузился движок, на котором работает сама игра), Редактировать таблицу стилей, Привязать к сетке (очень удобная вещь), получить копию для вычитки и Опубликовать в файл (открывается окно для сохранения истории в standalone-файл с движком внутри).
Чтобы добавить параграф нужно нажать + Параграф. На поле появится новый блок. У блока есть всплывающее меню из четырех иконок: Удалить, Изменить, Тестировать и Сделать «имя параграфа» отправной точкой истории. Параграф так же можно удалить кнопкой Delete, а открыть двойным кликом.
У каждого параграфа есть название, на на которое ссылается указатель, а так же тэги, которые можно использовать для стилизации и форматирования. В меню окна приложения есть пункты Twine и Редактировать. В меню Twine есть пункт Показать библиотеку – удобно для добавления историй, хотя это можно сделать через главное меню. Отменять/вырезать/копировать/вставлять можно и через Ctrl+Z/X/C/V. Да, правая кнопка мыши не работает.
Процесс создания игры
В качестве примера по созданию простой игры я буду переносить на Twine свою же игру Press [RE:START]. Исходники можно взять здесь, готовый Twine-файл со стилями здесь.
Для начала я создаю пустой параграф index и вставляю туда исходный тест первой страницы, который помещен внутрь <body>.
Поскольку Twine довольно превратно понимает [квадратные скобки], тест всех ссылок нужно обрамлять в [ ]. Однако, если ВСЕ ваши ссылки обрамляются таким образом, проще открыть Меню истории -> Редактировать таблицу стилей и добавить следующий блок: tw-link:before{content: «[»;}tw-link:after{content: «]»;}
.
Далее, заменяю ссылки вида:<a href=«data/000.html»>[RE:START]</a>на [[000<-RE:START]].
Twine автоматически создает параграфы, на которые были добавлены ссылки, поэтому проблема с созданием параграфов вручную отпадает сама собой.
По очереди переносим содержимое всех страниц в соответствующие блоки, заменяю ссылки на квадратные скобки. Поскольку лишний раз перетаскивать и переписывать мне было лень, ссылки я оформлял в обратном стиле: [[имя параграфа<-текст ссылки]]. Потому что в HTML сначала идет href=»», а потом текст ссылки. Я действительно ленив.
Поскольку мне не нужно возвращаться к предыдущей странице, я открываю в меню «редактировать таблицу стилей» и пишу туда: tw-sidebar{display:none}
. Это позволяет скрыть сайд-бар, на котором показываются стрелочки. В принципе, в Twine можно вставлять код на JavaScript/jQuery, но он исполняется сразу при загрузке, а сами «страницы» генерируются динамически из текста пассажей. Поэтому полностью удалить сайд-бар или набить его новым функционалом через JS лично у меня пока не получается.
Как видите создание страниц довольно просто само по себе, расширять функционал можно через макросы.
В Harlowe учитываются тэги, прикрепленные к блоку. Добавить их можно по кнопке +Тэг под названием истории.
Если вы хотите добавить шаблонный элемент, который будет на каждой странице, добавьте тэг header (содержимое будет отображать над текстом) или footer (содержимое будет отображать под текстом).
Тэг startup позволяет вставить макросы, которые загружаются до начала истории. Здесь можно, например, проинициализировать все переменные.
Так же Harlowe поддерживает локальное хранилище в браузерах. Это позволяет сохранять и загружать состояния игры:
(savegame: «Slot A») — сохраняет игру в слот «Slot A»
(loadgame: «Slot A») — загружает игру в слоте «Slot A»
(saved-games:) — возвращает список сохранений.
В Harlowe есть свои особенности по обращению с переменным и массивами в частности. Так, можно напрямую обратиться в элементу массива через (a:)'s 1st, 2nd, 3rd или last. Так же вместо этого поддерживается синтаксис вида (a:)'s (1) для доступа к первому элементу, (a:)'s (-1) — к последнему элементу.
Twine 2, поскольку он написан на HTML/JS, поддерживает скрипты и HTML/CSS. Для кастомизации содержимого через CSS полезно знать следующие элементы внутренней разметки Twine 2:
- tw-story — корневой элемент истории
- tw-passage — элемент, в котором рендерится сама история. Содержит стандартные свойства, аналогичные элементу div, стой лишь разницей, что свойство width имеет значение по умолчанию 60%.
- tw-link — элемент, в который оборачиваются ссылки типа (link:), (goto:) и [[]]. Поддерживает класс .visited.
- tw-sidebar — элемент, в котором отображаются кнопки вперед и назад.
- tw-icon — иконки вперед и назад. Класс .undo отвечает за иконку назад, .redo — за иконку вперед.
- mark — элемент, используемый для части HTML, которую нужно оставить без изменений. по умолчанию имеет свойства color:rgba(0,0,0,0.6); background-color: #ff9.
Итого:
- Из плюсов: Twine 2 получился удобным, понятным и быстрым. Язык макросов Harlowe – простой, понятный и единообразный. А люди, знакомые с Python, вообще будут себя чувствовать как дома.
- Из минусов: сложность внедрения JavaScript (статьи предлагают прописывать функции через
window.имяФункции()
) и невозможность написания собственных макросов. Что характерно, для SugarCube свои макросы писать можно. - Из неожиданного: Twine мало известен в русском IF-сообществе, но получил распространение среди маргинальных и ЛГБТ-игроделов. Русская Twine-тусовка позиционирует себя как крайний андерграунд и анти-мейнстрим. Даже на фоне всего остального IF-сообщества. Подробнее – здесь.
Публикация готовой игры
Предельно простой вариант
В левом нижнем меню вашей истории выберите «Опубликовать файл» и укажите куда его сохранить. Twine сам соберет HTML файл и добавит в него код движка. Остается только опубликовать. Для этого у сообщества Twine есть сайт philome.la. Или можете разместить ее в любом другом месте, на страничке уже есть код движка.
Node-WebKit
- Экспортируйте историю, сохранив под названием index.html
- Скачайте Node-Webkit (если хотите, можете скачать сборку не под вашу операционную систему, например для Linux)
- Распакуйте его в папку с экспортированным файлом
- Откройте package.json и добавьте туда:
{«name»: «Имя истории»,
«description»: «Описание истории»,
«main»: «index.html»,
«window»: {
«show»: false,
«toolbar»: false,
«width»: 1024,
«height»: 768
}}
- Для проверки запустите nw.exe — должна запуститься ваша история. Можете переименовать nw.exe и заархивировать.
Рецепты
Вариант первый
- Создайте отдельный параграф startup и добавьте ему тег startup.
- В блок вставьте следующий код:(set: $inventory to (a:)). Эта строка создает пустой массив для инвентаря.
- Создайте блок inventory с тегом inventory и вставьте следующий код:
(text: $inventory.join(«\n»))(link-repeat: «back»)[(goto: (history:)'s last)]
. - Создайте блок footer с тегом footer. Это шаблон, который будет выводиться внизу страницы. Вставьте следующий код:
(if: (passage:)'s tags contains «inventory»))[](else: (link-repeat: «check inventory»)[(goto: «inventory»)])
Вариант второй
- Создайте отдельный параграф startup и добавьте ему тег startup. В блок вставьте следующий код:
(set: $inventory to (a:))
- Создайте блок footer с тэгом footer и вставьте следующий код:
<div class=«inventory»>(text: $inventory.join(«\n»))</div>
- В левом нижнем углу откройте меню и выберите «Редактировать таблицу стилей» и вставьте:
.inventory{border-left: 1px #000 solid;float: right;top: 10%;left: 80%;position: fixed;padding: 20px;display:block;}
Теперь ваш инвентарь отображается в блоке справа на каждой странице.
Кстати
Я использую объединенный вариант, потому что решил сделать систему с инвентарем и журналом.
При создании большого проекта, состоящего из over9000 страниц, или совместном написании проекта могут возникнуть трудности с размером файла. Поэтому предлагаю такой рецепт:
- Создавайте историю как несколько блоков – в Twine это можно сделать создавая их как отдельные истории с именами Имя истории-1, Имя истории-2 и т.д.
- Проверьте, что у ваших историй есть входы и выходы – они могут висеть пустыми. Главное чтобы окончание истории имело продолжение в другой, с таким же названием. После чего можете удалить висячие параграфы
- Проверьте, не повторяются ли у вас общие блоки. Это могут быть характеристики персонажа, инвентарь, журнал. Удалите эти блоки из всех историй, кроме, например, первой или последней.
- Создайте пустой проект с названием Имя истории и удалите из него автоматически созданный блок.
- Проверьте любую мелочь, которая может отвалиться.
- Скачайте и установите Notepad++. Он переваривает крупные файлы и у него есть подсветка синтаксиса.
- В верхнем меню выберите Twine -> Показать библиотеку. После чего Twine нужно закрыть, он нам понадобится в самом конце.
- Выделите все файлы, относящиеся к истории, и откройте их в Notepad++.
- Структура у проекта следующая:
<tw-storydata>
<style></style>
<script></script>
<tw-passagedata></tw-passagedata>
...
<tw-passagedata></tw-passagedata>
</tw-storydata>.
Перенесите содержимое блоков <script></script> и <style></style>, если у вас там что-то есть. - Пройдитесь по всем файлам истории, делая следующее: замените
pid=»
наpid=»0n
, где n – номер истории, который вы редактируете. Это позволит избежать конфликтов в игре после ее слияния в один файл.Так же удаляйте все блоки <script></script> и <style></style>, потому что мы их уже перенесли. - Начинайте по очереди – из каждого файла – переносить содержимое между тэгов
<tw-storydata></tw-storydata>
. Переносить их нужно в общий файл, который мы создавали самым последним. - Когда содержимое всех частей истории перенесено, эти файлы можно закрыть. В начале общего файла найдите строку startnode=»1» и замените значение на «011», чтобы не потерять старт истории.
- Сохраните изменения в общем файле и закройте его. Откройте Twine и подождите пока он прогрузит историю. И я не советую вам открывать ее в редакторе. Это будет очень медленно.
Когда Twine прогрузится, в правом верхнем углу истории (общий файл, без цифр), нажмите на иконку шестерни и выберите Опубликовать в файл. Остальные действия такие же, как были описаны выше, в разделе Публикация.
Полезные ссылочки
Собственно Twine 2. В правом верхнем углу нажмите Download и получите копию под свою OS.
All about Twine 2 and Harlowe – британский сайт с рецептами.
Моя собственная папка Twine 2 в Google Drive, где я буду выкладывать наработки, статьи и переводы руководств. Но это не быстро – одно только руководство по Harlowe занимает 50 страниц. Эта статья тоже выложена, открытая для комментариев и предложений.
Для вопросов есть личка на Gamin.me и совершенно открытая личка в vk.
Спасибо за внимание, еще раз извините, что пришлось выкладывать на Google Docs, так еще и сырую версию с «апичаткаме».
- 25 апреля 2016, 10:01
- 017
Эх, твой бы пост да до начала Гаминатора, возможно у нас было бы больше текстовых адвенчур. Вернее, возможно, они бы у нас были. :)
Аминь брат(
Да у меня на работе появилось свободное время аккурат 18-го числа
Я слышала, что, возможно, будет текстовый квест на Гаминатор, только тсссссссс)
Ходят слухи)
Говорят Алюрусфулгенсфобий был замечен на рынке IF-конструкторов)
0_0 внезапно-таки)
Люканя, наверное, сделает текстовый квест.
Это сложнее, чем может показаться.
Сам так говорил себе, но когда начал делать - сразу взял свои слова назад)
Вроде тут в ветке комментариев никто ничего не писал, что текстовый квест - это просто.
Мне кажется, порог вхождения во все эти штуки слишком высок для "просто писателей", а для "уже целых программистов" текстовый квест - не самый интересный жанр. Какая-то незанятая ниша непонятно для кого.
Поэтому техническая подробность убрана под спойлер) а язык реально удобный и главное единообразный. нет месива из <<>>, {}, [] и еще кучи wiki-подобных макросов.
<<picture '[[Файл: folder/mediafile.ext]]'>> – агрх >_<
[[+Взять предмет 1|Обработка {$предмет=1}]] – привет, 1С...
А вот таких простых вещей как loop, for(), input и других полезных вещей реально не хватает :(
Дык без технической части по-настоящему крутой квест не сделать же, не?
Не сделать. Вопрос в удобстве инструмента. Twine, конечно, больше похож на швейцарский нож, но вот AXMA, при том что это неплохой столярный набор, напоминает мне вот эту картинку
А десятка - это реклама камня, который можете сами там приделать к чему-нибудь))
Там много вариантов
О дельная статья, в избранное! Спасибо большое, как раз это близко к AXMA, поизучаю на досуге!
Процесс написания поста заставил вспомнить старый как мир холивар на тему "Как создать игру без программирования". Мысль сия включила механизм батхерта, за чем последовала замена рабочего кресла по причине высокой горючести пластмассы. Но после проветривания комнаты пришла в голову другая мысль – а не написать ли на эту тему познавательную статью? С поэтапным донесением мысли о необходимой эволюции от школо-девелопера до, как минимум, студента-геймдизайнера. Естественно, с указанием всех необходимых инструментов эволюции.
Во имя Чарльза Роберта Дарвина, аминь.
Я знаю кое-кого, кто делал доклад на эту тему.
Где? Когда? Ссылку мне, ссылку, пойду и ознакомлюсь!
Кто-то уже лопату за что-то поставил. Не понимаю.
Доклад – сугой! Докладчик – самурай!
Но моя статья будет об другом. Наверно.
Пиши, буду рад такое читануть! Если пропущу, маякни как-нибудь. Интересно же.
Интересный материал, спасибо, я даже не знала, что есть Twine... зато вон Аксма эта у всех на слуху, а тут такой поворот! ^_^
Пожалуйста) Особенно если дело дойдет до технических подробностей)
У Аксмы сегодня обновление! Появились шаблонные версии при создании нового проекта - 5 видов.
Ога. Интерактивная история, Квест/RPG, Визуальная новелла, Книга-игра (???), Интерактивная аудиокнига. По мне так крайне искусственное членение. Особенно рамки ИИ-Квест/РПГ-ВН.
И в чем раздница?
Давно знаком с Twine. Правда мне по душе больше SugarCube, но это дело вкуса. Имхо, конечно, но такое руководство слишком уж сложное для новичка, который вдруг по каким-то причинам решит написать текстовую игру.
Да и сами текстовые игры слишком уж специфичны. Мало кто в них реально играет. Люди зачастую больше 140 символов не могут прочитать, а тут, можно сказать, целый рассказ, а то и объёмнее.
Вообще, конечно, круто, что еще кто-то знает о Twine. Я думал, что один такой xD
Pillars of Eternity тоже хорошо зашла. Но в такого рода rpg есть графическая составляющая и всё это ну никак нельзя отнести к текстовым играм.
Есть куда более конкретный пример - Choice of Robots. При обильной рекламной кампании (для текстовой игры) и поддержке игроков - всего ~30 тысяч продаж. И это английский язык. Сложно сказать, что будет, если такого рода игра была бы на русском. Мне кажется, что всё же продаж было бы намного-намного меньше.
А кто такие Oleg Isachkin и Дмитрий Шитяков? Нашел в комментах на Google Docs.
Хм. А собственный DOM-манипулятор, аналогичный тому, что лежит в основе Tine, занимает в сжатом виде около 500 байт js-кода. Пример – все там же.
А ты можешь сделать серию уроков по twine 2. К примеру
Twine 2. Урок 1. Где скачать Twine 2?
Twine 2. Урок 2. Как создавать комнаты, и переходить по ним?
Twine 2. Урок 1. Переменные в Twine 2
...
И так далее
На днях посмотрю. Но:
Но я имел ввиду, как во многих уроков, зайдите на официальный сайт Twine 2 (картинка официального сайта twine 2), и кликните на кнопку download в правом вернем углу.
И вообще серию уроков, с картинками, чтобы даже каменный человек, что живет в пещере понял, как сделать игру сравнимую с... Ну ты понял.
Ну как бе
Посмотрим, но по такой мелочи делать уроки? Проще картинку добавить) Она у меня как раз есть.
Большое спасибо. Я как раз заинтересовался темой IF, а тут такой пост. Пойду ковырять Twine
Незачто)
У меня проблема с инвентарем выдаёт ошибку и можно узнать как добавить вещи в инвентарь и перемещать его на зарубежных сайтах не нашел ответа можете помочь?
Есть вопрос, можно ли скрыть на какой-нибудь странице инвентарь?(Мне надо на стартовой) Или если гг не получил сумку и надо сделать так что в данном случае ему будет писать что некуда класть, а если получит то открывается к инвентарю доступ( на самом деле я работаю с журналом) Просто я немного не понимаю систему if else, а видео по ним в основном на sugarbox, а я на другом формате сижу и уже не хочу уходить, есть возможность такое провернуть? Если да, то помогите пожалуйста, заранее спасибо)
Что-то мне подсказывает, что автор уже не ответит. В профиле у него есть ВК, стоит написать туда, думаю.
Товарищи, доброго времени суток. Подскажите, пожалуйста, а то я сам никак не дойду.
Чтобы не делать четыре локации и соответственно, четыре перехода, пытаюсь изобразить следующее:
Надо вооружиться. Вы подошли к оружейной стойке, чтобы [[взять меч|выбор оружия]][(set: $sword to 1)] или [[взять копье|выбор оружия]][(set: $lance to 1)]
Так вот, как сделать, чтобы в зависимости от выбранной ссылки менялось значение определённой переменной? Чтобы в следующей локации отработать уже через if-else, в зависимости от выбора игрока.
`(link: "взять меч")[(set: $sword to 1)(goto: "выбор оружия")]`
Неудобный метод, в редакторе не будет показан переход.
С редактором знаком только по доке, может быть есть способ получше.
Спасибо!
Конечно, отсутствие отображения перехода огорчает, но я бы не обрел покоя, пока не узнал, как это сделать :)
С вами автор статьи
Я с момента написания статьи глубоко ушел в разработчики, поэтому сюда уже практически не захожу
НО! Личка в ВК все еще доступна, хоть и не факт что я вам сразу отвечу. Сейчас у Harlowe вышла третья версия, где появилось много нового, поэтому часть инфы немного устарела (например у них есть циклы и возможность писать свои макросы). Какая-то часть кода из примеров еще рабочая.
Всем спасибо за внимание, пошел дальше работать)