Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

На примере создания детской игры с загадками

И вновь приветствую всех! Пока продолжение прошлого поста, посвященное основам построения сюжета, еще в процессе написания, я попробую максимально доступно описать методы ветвления сюжета на примере детской игры с загадками (и, возможно, не самой лучшей графикой - не могу же я весь контент показать до релиза?).

Эта статья посвящена техническим моментам реализации новеллы при помощи инструментов движка RenPy, в частности - вариативности сюжетных линий.

В комментариях к прошлой записи несколько раз прозвучал вопрос о том, как реализована параллельность сюжета в новелле Spiritual Cavern, которая уже обзавелась собственной группой на Facebook.

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

Спойлер: создание новеллы с графикой и написанием кода заняло 20 минут.

Графика: персонаж и фон

Какая новелла может обойтись без действующих лиц? Подготовим нашего персонажа, который будет загадывать загадки:

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

События происходят не посреди пустоты, потому нам потребуется фон:

Комната, где нам загадывают загадки. Мрачновата, но для примера сойдет)
Комната, где нам загадывают загадки. Мрачновата, но для примера сойдет)
Улица, куда мы можем попасть только в одной из концовок
Улица, куда мы можем попасть только в одной из концовок

Простейший сюжет

Подготовив материалы, мы можем приступить к составлению сюжета - в нашем примере он будет очень простым:

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

Суть сюжета очень проста: игрок трижды отвечает на вопросы, в зависимости от его ответа меняется настроение кубика. Кроме того, при каждом правильном ответе мы увеличиваем счетчик "Ответы", от которого в последствии зависит концовка игры: если был дан хоть 1

Итак, приступим. Я не буду описывать полный процесс написания кода в RenPy, так как уроков наэту тему довольно много. Но уделю отдельное внимание тем функциям, которые отвечают за ветвление сюжета.

Написание кода игры

Не пугайтесь, если показанные ниже примеры кода покажутся Вам сложными, или раньше у Вас не было опыта в работе с подобными редакторами - ниже описана структура любой графической новеллы в терминах языка RenPy, а также назначение каждой команды.

Кроме того, при создании нового проекта RenPy создает не пустой файл, а стандартную сцену, которая может быть основой для Ваших первых работ.

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

Основными конструкциями в RenPy являются:

  • label имя_метки - место в коде, к которому в последствии можно перейти при помощи команды jump имя_метки
  • scene - команда загрузки фонового изображения из папки images созданного проекта. Важно знать: в случае смены фона требуется заново ввести команду по выводу изображения персонажа.
  • show - отобразить картинку (чаще всего - персонажа) поверх существующего фона.
  • say - фраза, произносимая персонажем. Чаще всего используется в следующих форматах:Вариант первый: "автор" "фраза" - здесь мы явно указываем, кто говорит фразу и как эта фраза звучит.Однако, для удобства пользователя есть возможность упростить свою жизнь, заранее указав имя автора.Для этого перед меткой начала игры применяется следующая конструкция:define anna = Character("Anna:")В дальнейшем достаточно написать anna "фраза", что будет воспринято системой как "Anna:" "фраза"Важно понимать, что нет прямой связи между показываемой картинкой (show) и автором фразы - кроме той, которая формируется у игрока в процессе игры.
  • menu - выбор игрока, в зависимости от которого происходит выполнение соответствующего кода, будь то простая фраза либо переход к конкретной метке.

Итак, что же происходит в первом фрагменте кода?

1) мы выводим на экран сцену "bg 1" из папки images нашего проекта
2) от имени игрока (define char = Character("Я:") перед label start) выводим фразу "Интересно, где же кубик?"
3) плавно (with dissolve) выводим на экран изображение "cube wow"
4) от имени кубика (строка define e = Character("Кубик:") перед label start) выводим фразу "А вот он я!"
5) после обмена фразами мы переходим к новой для нас команде - menu, отвечающей за выбор игрока и реакцию игры на этот выбор.

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

Ничего сложного, согласитесь? Требуется лишь следовать правилам составления сцены и корректно вводить команды.

У тех, кто был внимателен при прочтении нашего "сценария", может возникнуть вопрос: а как нам определить, хорошо или плохо заканчивается игра? Всё верно, при помощи команды menu мы можемпредоставить выбор игроку, а в данной ситуации требуется противоположное - сделать выбор на основе данных самой программы.
С этой целью мы добавляем в игру типичный для программ элемент -переменную под названием "answers" и устанавливаем её значение равным нулю.

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

В дальнейшем, при выборе игроком положительного (правильного) ответа, мы увеличиваем значение этой переменной следующим образом:

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy

Таким образом, после трех вопросов её значение находится в диапазоне от 0 (если не было дано ни одного правильного ответа) до 3 (если все ответы были правильными).
Будем добрыми, и поставим простое условие: отгадал хоть одну загадку - добро пожаловать на прогулку. Для этого нам потребуется конструкция if-else, "если-иначе". Ниже - пример её применения в нашей новелле:

Если больше 1 правильного ответа - переходим к метке good ending; иначе - к метке sad_ending
Если больше 1 правильного ответа - переходим к метке good ending; иначе - к метке sad_ending
Обратите внимание - каждая из меток заканчивается переходом к метке "конец истории". В противном случае возможен последовательный показ обеих сцен, что будет выглядеть.. довольно странно.
Обратите внимание - каждая из меток заканчивается переходом к метке "конец истории". В противном случае возможен последовательный показ обеих сцен, что будет выглядеть.. довольно странно.

Итоги

Одна из двух возможных концовок.
Одна из двух возможных концовок.

Итак, мы создали новеллу, в которой присутствует как локальная (не влияющая на концовку), так и глобальная (определяющая финал истории) вариативность.

Было ли это сложно? Нет - у человека, ранее не работавшего с движком, подобная задача займет не более, чем два часа. Поиграть с Кубиком из нашего примера можно на ПК:

И на Android устройствах:

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

К примеру, в Spiritual Cavern на текущий момент присутствует порядка 1200 строк кода, реализующих первые шесть сцен игры - и, если бы не грамотная организация процесса, я давно потерялся бы в этих дебрях.

А о том, как стоит и не стоит организовывать процесс воплощения новеллы мы поговорим в следующей статье, которая выйдет в Воскресенье. Всем удачи, и приятных выходных!

Визуальная новелла, интерлюдия: создание разветвленного сценария силами RenPy
2222
10 комментариев

Дико интересен подход к организации разработки, ибо после первый 1000 строк кода лично мне было сложно ориентироваться где, что и куда должно срабатывать :)

1
Ответить

Я веду таблицу с сюжетными ветками для каждого "сценария" - сцены от начала и до концовки: название метки в RenPy, из какой метки происходит переход, суть метки и название файла с фоном (опционально, но мне так удобнее).
В коде оставляю комментарии, чтобы открыв код после выходных не потеряться в бездне сцен.
Ну и правило: код после каждой метки выполняет переход к другой/другим меткам.
В итоге получается довольно удобная система)

1
Ответить

Комментарий недоступен

1
Ответить

Рад, что статья оказалась полезной) Удачи в Вашем начинании!

Ответить
Комментарий удалён модератором

RenPy настолько профессионально скрывает аспекты создания кода, что для создания простых новелл достаточно прочитать Quick Start Guide на их сайте: https://www.renpy.org/doc/html/quickstart.html
Кроме того, обучающих материалов конкретно по основам создания новелл в RenPy более чем достаточно. Зачем плодить сущности?
Это только моё ИМХО, прошу заметить.

2
Ответить