Туториал по языку TextGen Script



Урок 0. Примеры, чтобы не было страшно


Чувствую, что многим, кто не программировал, кажется, что сделать скрипт, это очень непонятно и страшно. Давайте покажу, что это совсем не так!


Пример 1:

("Мама " "мыла " "раму")

Этот скрипт сгенерирует единственную фразу – «Мама мыла раму». Предсказуемо, не так ли?
Проверьте это прямо сейчас:
  • запустите инструмент
  • скопируйте скрипт выше в текстовое поле TextGen Script (S-expression)
  • нажмите «Сгенерировать текст!»

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

("Мама " "мыла " (#r "раму" "окно" "дверь"))

Запустите и проверьте скрипт – он будет выдавать одну из фраз «Мама мыла раму», «Мама мыла окно» или «Мама мыла дверь».

Ну что, надеюсь, теперь у вас появилось уверенность в том, что вы можете это освоить?
Если да, то давайте пойдем дальше и почитаем чуть-чуть теории.
Если нет, то зайдите в инструмент и попытайтесь по аналогии сделать пример, в котором будет еще 4 строчка – «Мама мыла машину». Думаю, у вас получится!

Урок 1. База


Чтобы писать (или хотя бы понимать) генераторы на TextGen Script, нужно понять, что есть всего 3 основных элемента программы:
 

  • Просто текст. Пишется в двойных кавычках. Например: "Мама". Или "Эльф пошел в лес". Если нужно использовать в тексте двойную кавычку, она экранируется обратным слешем - "Вот \" двойная кавычка".
  • Управляющие конструкции. Пишутся без двойных кавычек и управляют процессом генерации текста; используются в паре с текстовыми элементами. Например: есть конструкция #r , позволяющая выбрать случайный элемент.
  • Список. Список - это куча текстов/управляющих конструкций/списков. Список обрамляется в круглые скобки. Например: ("Мама" "мыла" "раму"), или ("Мама мыла раму"), или ("Здесь был " (#r "эльф" "гном")). Все скобки в программе должны быть закрыты!


Основное правило:
Программа работает так: она проходит по всем элементам
  • Если это текст – он идёт в копилку
  • Если управляющая конструкция – она выполняется, результат идет в копилку
  • Если список – проходится по всем элементам списка, применяя данное основное правило; результаты всех элементов складываются в копилку.
В конце работы выводится результат копилки.

Давайте для начала возьмем генерацию только с текстом; несколько программ будут генерировать один и тот же текст.


1 вариант – единственный текст:

("Мама мыла раму")

2 вариант – будут взяты все элементы списка последовательно, и сложены:

("Мама " "мыла " "раму")

3 вариант – какие бы не были вложенные списки, идея остаётся одинаковой. Можно переносить строки, форматировать код и т.д.:

("Мама " (("мыла" " ") "раму"))

Этот пример на сайте


Кстати, никто не запрещает переносить элементы на следующие строки, форматировать текст и писать комментарии:

(
	"Мама " ; комментарий в программе начинается с ; и продолжается до конца строки
	("мыла" "раму") 
)

Урок 2. Рандомная генерация (#r)


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


Управляющая конструкция #r возвращает один из случайных оставшихся элементов списка.
Например, конструкция:

(#r "Туз" "Двойка" "Тройка" "Четверка")

вернёт нам достоинство карты.

Конструкция:

(#r "пик" "треф" "бубей" "червей")

вернёт нам масть карты.

Чтобы сложить их, упакуем их в еще один список; также надо не забыть пробел между достоинством и мастью карты.


Результирующая программа:

( 
	(#r "Туз" "Двойка" "Тройка" "Четверка")
	" "
	(#r "пик" "треф" "бубей" "червей")
)

Этот пример на сайте


В принципе, этого достаточно, чтобы сделать большинство классических генераторов – карт, персонажей и т.д.


А теперь остановитесь и зайдите на страницу, где можно писать свои генераторы:
http://d.janvarev.ru/sexp/textgenscript-htmlru/
Там уже есть программа, которая генерирует тексты abd, abe, acd, ace. Разберитесь, как она устроена, и модифицируйте её как-нибудь, чтобы она делала что-то, что нужно вам!

Урок 3. Переменные и условия


Если всё генерировать случайно, то может произойти казус – в одном месте у нас герой эльф, а во втором – гном. Нехорошо. Чтобы избежать подобного и увеличить связность текста используются переменные.


У них есть три конструкции:
1. #varSet – устанавливает переменную (1 параметр) в значение (2 параметр).

(#varSet "hero" "эльф")

установит переменную hero в значение эльф.

2. @<имя переменной> – возвращает значение переменной. Например,

("Грозный " @hero " вернулся с поля боя")

3. #ifVarEq – проверяет, равна ли переменная (1 параметр) значению (2 параметр). Если да – генерация идет по 3 параметру, иначе – по 4-му. Пример:

(#ifVarEq "hero" "эльф"
	("Вышел эльф из девственного леса... ")
	("Вышел гном из высоких гор... ")
)

Можно делать сложные вложенные конструкции:

(#ifVarEq "hero" "эльф"
	("Вышел эльф из девственного леса... ")
	(#ifVarEq "hero" "гном"
		("Вышел гном из высоких гор... ")
		("Вышел непонятно кто непонятно откуда... ")
	)
)

Ну, и наконец пример, задействующий все элементы – генерацию, случайный выбор и переменные:

( 
	(#varSet "hero" (#r "эльф" "гном")) ; выбираем случайного персонажа
	(#ifVarEq "hero" "эльф" 
		("Вышел эльф из " (#r "девственного леса... " "зеленой рощи... ")) ; подвыражения будут работать
		("Вышел гном из высоких гор... ")
	)
	"Помотал головой... "
	"И направился " @hero " в сторону великого города..."
)

Этот пример на сайте

Урок 4. Объединение программ


Одно из самых больших преимуществ языка по сравнению с другими способами генерации текста – возможность легко использовать чужой код для генерации.


Возьмем для примера текст про Штирлица и попытаемся его разнообразить:

(
"Штирлиц потянул карту. Дама пик."
"\"Перебор\" – подумал Штирлиц."
)

Возьмем наш код для генерации карт. Мы можем просто взять готовую программу и добавить её в то место, которое мы хотим сгенерировать.
Выглядеть это будет так:


(
"Штирлиц потянул карту. "
( 
	(#r "Туз" "Двойка" "Тройка" "Четверка" "Дама")
	" "
	(#r "пик" "треф" "бубей" "червей")
)
"."
"\"Перебор\" – подумал Штирлиц."
)

У нас есть множество стандартных программ, которые можно использовать:

и куча всего другого!