Как создать визуальную новеллу с нуля
Как создать визуальную новеллу с нуля
Киногад
Все, что вы хотели знать о кино…
Гид по созданию визуальных новелл. Часть 1
Данный материал является вольным переводом английской статьи, появившейся на сайте Fuwanovel в 2015 году. Начинающим авторам можно использовать его как инструкцию или подсказку, облегчающую нелегкий процесс творчества. Рассказ ведется от лица автора довольно популярной бесплатной новеллы «Lucid9: Inciting Incident», которую каждый легко может найти и опробовать в Steam.
Итак, вы решили сделать визуальную новеллу…
Стоит ли мне встревать в эту затею?
Значит, вы только-только закончили читать новеллу от студии KEY, тотчас ставшую вашей любимицей, или вас поразила до глубины души G-senjou, или вы в восторге от Steins;Gate… Вы также наслышаны о «Katawa Shoujo» и о том, как к ее созданию была причастна любительская братия анонимов с 4chan… И внутренний голос шепчет вам на ухо: “Я тоже хочу сочинить историю!” Как кстати, что в вашем списке дел на этот год поставлено четкое задание — сделать что-то свое…
В то время как многие решат проигнорировать искушение, некоторые смельчаки захотят взяться за дело. Тогда-то вы впервые и зададите себе вопрос: «А стоит ли тратить на это время?».
Я говорю только, основываясь на собственном опыте, но мой ответ будет положительным. Процесс создания безусловно отнимет немало времени, но усилия того стоят и по завершению вы получите незабываемый опыт. На пути к свершению вы, вполне вероятно, обретете новых знакомых, ощутите неимоверную гордость и удовлетворение от проделанной работы.
Однако, достижение финальных титров — привилегия меньшинства. Только самого упертого, а еще важнее, наиболее организованного. И моя задача — помочь вам разобраться в том, как запустить и правильно подготовить проект мечты.
Почему Визуальные Новеллы?
Вам не потребуются серьезные знания программирования. Всего лишь с помощью спрайтов, фонов, музыки вы можете изобрести очень трогательные вещи. Говоря проще, вам не нужны деньги, чтобы сделать новеллу. При должных усилиях и эффективной команде качество вашей игры не уступит даже коммерческим проектам. (пример «Katawa Shoujo»). Визуальные новеллы на Западе — это растущий рынок и, если соблюсти все требования, при должной толике удачи, вы вполне можете заработать, официально издав свое детище. Разработкой новелл занимаются совершенно разные люди, вы также в состоянии уделять этой затее лишь свободное время, если правильно организуете рабочий процесс.
Вопрос о масштабе вашего проекта
Что же, вы окончательно решили пересечь черту и войти в ряды разработчиков\творцов. Вас обуревают чувства надежды и большим амбиций, вы заряжены на успех и готовы свернуть даже горы! Это хороший настрой, но не стоит торопиться, ведь теперь вы стоите перед развилкой:
От себя хочу посоветовать придерживаться первой опции, пусть даже второй вариант облегчит вам поиски соратников, но, вполне возможно, вызовет последующие разногласия внутри коллектива. Разработка игр — тот самый случай, когда демократия приносит только вред. Позже я также затрону вопросы оплаты и краудфандинга, но, так как я не имею серьезного опыта в этой области, мои слова не стоит принимать как истину в последней инстанции.
Маленький, средний или большой проект?
Это самый первый аспект, на котором нужно заострить внимание до набора кадров и непосредственного создания контента. Фактически на этом этапе будет определено, какое именно участие потребуется от каждого вовлеченного в разработку. Следует держать в уме тот факт, что чем длиннее будет новелла, тем больше объем работ, а не все горят желанием тратить свое свободное время на протяжении многих месяцев и лет.
Если вы планируете создать короткую новеллу (2-3 часа на чтение, например), это займет несколько месяцев. Если вы думаете создать средней длины новеллу (10-15 часа на чтение), это затянется не меньше, чем на год. Если вы рассчитываете создать длинную новеллу (20 часов на чтение и больше), это отнимет годы, по меньше мере 1,5 — 2, если вам повезет.
Столь важный параметр нужно определить сразу, и вам придется довести окончательный выбор до остальных участников проекта, дабы убедиться, что каждый из них в готов остаться до самого конца.
Статус вашей визуальной новеллы
Некоторые люди придумывают новеллу хотения ради и просто стремятся поделиться плодами своего творчества с другими индивидуумами, по большей части выпуская бесплатные игры. Вполне себе нормальное решение. Однако есть и те, кто полагает, что неплохо было бы заработать на своем увлечении. И это тоже естественно. Прибавим к списку еще возможность использовать краудфандинг платформы.
Позвольте мне просуммировать различные преимущества и недостатки каждого подхода.
а) “Я хочу выпустить бесплатную игру, без финансовой поддержки.”
Пример: Katawa Shoujo
Это означает работать на одном вдохновении, без оплаты или дополнительной комиссии. Останавливаясь на этом, нельзя забывать, что наиболее талантливые художники или композиторы не готовы предоставлять свои услуги безвозмездно, однако найти таких уникальных людей и привлечь к вашему проекту реально, если он покажется им достаточно интересным.
Вам придется искать таких же увлеченных личностей, как и вы, готовых жертвовать своим временем на что-то, что вряд ли озолотит их в будущем. Скорее всего, вам удастся найти единомышленников и сколотить команду, однако, если их желание угаснет, будет не так-то просто сдержать их от ухода.
По моему скромному мнению, именно в проектах такого типа вы, без сомнения, встретите много новых персоналий, разделяющих ваши стремления и грезы, имеющих схожие амбиции и склад ума, и, в конечном итоге, подружиться с ними в жизни.
б) “Я хочу выпустить бесплатную игру с помощью краудфандинга”
Уверен, вам известно более чем достаточно примеров визуальных новелл, выпущенных с финансовой поддержкой краудфандинг платформ (Fig, Kickstater, Indiegogo, Patreon), сама по себе это не плохая идея, которая может серьезно подсобить вашему проекту, но только в том случае, если вы правильно подготовите компанию по сбору средств. Вам потребуется огромные усилия при планировании и организации, вы должны будете составить смету и создать игровую страничку, которая сможет привлечь желающих пожертвовать. Наилучшим вариантом будет сначала собрать команду, узнать об их желаемом вознаграждении и на основе этого сосчитать бюджет, и, пока вы набираете людей, стоит попросить их о рекламных материалах для вашей игры. В интернете немало полезных статей на счет того, как провести успешный сбор средств, так что обратите на них внимание, а еще лучше возьмите за пример успешные компании для других визуальных новелл.
Весомым плюсом в денежной подпитке является то, что вы способны сделать более качественную игру и привлечь к разработке искусных творцов.
в) “Я хочу создать коммерческий продукт”
Пример: практически каждая вторая новелла в Steam.
Тут перед вами опять возникает выбор:
Использовать краудфандинг: примерно все то же, что было сказано выше с тем исключением, что люди, работающие с вами над игрой, могут попросить о своей доле с будущих продаж. Данный нюанс потребует грамотной координации и урегулирования юридических формальностей, но в далекой перспективе это довольно рациональный ход, если вы планируете самостоятельно разрабатывать новеллу или создать фонд для превращения вашего сообщества энтузиастов в настоящую независимую игровую студию.
Не использовать краудфандинг: Если у вас уже имеется капитал то ли от продаж предыдущей игры, то ли из посторонних источников, и вы готовы оплачивать труд из своего кармана, то, пожалуй, это наиболее простой способ привлечь внимание народа к своему проекту, так как люди в данном варианте гарантировано получат свои деньги. Если же у вас нет финансовых сбережений или вы просто делаете ставку на коммерческий успех новеллы, то ваша ситуация фактически такая же, как если бы вы выпускали бесплатную игру: много людей могут не захотеть ждать так долго, надеясь на хорошие продажи, особенно в опасении, что проект может быть не доведен до финала.
Какой тип истории?
Итак, самое время решить, о чем вы хотите написать. Так вы определите будущий жанр вашей игры:
Все вышеперечисленное требует мозгового штурма, который займет определенное время, но, знание направление движения позволит вам не заплутать на полпути.
б) На чем делать акцент: на сюжете или персонажах?
Весьма интересный вопрос, не имеющий четкого ответа, так как он зависит от типа визуальной новеллы, которую вы хотите создать. Если вы рассчитываете сделать чараге или моэге, то логичным шагом будет создание персонажей, рисование фонов и прочее, а уж потом перенос их в историю, которую вы сочинили.
Но если вы поставили за цель создание сюжетной игры, тогда важнее на первых порах придумать сеттинг, решить, что за сюжетные повороты вы хотите в него включить, а также героев, как движущую силу всей истории, и уж потом рассуждать на тему фонов и характеров, которые могли бы вам подойти.
Движок, скриптовый язык и визуальная новелла — за 45 часов
Приветствую. Так получилось, что уже три года подряд в качестве подарка на Новый год определенным людям я делаю игру. В 2018-ом году это был платформер с элементами головоломки, о котором я писал на хабре. В 2019-ом — сетевая RTS для двух игроков, о которой я ничего не писал. И наконец, в 2020-ом — визуальная новелла, о которой далее и пойдет речь, созданная в условиях сильно ограниченного времени.
Интересно? Тогда добро пожаловать под кат.
Осторожно: тут много текста и
0. Обоснование разработки движка.
Примечание: Если вам по каким-то причинам неинтересны технические подробности, можете переходить сразу к п. 4 «Разработка игры», однако Вы пропустите основную часть контента
0. Обоснование разработки движка
Разумеется, существует огромное количество готовых движков для визуальных новелл, которые, без сомнения, по всем пунктам лучше нижеописанного решения. Однако каким бы программистом я был, если бы не написал еще один. Поэтому давайте сделаем вид, что его разработка была обоснована.
1. Выбор платформы
Выбор, собственно, был невелик: либо Java, либо C++. Недолго думая, я решил реализовывать задуманное на Java, т.к. для быстрой разработки она даёт все возможности (а именно: автоматическое управление памятью и большую, по сравнению с C++, простоту, которая скрывает много низкоуровневых деталей и, как следствие, позволяет меньше акцентировать внимание на самом языке и думать только о бизнес-логике), а также обеспечивает поддержку окон, графики и аудио из коробки.
Для реализации графического интерфейса был выбран Swing, так как я использовал Java 13, где JavaFX уже не входит в библиотеку, а добавлять в зависимости десятки мегабайт OpenJFX было лень. Возможно, это было не лучшим решением, но тем не менее.
Вероятно, возникает вопрос: что это за игровой движок, да без аппаратного ускорения? Ответ заключается в отсутствии времени для борьбы с OpenGL, а также абсолютной её бессмысленности: для визуальной новеллы неважен FPS (во всяком случае, с таким количеством анимации и графики, как в данном кейсе).
2. Архитектура движка и его реализация
2.1 Постановка задачи
Для того чтобы решить, как что-либо делать, нужно определиться с тем, зачем это делать. Это я о постановке задачи, т.к. архитектура не универсального, а «домен-специфичного» движка по определению напрямую зависит от задумываемой игры.
Под универсальным движком я понимаю движок, поддерживающий относительно низкоуровневые понятия, типа «Игровой объект», «Сцена», «Компонент». Делать было решено именно не универсальный движок, потому что это значительно сократило бы время разработки.
По задумке, игра должна была состоять из следующих частей:
Т. е. имеется фон для каждой сцены, основной текст, а также текстовое поле для пользовательского ввода (визуальная новелла задумывалась именно с произвольным пользовательским вводом, а не выбором из предложенных вариантов, как это часто бывает. Позже я расскажу, почему это было плохим решением). Также на схеме показано, что в игре может быть несколько сцен и, как следствие, между ними могут осуществляться переходы.
Примечание: Под сценой я понимаю логически выделенную часть игры. Критерием сцены может служить одинаковый фон на протяжении этой самой части.
Также среди требований к движку была возможность воспроизведения аудио и показа сообщений (с опциональной функцией пользовательского ввода).
Пожалуй, самым важным желанием было желание писать логику игры не на Java, а на каком-нибудь простом декларативном ЯП.
Также было желание реализовать возможность процедурного анимирования, а именно элементарного движения изображений, при этом чтобы можно было на уровне Java определять функцию, по которой считается текущая скорость движения (например, чтобы график скорости был прямой, либо синусоидой, либо ещё чем-то).
По задумке, всё взаимодействие с пользователем должно было производиться через систему диалогов. При этом диалогом считался не обязательно диалог с NPC или что-то подобное, а вообще реакция на любой пользовательский ввод, для которого был зарегистрирован соответствующий обработчик. Непонятно? Скоро станет яснее.
2.2. Архитектура и реализация
Учитывая всё вышесказанное, можно поделить движок на три относительно большие части, которые соответствуют одноимённым java-пакетам:
В данном пункте я рассмотрю первые две части. Начну со второй.
Файловая структура квеста следующая:
Имеется отдельная папка для квеста, в корне которой лежит манифест, а также три дополнительные папки: audio — для звукового сопровождения, graphics — для визуальной части и scenes — для скрипто, описывающих сцены.
Хотелось бы в двух словах описать манифест. Он содержит следующие поля:
Стоит отметить, что во время инициализации дисплея, помимо всего прочего, происходил расчёт разрешения рендеринга: т. е. бралось требуемое разрешение из манифеста и ужималось в доступное для окна пространство так, чтобы:
Также при инициализации дисплея скрывается курсор, так как в игровом процессе он не участвует.
В двух словах о консоли разработчика. Она была разработана по следующим причинам:
На этом описание инициализатора и связанных вещей заканчивается, и можно переходить к описанию дисплея.
Его финальная структура имеет следующий вид:
Из постановки задачи можно сделать вывод, что всё, что придется делать, — это рисовать изображения, рисовать текст, воспроизводить аудио.
В моем случае было решено поступить немного по-другому. Так как для визуальных новелл текст и изображения имеют относительно перманентный характер, а также являются почти всем, что видит пользователь (то есть достаточно важны), они были сделаны, как игровые объекты — то есть такие вещи, которые нужно лишь заспаунить и они не исчезнут, пока их не попросишь. К тому же данное решение упрощало реализацию.
Объект (с точки зрения ООП), который описывает текст/изображение, назовём дескриптором. То есть для пользователя API движка существуют лишь дескрипторы, которые можно добавить в состояние дисплея и удалить из него. Таким образом, в финальном варианте дисплея имеются следующие дескрипторы (они соответствуют одноименным классам):
Дисплей содержит также поля для текущего приемника ввода (дескриптора ввода) и поле, указывающее на то, какой текстовый дескриптор сейчас имеет фокус и чей текст будет скроллиться при соответствующих действиях со стороны пользователя.
Игровой цикл выглядит примерно так:
Примечание: Возможно, возникает вопрос «Зачем рендерить поля для ввода, если для них созданы соответствующие текстовые дескрипторы, которые рендерятся на шаг раньше?» На самом деле рендеринга в пункте 7 не происходит — происходит лишь синхронизация параметров InputDescriptor ‘а с параметрами TextDescriptor ‘а — такие как видимость на экране, позиция, размер и другие. Это было сделано, как указывалось выше, по той причине, что пользователь не управляет напрямую соответствующим дескриптору ввода дескриптором текста и вообще о нём ничего не знает.
Стоит отметить, что задание размеров и позиций элементов на экране происходит не в пикселях, а в относительных размерах — числах от 0 до 1 (схема ниже). То есть вся ширина для рендеринга — это 1, и вся высота — это 1 (причем они не равны, о чем я несколько раз забыл и позже пожалел). Также стоило бы сделать, чтобы (0,0) был центром, и ширина/высота были равны двум, но я почему-то про это забыл/не подумал. Однако даже вариант с шириной/высотой равной 1 упрощал жизнь разработчику квестов.
Пару слов о системе освобождения памяти.
При её инициализации она как раз и добавляет в дисплей дескрипторы для фона, текста и т. д. Также она умеет показывать сообщения с опциональными иконкой, полем ввода и колбэком.
Тут всплыл небольшой баг, полное исправление которого потребовало бы переделывания половины системы рендеринга: если посмотреть на порядок отрисовки в игровом цикле, видно, что сначала рисуются изображения и только потом текст. В то же время, когда тулкит показывает изображение, он располагает его посередине экрана по ширине и по высоте. И если текста в сообщении достаточно много, то он должен частично перекрывать основной текст сцены. Однако так как фон сообщения — это изображение (полностью черное, но тем не менее), а изображения отрисовываются до текста — то один текст накладывается на другой (скриншот ниже). Проблема была частично решена вертикальным центрированием не по экрану, а по области над основным текстом. Полное решение включало бы в себя введение параметра глубины и переделывание рендереров от слова «совсем».
3. Скриптовый язык
Примечание: Если уважаемый %USERNAME% дочитал досюда, то он молодец, и я попросил бы его не бросать это делать: сейчас будет значительно интересней, чем было до этого.
3.1. Язык
Изначально хотелось сделать декларативный язык, в котором нужно было бы лишь указать все необходимые параметры для сцены, и всё. Всю логику бы на себя брал движок. Однако в итоге я пришёл к процедурному языку, даже с элементами ООП (едва различимыми), — и это было хорошим решением, так как, по сравнению с декларативным вариантом, давало возможность многократно большей гибкости игровой логики.
Синтаксис языка продумывался так, чтобы быть максимально простым для парсинга, что логично, учитывая количество имевшегося в наличии времени.
Итак, код хранится в текстовых файлах с расширением SSF; каждый файл содержит описание одной либо больше сцен; каждая сцена содержит ноль или больше действий (action); каждое действие содержит ноль или больше операторов.
Возможно, вы жаждете увидеть наконец исходный код на SL, вот он:
Теперь становится ясно, что такое оператор. Видно также, что каждое действие есть блок высказываний (statement) (при этом высказыванием может быть и блок высказываний), а также то, что поддерживаются однострочные комментарии (вводить многострочные не имело смысла, к тому же я и однострочными не пользовался).
Ради упрощения такое понятие, как «переменная», в язык не вводилось; как следствие, все значения, используемые в коде, — литералы. В зависимости от типа выделяются следующие литералы:
Название литерала: | Примечание: |
---|---|
Строковый литерал | Возможность экранирования кавычек и слешей (\\) прилагается, также есть возможность вставить в текст перенос |
Целочисленный литерал | Поддерживает отрицательные числа |
Литерал с плавающей точкой | Поддерживает отрицательные числа |
None-литерал | В коде представлен как none |
Булев литерал | В коде — on / off для истины/лжи соответственно |
Общий литерал | Если литерал не подпадает ни под один из вышеперечисленных типов и состоит из букв английского алфавита, цифр и знака нижнего подчеркивания, он общий литерал. |
Пару слов про парсинг языка. Имеется несколько уровней «загрузки» кода (схема ниже):
Теперь вкратце об операторах, чтобы появилось представление о функциональности языка. Изначально имелось 11 операторов, затем в процессе продумывания игры некоторые из них слились в один, некоторые изменились, и добавилось ещё 9 штук. Вот сводная таблица:
Операторы для работы со счётчиками — специфичными для сцены целочисленными переменными.
Была также мысль ввести оператор return (на уровне ядра интерпретатора даже была добавлена соответствующая функциональность), однако я забыл, да он и не пригодился.
В загрузчик скриптов встроено не так много проверок на правильность SL-программы, как хотелось бы. Например, всё, что может выброситься на этапе загрузки скрипта, — это исключение о непредвиденном либо неизвестном токене. Во времени исполнения ситуация лучше: есть проверки на типы аргументов операторов (да-да, операндов), на их количество, на наличие запрашиваемой сущности во время lookup ‘а, возможно, и другие, не помню. Однако нет таких проверок времени загрузки, как вызов только существующих действий или использование только существующих сцен в goto и lookup ‘ах, а также проверки типов аргументов и многих других.
В первую очередь из-за нехватки времени и во вторую — из-за того, что анализаторы всех операторов сделаны через базовый анализатор, который умеет только брать из потока n токенов (представляющих аргументов) и строить объект оператора. При этом никакой проверки на типы аргументов или правильность их содержания не производится, потому что анализатор знает только, что ему нужно забрать из потока n токенов и всё. Проверка происходит позже, в рантайме.
Кратко о диалогах. Приведу синтаксис оператора добавления диалога:
Как я прочитал в википедии, очень важной частью любого движка для визуальных новелл с произвольным пользовательским вводом является анализатор ввода на естественном языке. Разумеется, я решил несколько упростить задачу: игра реагировала не на смысл, заложенный во фразе, а лишь на форму самой фразы, которая задавалась регулярным выражением (схема ниже).
Таким образом, если пользователь вводил текст, который совпадал с одним из регулярных выражений (первый аргумент) одного из включенных (последний аргумент) диалогов данной сцены, то выполнялся колбэк (третий аргумент). Для упрощения регулярных выражений пользовательский ввод подвергался следующей обработке: один и более пробельных символов заменялись на один пробел, боковые пробельные символы удалялись, текст переводился в нижний регистр, «ё» заменялось на «е».
Возможно, стоило сделать ещё удаление знаков препинания (знаков вопроса, в частности)
Пример регулярного выражения для диалога, обозначающее «осмотреться»:
Учитывая всё вышесказанное, можно увидеть аналогию с ООП: сцены — классы, все члены которых статичны и публичны, а действия — методы.
Полагаю, в максимальном упрощении языка был и плюс: порог вхождения в него очень низок
3.2. Интерпретатор
Рассказывать про сам интерпретатор особо нечего: он тоже модульный, модули — это «исполнители» операторов (по одному для каждого). Больший смысл имеет рассказать про специальные действия и смену состояний дисплея.
Для самого SL специальных действий не существует, но для интерпретатора они все-таки есть. Вот они:
Примечание: init и first_come — вместе составляют некое подобие конструктора, что ещё раз намекает на легкий объектно ориентированный оттенок языка.
Это состояние состоит из состояния дисплея и состояния тулкита (обертки, которая добавляет понятие «фон», «основной текст», «поле для ввода» и т. д.). Стало понятно, что нельзя просто выбрасывать эти состояния, а их где-то надо хранить и как-то заменять. Проблема была в том, что все дескрипторы дисплея и тулкита хранились прямо в классах их представляющих (в полях), а сохранять вручную с десяток объектов никоим образом не хотелось.
На помощь пришла композиция и выделение состояния дисплея и тулкита в отдельный класс (что, вероятно, нужно было сделать сразу). Оставалась одна проблема: каким образом заменять состояния с текущего на старое? Ведь нельзя же во время игрового цикла, а именно во время итерации по спискам дескрипторов, просто взять и заменить эти списки. Поэтому тут пришлось добавить метод provideState в дисплей, в который передавался колбэк и состояние для загрузки; а после завершения очередной итерации игрового цикла это состояние заменялось и вызывался колбэк, в котором происходила замена состояния тулкита.
Ещё был нюанс с остановкой воспроизведения аудио, да так, чтобы само аудио не подумало, что оно было полностью воспроизведено, и не самоуничтожилось (так как оно автоматически очищается, если было полностью проиграно), но это решилось введением пары методов и флагов (которые, вероятно, были избыточными и заменялись уже существующими, но это не точно).
4. Разработка игры
Тут я кратко опишу саму игру и процесс её разработки. Как в 2019-м и 2018-м, я решил начать с чего угодно, кроме графики, и начал с истории.
4.1. История и разработка логики игры
Так как разрабатывалась визуальная новелла, самое важно, что было в игре, — это история. Она была написана по лавкрафтовским мотивам и рассказывала про приключения пережившего кораблекрушение человека, попавшего на очень даже обитаемый остров. В истории было разветвление сюжета (с двумя концовками), один явный и несколько скрытых вотэтоповоротов, четыре полдесятка персонажей с разветвленными кое-где диалогами, 9 локаций (сцен), на каждой можно было найти что-то интересное (не влияющее на сюжет, но дающее немного подробностей (а иногда, наоборот, вопросов) о происходящем.
Стоит сказать, что игра линейная: игрок не сможет пойти туда, куда игра не хочет в данный момент, однако сможет позже, когда игре это будет надо. Отчасти это было сделано для уменьшения количества возможных вариантов развития событий, благодаря чему разработка становилась проще и быстрее, а количество возможных багов снижалось.
Как оказалось, для разработки задуманной игры мне не понадобилось 25% (5) существующих операторов, а именно: все операторы, связанные со счётчиками; оператор анимирования ( animate ), а также оператор внешнего вызова ( call_extern ).
Помимо основной игры, для ознакомления игроков с кор-механиками игры был разработан демоуровень (скриншот ниже), который состоял из одной сцены (двух, если быть точным, но вторая — просто заглушка, типа «You won»).
4.2. Графика
Во время разработки логики и тестирования вместо изображений использовались заглушки, как видно на скриншоте ниже:
Как видно по изображению до ката, рисование не моя стихия, однако нужно было как-то обеспечить хоть какую-то графику на уровне «не отвратительно». Достигнуть его помогли следующие условия:
5. Статистика и итоги
На разработку первой версии движка и языка (с 11 операторами) у меня ушло 30 часов 40 минут. На реализацию дополнительных 9 операторов ушло ещё 4 часа 55 минут. Разработка логики непосредственно игры (вместе с демо) потребовала 7 часов 41 минуты. Рисование графики —
4-6 часов (графика не учтена в 45 часах из заголовка).
Примечание: Время кодинга мерялось через расширение «Darkyen’s Time Tracker» для продуктов JetBrains (абсолютно не реклама).
Примечание: Я начал писать это все за 2 дня до Нового года, но не успел — релиз пришлось перенести на Рождество. Так что 45 часов из заголовка были распределены примерно на 8 дней.
Количество чистых строк кода для движка: 4777, для игры (без демо) — 637.
Целью было создать 30 минут игрового времени. В итоге прохождение (с моими подсказками) заняло: демо —
8 минут, основная игра на первую концовку —
24 минуты, на вторую (с быстрым прохождением до момента разветвления) —
8 минут. То есть план был выполнен.
Размер квеста — 232 мегабайта (так много из-за музыки, записанной в WAV).
Было нарисовано 28 изображений (и ещё 3 для демо). Это была моя первая игра с адекватным аудио сопровождением — всего с просторов интернета было скачано и запихнуто в игру 17 единиц звуков/музыки.
Все жалобы на игру заключались в абсолютно не юзер-френдли интерфейсе ввода: очень часто регулярные выражения не покрывали вводимых фраз, хотя смысл этих фраз был более чем верный. То есть, например, игрок вводил «вставить ключ в дверь», а предусмотрено было лишь «вставить ключ». Однако были и моменты (один, насколько я помню), когда пользовательский ввод с первого раза совпадал с задуманным (и это было даже не «да»/»нет» или что-то очевидное).
Очевидное решение — просто выдавать игроку список вариантов того, что он может сделать. Но тут есть и очевидная проблема: вся игра сведется к методичному прокликиванию всех вариантов. Скучно. Поэтому, в итоге после обсуждения был сделан вывод, что максимально приятным и не слишком «открытым» интерфейсом был бы следующий: варианты диалогов даются лишь при диалогах с NPC, а действия с миром производятся мышью, путем клика на определенные участки экрана (например, нажать на куст — обыскать его и т.д.).
Также я считаю, что не смог адекватно раскрыть историю: остались недосказанности, непонятные моменты и даже маленькие противоречия.
Теперь к коду. В целом качество кода меня устраивает (хотя это ещё ни о чём особо не говорит), однако есть следующие моменты:
Кстати, во время игры багов выявлено не было и всё отработало без единого краша, что приятно.
Исходный код движка может быть найден по данной ссылке на GitHub.
Демо и основная игра находится в файлах (assets) в разделе «Releases» для версии «v1.0» там же.
Как создать визуальную новеллу с нуля
__ __ __ __ __ __ __ __
Начните с выбора жанра. Подумайте, будет ли ваша новелла ужастиком, или может симулятором свиданий с хентай сценами? От жанра зависит целевая аудитория новеллы (возраст, пол, люди, принадлежащие к каким-либо обществам и т.п.) Лично я делаю новеллу для подростков и детей моего возраста (11-16 лет). Выбрал я жанр, как вы поняли квест, психология и повседневность. Так же немного хоррора.
Далее придумайте, о чём повествует ваша новелла? Придумайте сеттинг, в котором будут происходить действия. Продумайте его тщательно, ибо музыка, графика и прочие элементы игры подстраиваются под сеттинг, чтобы создать атмосферу.
Когда будет достаточно идей, приступайте к персонажам.
Совет: предлагаю начать с новеллы по мотивам какого-либо произведения, например, книги, фанфика, аниме, манги, даже театральной пьесы! Это поможет не морочиться с придумкой некоторых элементов, что удобно, если вы делаете новеллу в первый раз.
Как вы наверное заметили, персонажи в новеллах очень разнообразны и контрастируют между собой. Например беспечная Ульяна и ответственная Славя, или робкая Лена и смелая, бойкая Алиса. Придумайте побольше самых разных персонажей, особенно, если это симулятор свиданийг, или эроге. На выбор но в таком случае будет несколько персонажей, среди которых он может выбрать кого-то и выйти на его рут. Можно также добавить популярных клише, типо родственницы, лоли, лучшая тян в классе, староста тян, можете даже трапа туда закинуть) Главное, чтобы персонажи были раскрытыми и реагировали на ситуацию по разному.
Вам нужно хорошо продумать сценарий, прежде чем приступать к программированию. Продумайте, какой будует концовка, или концовки, с чего всё началось, как героя можно привести от начала до этих концовок. Как другие персонажи реагируют на выбор гг. Всё это очень важно для сюжета.
На свете есть множество удобных движков для создания визуальных новелл, правда большинство из них японские. Вот некоторые движки, которые наиболее известны в интернете:
KiriKiri Adventure Game System
Факт: Такие новеллы, как Тук тук литературный клуб, или Бесконечное лето были сделаны на движке ренпай.
Как наверное уже многие заметили, почти ВСЕ новеллы имеют анимешную графику. Поэтому, если хотите иметь прямо очень новельную графику, вам придется научиться рисовать японские мультики. Или же пойти по моим стопам и отклониться от традиции. Я например рисую новеллу в своём стиле (векторный мультяшный лайн-арт мышкой :3).
Итак, что вам придется отрисовывать? Все игровые элементы, элементы меню, настроек, самой игры на всём её протяжении. Всех персонажей, по нескольким эмоциям на каждого. Также множество фонов. В общем, работы много, но графика есть графика.
Кстати, я рисую в sai2.
Да, конечно написать самому музыку, когда тебе на ухо наступил медведь проблематично, но если ты знаешь базовые вещи, например строения тонического, субдоминантного и доминантного аккорда, или из чего состоит простейший бит. Есть множество удобных программ, таких как caustic, fl studio и подобные. Лично я пользуюсь именно ими)
Вам нужно написать большое количество треков, на разные моменты игры. Они должны быть разными по характеру, чтобы их можно было везде распихать. Звуки можно брать с сайтов с бесплатными звуками (не поверите, но все звуки из БЛ взяты с таких сайтов).
Как я создавал на Unity свою визуальную новеллу «Только Один»
Пожалуй, как и при написании любого другого текста, самое тяжелое — это первые строки, поэтому вместо них пусть будет лицо одного из героев моего проекта «ТОЛЬКО ОДИН».
Изначально этот сюжет я писал в качестве сценария короткометражки для одного начинающего кинопродюсера. Он сразу сказал, что ему нужна история, которая будет от начала и до конца проходить в одной тёмной комнате, в которой стоит стол, несколько стульев и в кадре должно быть не более 4-х действующих лиц, при этом не важно что будет в этой комнате происходить.
Обожаю подобные вызовы, поэтому спустя пару недель мой оригинальный сценарий был готов. А когда я его опубликовал на специальном сайте для сценаристов, то ко мне обратились ещё двое молодых режиссеров ВГИКА, которым нужен был хороший сценарий для курсовой работы.
Итого, за месяц у меня было 3 предложения от трех киноделов снять эту короткометражку и даже отправить её на фестиваль, но для каждого из них нужны были «небольшие» корректировки сюжета. Как вы поняли, корректировки там были совершенно противоположны слову «небольшие». Они все уводили историю совершенно не в те стороны, которые видел я, и полностью меняя финальный посыл в конце истории. А ведь весь упор сюжета был на необычном сюжетном твисте в самом конце.
Я мог просто продать эту историю любому из них и имел бы в своём портфолио снятую короткометражку, но в какой-то момент внутри меня проснулся упертый творец и я понял, что не хочу этого делать.
Поскольку я уже продолжительное время пишу сценария для одного крупного консольного игрового проекта, то решил, что этот сюжет очень хорошо подойдет для небольшой, довольно линейной, визуальной новеллы для мобильных телефонов — ни средств, ни ресурсов, ни собственно желания для того, чтобы делать более крупный проект, у меня не было, и я сразу решил, что это будет не продолжительная, камерная история с небольшой вариативностью вопросов/ответов и одним единственным вариантом концовки, который я, собственно, и защитил от начинающих киноделов.
Я сразу решил, что создавать проект буду на движке Unity — выбор был между ним и UE4, где тоже есть готовые темплейты визуальных новелл, но Unity мне просто больше нравится своей простотой.
В качестве основы я взял супер простой, но очень подходящий для моего проекта VNcreator:
Сюжет у меня уже был, но мне требовались герои и бэкграунды. А поскольку рисую я чуть хуже, чем конь танцует на льду, то я решил схитрить: я строил нужные мне декорации сцены прямо в сцене Unity при помощи лоу=поли ассетов, делал скрин и вставлял его вместо бекграунда.
Тоже самое я сделал и с главными действующими героями проекта — я выставлял виртуальную камеру перед ними так, чтобы они выглядели, как обычные персонажи в визуальных новеллах, а потом обрезал их в фотошопе, оставляя только нужный контур.
Разработка визуальной новеллы в одно лицо. Слабоумие и отвага или история успеха?
Всем привет. Слабоумный и отважный автор статьи — это я, меня зовут Паша.
Сразу хочу сказать, какие цели преследует эта статья. Во-первых, она должна рассказать о том, как я делал свою игру (с целью какого-никакого пиара, разумеется)). А во-вторых, я хочу спросить совета у пользователей — как можно её попиарить? Сама игра скоро выходит в стиме, а у меня закончились идеи, как это делать(
Вот что получилось в итоге.
Но давайте по порядку. История создания визуальной новеллы в одно лицо.
Песнь первая: с какого фига я вообще за это взялся?
Откровенно говоря, я стал инди-разрабом очень неожиданно. Я всегда хотел быть сценаристом, но как-то не сложилось. Вернее, сложилось, но не очень.
В своё время я сделал несколько модификаций для визуальной новеллы (ВН) «Бесконечное лето». Модификации народу понравились, они быстро взлетели на первую страницу рейтинга «за всё время» и до сих пор висят там.Если интересно, то вот ссылка. Такое признание меня взбудоражило и я решил — а почему бы не сделать собственную визуальную новеллу? Тем более я почитал другую визуальную новеллу — «Девушка в Скорлупе 2» и был очень вдохновлён её сюжетом…
Классная вещь, кстати. Рекомендую.
В общем, с этого и началась история моего падения)
Песнь вторая: сюжет и сценарий.
Сюжет в моей голове рождался медленно и размеренно. Как я уже сказал — я был очень вдохновлён другой визуалкой. Настолько там закрученный сюжет, персонажи. Прям ух! Соответственно, из щенячьего восторга и выросла идея сделать что-то похожее.
Следующим источником вдохновения стал Джон Константин. Яркий и харизматичный трикстер-экзорцист. У него я позаимствовал конструкцию имени. Моего главного героя будут звать Джон Виктор. Потому что Виктор по-латыни — «победитель». И это можно клёво обыграть в истории.
В этом моменте я впервые столкнулся с трудностями. Сфера любителей визуалок оказалась довольно ядовитой и я практически сразу стал получать отзывы в стиле «ты что, дурак? Такое имя-фамилию только имбецил придумает». Один из таких уникумов так вообще организовал фан-клуб Джона Виктора. Однако черт с ними, надо писать сценарий.
Сценарий планировался многовариантный. Т.е. в игре три акта, в каждом из них выборы. Эти выборы между собой переплетаются и выводят на разные ситуации. В принципе, это стандартная ВН-схема. Вот только я раньше такие не писал. Я писал кинетику — т.е. книгу, по сути. А тут — если в первом акте выбрать «нож», а во втором «телефон», то в третьем размышления будут про одно. А если в первом выбрать «нож», а во втором «газету», то размышления уже будут совсем про другое.В первом акте таких выборов 6. Количество выборов во втором зависит от того, что игрок выбрал в первом. В третьем акте просчитываются выборы обоих предыдущих.
Песнь третья: ресурсы.
Какое-то время всё шло достаточно гладко. Потихоньку рисовалась графика, на форуме любителей визуалок один энтузиаст предложил написать музыку.
Так герои выглядели первоначально.
А потом в моём мире наступил экономический кризис и я ушёл с работы. И заказывать графику стало не на что. А раз так — прощай, детектив Виктор, увидимся в следующей жизни. Графики нет, да и у композитора начались какие-то свои проблемы, потому он отказался сотрудничать дальше. (Тем не менее, пару мелодий он написал и они мне понравились — эти треки вошли в финальную версию.)
Но мне повезло. Я наткнулся на японский сайт с готовой графикой. Там продавалось много пресетов по низкой цене и я, не долго думая, затарился сразу по самое «не балуйся». Вопрос с графикой был решён.Правда, оставался вопрос, куда девать предыдущие наработки — всё-таки они делались специально под меня и нравились мне. Увы, частью пришлось пожертвовать. А часть была успешно вставлена в нынешнюю версию.
Так герой стал выглядеть в итоге.
Вопрос с музыкой решился схожим образом. В стиме был куплен пак мелодий, техподдержке был задан вопрос «а можно это использовать там-то и так-то?» и получен ответ «можно». Ура! Проблема с ресурсами была решена.
Песнь четвертая: код.
Тут надо оговориться. Я — человек не командный, стремлюсь держать всё под контролем, а потому мне гораздо легче сделать всё самому, чем поручить кому-то и в дальнейшем ходить проверять, сделал он или нет.Потому кодить я тоже стал сам.
С движком RenPy я уже был немного знаком, когда делал модификаций для «Бесконечного лета». Там всё было достаточно лайтово — никакой возни с интерфейсом, размерами шрифтов, оформлением и проч. Просто вставлял текст и менял картинки.И да, напомню ещё раз — я не работал с выборами и переменными.
Тут моя гуманитарная голова начала трещать во второй раз.Прописать развилки на бумаге — это одно. А как их запихнуть в код так, чтобы оно правильно реагировало — это другое.В третьем акте у меня выходило около 16 вариантов развития событий. И эти 16 вариантов складывались из предыдущих выборов.Огромное количество переменных. Все эти «if» «elif», эти флажки и поинты… ой блин.
Но, методом проб, ошибок и какой-то матери, за пару недель я всё это закодил. И, как ни странно, мне понравилось. Видимо, есть во мне какие-то мазохистские черты.Ты что-то делаешь и тут же видишь, как твоя работа воплощается в программе. Прикольно.Также в процессе кода рождалось много интересных идей. А что если персонаж в одном акте спросит имя человека, а в следующем назовёт его по этому имени? А если не спросит — то имени знать не будет? А таких персонажей 7. Здравствуйте, новые переменные.А что, если в ряде сцен экран будет с помехами? Это как раз логично выглядит с учётом сценария. Здравствуйте, эффекты глича и видеошума. А что, если в главное меню запилить ещё кнопку с выводом концовок и сделать одну из них скрытой, доступной только после первого прохождения? А что, если… И всё это реализовывается, и делает игру всё круче и круче.
Спецдеффекты со старой оригинальной графикой.
Однако, работая над этим ты понимаешь, что предела совершенству нет и править можно бесконечно. Нужно когда-то останавливаться и публиковать. И вот, начались вопросы с публикацией.
Песнь пятая: провал.
Сначала мне предложил издать игру друг. Он знал о том, что я делаю успехе в модификациях и предложил свои услуги. Я обрадовался и сказал «океюшки!».Но потом ему не понравился ряд моментов и мы разошлись.
Боль. Я стал искать другого издателя. И, кажется, нашёл (тут немножко рекламы) — такой же инди-разраб 7DOTS. Его мне прямо хочется расцеловать в обе щеки и повторять много раз «спасибо-спасибо»)) В первую очередь за то, что он сказал «не, такое оформление не катит» и в одно лицо перефигачил весь дизайн о_О. Кроме того, он добавил пару ЦГ и даже запилил в ВНку слоу-мо сцену (я вообще в шоке, что там так можно).
Анимированная сцена.
Во-вторых, он всё-таки выпустил игру на андроид, где она продавалась за 35 рублей.
Но потом этот разраб-издатель отвалился из-за ряда личных обстоятельств.
Песнь шестая: возрождение из пепла?
Но время шло, я случайно наткнулся на студента-переводчика (вернее, я думаю, что он студент, доказательств у меня нет) и тот согласился перевести проект. Качество, судя по всему, вышло более-менее читабельным. По крайней мере текст понятен. У меня появились некоторые сбережения и я смог оплатить взнос в стиме. Саму игру немного дополнил и подшлифовал, так что версия отличается от торрент-эдишна.
И теперь игра на проверке, страница в стиме есть, я спамлю друзьям «добавьте в вишлист»…
Но что делать ещё? Везде советуют разное. Отправлять кураторам или нет? Искать стримеров или надеяться на бусты стима? Я запутался.
Игроки, разработчики, помогите советом, пожалуйста.
Ну и, конечно же, прошу заценить страницу в стиме — и, если понравится, добавить игру в вишлист.
А вот тут, кстати, сделанный на коленке трейлер. Его я тоже делал сам и это отдельная головная боль.
В общем, моя игра получилась очень многострадальной. Но из-за этого ещё сильнее хочется, чтобы хоть где-то она поимела успех)
На этом пока всё. Надеюсь, вам было интересно читать. И надеюсь, что коллективный разум подкинет клёвых идей.
Пишем текстовую игру на Python/Ren’Py
Как сделать текстовую игру? Да как угодно. Как сделать кроссплатформенную текстовую игру на русском с иллюстрациями, звуком, работающими сохранениями, без проблем с кириллицей, и с каким-никаким геймплеем? Да ещё и в свободное время, не отрываясь от основной работы? Вот это уже интересней и на самом деле — довольно несложно. Заинтересовавшихся прошу под кат.
Примерно год назад мы с товарищем задумали сделать небольшую текстовую игру приблизительно в духе Sunless Sea и 80 days: про мореплавание, торговлю, исследование странных поселений и общение со странными личностями. Там должна была фигурировать религия, а лучше несколько, главного героя хотелось видеть не спасителем, героем страны и прославленным мореходом, а умеренно неудачливым предпринимателем/авантюристом, до которого и дела никому нет, а модный выбор между меньшим и большим злом заменить на выбор между добром и добром: никакого набившего оскомину гримдарка ради гримдарка. Довольно быстро придумались основные фракции и персонажи, крупные порты, политическая обстановка и куча симпатичных мелочей вроде подводной охоты на осьминогов (изображена на КДПВ) и гениальной идеи дать почти всем персонажам венгерские имена, которые звучат экзотичней привычных европейских и вызывают некоторую неявную симпатию. В общем, деревянных домиков понабигало немало.
В команде у нас на тот момент был один писатель и один программист (то есть я). Требования в предыдущем абзаце относятся скорее к сетингу и духу игры, так что исполнять их должен был мой товарищ, а передо мной встали вопросы геймдизайна и функциональности движка. Во-первых, большую часть времени игрок будет тратить, читая текст и выбирая действия главного героя. Для этого нужна только сносная типографика и возможность писать сценарий с меню, опциями и переменными. Вскоре подключилась художница, так что надо было думать ещё и об иллюстрациях. Во-вторых, игра про исследования и торговлю, поэтому нужно где-то в доступном игроку виде хранить информацию о собранных слухах и купленных товарах (а также всячески её обрабатывать). И, наконец, в игре про мореходство нужна карта и возможность по ней перемещаться; просто команда “поплыть к тартарам и послушать сказки морских лошадей” явно не соответствует духу проекта. Значит, движок должен ещё и поддерживать хотя бы несложные мини-игры, а не ограничиваться только показом текста и обсчётом игровых переменных.
Почему Ren’Py
Сразу скажу, что писать движок с нуля мы даже не пытались: велосипедостроение увлекательно само по себе, но малоэффективно, если стоит цель всё-таки выпустить игру до выхода на пенсию. Также мы не рассматривали парсерную Interactive Fiction: у неё и на английском языке очень небольшая аудитория, а на русском наш проект, будь он парсерным, мог бы заинтересовать в лучшем случае несколько сот человек. А хочется если не заработать денег, то хотя бы пройти гринлайт и набрать какую-никакую репутацию. К счастью, большинство нынешних англоязычных разработчиков текстовых игр перешло от некоммерческих хобби-проектов к профессиональному геймдеву буквально несколько лет назад. Поэтому основные движки либо опенсорсны, либо, во всяком случае, бесплатны. Давайте посмотрим, что нам предлагают.
Первый вариант, пришедший мне в голову – Storynexus от Failbetter games, разработчиков Fallen London и Sunless Sea. Проекты на нём редактируются через браузер, хостятся Failbetter и через браузер же доступны игрокам. Возможности для монетизации с прошлого года удалили. Главный минус, однако, не в этом, а в том, что в Fallen London большая часть событий представлена картами, выпадающими из колоды, и сделать на Storynexus игру, не использующую эту метафору – задача нетривиальная. Да и вообще намертво привязывать свой проект к стороннему серверу с закрытым кодом, который теоретически может вообще прекратить работу в любой момент, довольно рискованно.
Есть ещё два хороших проприетарных движка для Choose Your Own Adventure, то есть игр примерно нашего типа: ChoiceScript и Inklewriter. Оба обещают прекрасную типографику, простоту разработки (браузерный редактор у Inklewriter, скриптовый язык у ChoiceScript) и возможность коммерческой публикации. К сожалению, оба позволяют делать только чистое CYOA: нет никакой возможности добавлять в игру что-то помимо собственно текста, меню и иллюстрациий. Внимательный читатель воскликнет: “Но как же так? В 80 days ведь был довольно сложный инвентарь и интерфейс путешествий, верно? А в Sorcery! я точно видел боёвку!” Увы, эти системы разрабатывались Inkle Studios под конкретные игры и в редакторе нет ни их, ни хоть какой-нибудь возможности сделать себе такие же. По той же причине (а также потому что он, эм, своеобразный) мы отказались от Twine.
Единственным устраивающим нас вариантом оказался Ren’Py. Это бесплатный опенсорсный движок для визуальных новелл (например, именно на нём сделаны “Бесконечное лето” и “Katawa shoujo”), который довольно легко настраивается для наших задач. Игры получаются кроссплатформенные: сборка дистрибутива под Win/Mac/Linux – вопрос нажатия одной кнопки, причём даже не надо иметь под рукой целевую ОС. Android и iOS также заявлены и Ren’Py-релизы под мобильные оси существуют, но мы сами пока на мобильный рынок не целимся и о разработке для него рассказать не можем. К тому же у Ren’Py очень дружелюбное и живое сообщество на русском и английском.
Простейший сценарий на Ren’Py
Ren’Py написан на Python 2.7 + Pygame и имеет собственный DSL. На этом языке, во-первых, за счёт команд типа “Показать bg_city_night_53.png в качестве фона без анимации” или “Произнести реплику «Cем… СЕМПАЙ. » от имени персонажа nyasha1” в императивном стиле пишется собственно сценарий. Во-вторых, подмножеством этого языка является Screen Language, на котором можно в декларативном стиле собирать из ограниченного набора Displayables (то есть виджетов: кнопок, изображений, текстовых полей и тому подобного) экраны и настраивать их функциональность. Если встроенных возможностей недостаточно, то с помощью Python можно добавлять собственные. Этим мы займёмся в следующей статье, а пока разберёмся со сценарием.
Сценарий в Ren’Py состоит из последовательности реплик, действий с экранами и ввода игрока. Про экраны и ввод чуть ниже, а для начала мы разберёмся с персонажами. В визуальной новелле они создаются так (код из официального туториала, с незначительными правками):
Создано два персонажа: протагонист и Сильви, оба пишут бледно-синим цветом в стандартное окошко внизу экрана. У Сильви к тому же есть портрет, который появится на экране перед тем, как она начнёт говорить. Выглядит это вот так:
Если бы мы создавали визуальную новеллу, то продолжали бы в том же духе, но мы-то не собираемся показывать портреты персонажей, да и иллюстраций пара десятков на всю игру. Большая часть текста вдобавок не является прямой речью персонажей, так что нелогично было бы привязывать её к кому-то из них. Лучше создадим виртуального персонажа-рассказчика:
Его зовут narrator; это специальное имя, которое отдаёт ему весь текст, явно не аттрибутированный другим персонажам (строго говоря, его зовут None, а narrator, как и m и s в предыдущем примере – переменная, в которую помещается объект персонажа и из которой вызываются его методы, например, say) Аргумент kind принимает два значения: adv и nvl. Первое – это дефолтное поведение, описанное выше, а второе включает nvl-режим, в котором портреты не показываются, а текстовое поле занимает большую часть экрана. Как раз то, что нам было нужно. Этот режим описывается экраном nvl_screen в файле screens.rpy и группой стилей styles.nvl* (файлы screens.rpy и options.rpy соответственно), в которых мы зададим шрифт, фон текстового поля, цвет меню и всё остальное.
Разберём построчно: сперва объявляется ярлык start, с которого начнётся игра. Это название зарезервировано и движок всегда будет переходить на него после нажатия кнопки “Новая игра”, где бы в сценарии он ни находился. Всё, что следует за ярлыком, логически находится “внутри” этого ярлыка, поэтому выделяется индентацией: она в Ren’Py работает так же, как и в чистом питоне. Инициализация картинки достаточно очевидна, а вот следующая строчка делает важную вещь: убирает весь текст с экрана nvl_screen. Автоматически это не делается, поэтому, если не расставлять nvl clear в конце каждой страницы, текст спокойно уползёт за пределы экрана и будет выводиться туда, пока экран не будет наконец очищен. Вроде бы мелочь, но на отладку пропущенных nvl clear я потратил намного больше времени, чем готов признать. Свежевымытый экран мы временно уберём, чтобы позволить игроку полюбоваться фоном, покажем фон, включим бесконечную паузу (то есть дождёмся клика) и начнём историю. Как только на nvl_screen начнёт выводиться текст, экран сам вернётся на место.
Строка с паузой, кстати, уже на питоне: для включения единичной строки её достаточно начать с ‘$’, а более длинные куски кода нужно писать внутри блока ‘python:’. Любой код, исполняемый игрой, видит модули самого Ren’Py и явно импортировать их уже не нужно.
Добавляем ветвление и переменные
К этому моменту игра представляет собой читалку, которая показывает текст, меняя при необходимости фоны. Сохранение, перемотка, главное меню и настройки уже работают из коробки. Однако если бы мы хотели написать иллюстрированную повесть, то мы бы её и написали, верно? Добавим перед текстом небольшое меню:
Теперь после включения игры пользователь (или, скорее, разработчик) сможет при желании войти в режим дебага или пропустить уже готовый кусок вступления и начать тестировать сразу кусок из последнего коммита. Строка show screen nvl закомменчена за ненадобностью – как я уже упоминал выше, экран покажется сам собой, когда на нём обновится текст. Комменты, как видите, работают абсолютно очевидным образом.
Ярлыки, меню и другие индентированные блоки могут быть вложены до произвольной глубины, но на практике мы стараемся дробить текст на эпизоды в десяток страниц. Каждый такой эпизод описан внутри отдельного ярлыка с нулевой индентацией (он уже не обязан быть внутри ярлыка start или даже в одном с ним файле), а переходы из одного эпизода в другой осуществляются прыжками. Так мы не только боремся с десятками уровней индентации, но и обеспечиваем модульность кода: каждый эпизод может тестироваться отдельно и довольно несложно проверить, какие переменные он читает, в какие пишет и куда позволяет перейти.
Внутриигровые меню и переменные устроены абсолютно так же. Поскольку и переменных, и ярлыков даже в небольшом эпизоде на десять минут игры разводится невероятное количество, мы приняли несложный вариант венгерской нотации: имя ярлыка ‘the_very_start_lazlo_nooptions’ состоит из трёх частей: названия локации the_very_start (то есть период от начала игры до первого выхода в море), названия эпизода lazlo (то есть пьянка у Лазло, на которой можно нанять молодых бездельников в матросы) и имени собственно ярлыка. При таком подходе имена получаются достаточно громоздкими, но лучше так, чем обнаружить при тестировании, что три месяца назад кто-то уже создал переменную ship_listing, выставил True бог весть где и теперь крен из одного случайного события влияет на исход другого случайного события на другом конце моря.
Вместо заключения
К этому моменту мы уже воспроизвели на Ren’Py функционал упоминавшихся выше Choicescript и inklewriter. Вроде бы наш кораблик готов к отплытию. В следующей статье я покажу, как можно создавать более сложный интерфейс с использованием экранного языка RenPy и ещё более сложный — на чистом питоне.
Как правильно делать визуальные новеллы (КПД ВН), Часть 1
Коротко об авторе: Я сценарист визуальной новеллы «Большая Медведица» . Здесь я делюсь знаниями и наблюдениями.
Начнем с того, что многие не понимают, что это за жанр. Бегло взглянув на ходовые новеллы, игродел преисполняется уверенностью, что тоже так может. Всё так, только выходит у него совсем не то – особенности жанра упускаются или попросту игнорируются, ведь мастер над игрой уверен, что знает, как лучше.
Я приведу пару примеров, которые промахнулись жанрами:
Эта игра еще не вышла, но демо уже можно пощупать. У нее интересный сеттинг, приятная графика и интригующий сюжет, но с жанром разработчик ошибся – это понятно с первых минут, когда вас встречает туториал по геймплею.
Туториал. По геймплею.
Ирония в том, что геймплей в визуальной новелле сводится к нажатию пробела, в этой же игре такого удовольствия и вовсе лишили – на пробел игра не реагирует, текст листается мышкой и ею же жмутся метки, собираются предметы и открывается инвентарь.
Все это элементы квеста, а не визуальной новеллы. Кажется, игра просто переросла жанр – разработчик увлекся добавлением интерактива и проект вышел за берега.
Когда спортсмен набирает массу, он переходит в другую весовую категорию. Если он не хочет в другую весовую категорию, он держит себя в узде. То же и с визуальными новеллами. Жанр практически лишен гибкости и у него есть свои границы, выпасть за его пределы легко.
К самой игре претензий нет. Видно, что авторы стараются и к проекту относятся с большой любовью. Он достоин внимания, но не как визуальная новелла.
На этом «хорошие» примеры заканчиваются. Если в случае с Короной верится, что авторы забыли переобуться, то следующие игры, которые прибились к жанру визуальных новелл – пухлотелые барышни, втискивающие себя в чужие джинсы маленького размера.
Эти три игры объединяет то, что их разработчики не знакомы с жанром. Половина из них словосочетание «визуальная новелла» впервые услышали уже приступив к работе, а после не потрудились прочитать хоть одну. Если вы попросите ребенка нарисовать животное, которое он не видел, выйдет тот же результат.
Графика, сеттинг, стилистика, геймплей – из новеллы выбивается всё, и благополучно вбивается в треклятый квест. Зачем паразитировать на жанре визуальных новелл и обходить своего родителя за версту – загадка.
К чести Левиафана и Лондона стоит отметить качество игр, а вот Пасторат вышел халтурным, и место в списке заслужил лишь недавним релизом.
В этом случае ошибся не автор, это сделали игроки. Заявленные разработчиком жанры игнорируются, как и отсутствие какого либо упоминания новелл на сайте игры, и присутствие в игре мультиплеера. Казалось бы, опытный разработчик понимает, что делает, но куда ему тягаться со знатоками, что ставят штамп при виде обилия букв.
Если ошиблись вы – не проблема, но если вы выдаете ошибочное мнение за истину и несете в массы, вы заражаете им людей, которые по незнанию принимают его за единственно правильное. Это хуже чумы – чума хотя бы вырезает зараженных.
Обилие текста не делает игру визуальной новеллой, как наличие кожи не делает вас негром или азиатом. То, что в Pyre приняли за визуальную новеллу – лишь способ подачи сюжета, которую можно найти в доброй половине рпг-игр, жанр же игры определяет геймплей.
В шутерах стреляют, в файтингах дерутся, в головоломках решают задачки.
Если в своем проекте вы гоняете игрока от одной мини-игры к другой и используете point-and-click механику – поздравляю, у вас квест.
Визуальная новелла это национальный жанр, вне Японии – жанр нишевый и закрытый. Вмешательства извне он не терпит, развиваться он может только изнутри, постепенно увеличиваясь в объемах и обретая форму. Это черепаха, которой упомянутые разработчики норовят нацепить колеса, крылья и реактивный двигатель. Не надо так.
Визуальная новелла – это треугольник, сторонами которого выступают графика, текст и звуковое сопровождение. Добавьте еще одну сторону – получите другую фигуру.
Если вам кажется, что читать текст – скучно, и раз в двадцать минут необходимо разбавлять сюжет играми «найди пару», «три в ряд» и «2048», рисованием рун, нахождением котов в темной комнате и смешиванием зелий, то этот жанр не ваш. Отпустите его.
Если нет – читайте новеллы. Читайте как можно больше, старайтесь погрузиться в жанр и выделить элементы и приемы, которые покажутся интересными.
Задавайте вопросы, я постараюсь ответить на них в следующем посте.
Зачем вливать силы в спрайты, бг арт и ОСТ, если история не сможет просто захватить? Вон, Katawa Shoujo сделали на RenPy с не самыми лучшими артами и минимумом CG, а все равно прокатило. Да даже ранний Такеучи, когда рисовал свои первые дизайны для Tsukihime, был на уровне школьника с РПГмэйкером, но они с Насу как-то же смогли рассказать историю на 30+ часов.
Как я писал ветвистый сценарий для мобильной визуальной новеллы
Всем привет! Горю желанием поделиться личным опытом работы над сценарием для мобильной игры жанра Interactive Story.
Я, вместе с небольшой командой, занимаюсь разработкой такой игры с апреля прошлого года и за это время написал для нее 43 эпизода, суммарным объемом около 200 тысяч слов. Сразу хочу уточнить, что в других компаниях я сценаристом не работал, так что данная статья — опыт одного конкретного проекта и одной конкретной истории.
Говоря о мобильных визуальных новеллах, я имею в виду не классические ВИ, портированные на мобилки, а такие игры как «Клуб Романтики», «Chapters», «Choices», «Love Sick», «Tabou», «Novels», «Desires», «My Love», «Secrets», «Moments», «Episode», «Maybe». Это важно понимать.
С сюжетной точки зрения, мобильные новелки — это ни что иное как новая стадия эволюции дешевых любовных романов. В случае с играми, ориентированных на женскую аудиторию (таковых в жанре большинство), всё крутится вокруг любви-отношений, а игровой процесс завязан на том, что игрок романсит интересующих его персонажей (таковые зовутся Love Interest или просто LI).
Качество сюжета в мобильных Interactive Story… ну, оно разнится. Есть как хорошие тайтлы, так и способные нанести мозгу неподготовленного читателя тяжелый урон. Вторых, само собой, больше.
Сюжет и сеттинг чаще выполняют роль фона, поэтому стабильно держат планку на уровне с фильмами категории «B». Героиня может спасать мир от инопланетного вторжения, расследовать загадочное убийство, покорять Голливуд, сражаться с вампирами, отдыхать в летнем лагере или осваивать дикий запад — это не важно, основное внимание всё равно всегда сосредоточено на ее отношениях с персонажами-LI.
Если говорить о степени интерактивности в рамках истории — она встречается в разной степени, но практически всегда ограниченная. 90% развилок меняют только несколько строчек диалога. Также есть премиум-выборы, доступные за внутриигровую валюту. Вот они как раз разблокируют большие куски дополнительного контента и могут оказать влияние на историю.
Приложение-хост чаще всего представляет собой книжную полку с набором подобных историй. История может быть как короткой (10-15 эпизодов по 15 минут), так и растянуться на несколько сезонов.
Изначально мы тоже собирались делать приложение «книжную полку». Я даже написал несколько пилотных эпизодов под разные жанры и сеттинги.
Для этой цели был использован веб-сервис InkleWriter — бесплатный и очень удобный инструмент для прототипирования интерактивных историй. Максимально прост в освоении, но функциональность ограничена и нет нормальной техподдержки. Для коммерческого использования не подойдет, а вот сделать быстрый прототип — самое то.
После работы над пилотами я выяснил сразу две важные вещи:
1. Американские бета-ридеры не плакали от моего английского. Это было очень позитивным моментом, потому как с такими играми целиться нужно в страны из Tier 1. Мы со своей игрой целились конкретно на Америку.
2. Я осознал, что физически не смогу заставить себя писать приторный сюжет условных «50 Оттенков Сумерек» в течение следующих шести месяцев. Мое психическое здоровье этого просто не вывезло бы.
Второй пункт являлся серьезным препятствием в работе. Вариантов решения было два: а) нанимать авторов-фрилансеров, самому перейти на редактуру; б) думать над какой-то оригинальной концепцией, с которой было бы не так больно работать. Я решил пойти по второму пути.
Есть в Англии такое мегапопулярное дейтинг-шоу, называется «Love Island». Участники — группа молодых и красивых парней и девушек — живут вместе в одной вилле и строят отношения. Чем-то может быть похоже на Дом-2 или Каникулы в Мексике (если кто помнит), с той разницей, что в английском шоу все как-то более культурно и интеллигентно. Никто не дерется, матом не ругается. Внешний вид участников то и дело наталкивает на мысль, что пластмассовый мир победил и макет оказался сильней, однако в целом смотреть на девушек в купальниках и подкачанных парней эстетически приятно.
По IP этого телешоу была сделана и выпущена одноименная мобильная игра. И во время своих исследований жанра я на эту игру наткнулся, не зная при этом о существовании самого телешоу. Я решил, что передо мной история в концепции вымышленного дейтинг-шоу, и восхитился подобной идеей.
Это ведь то, ради чего люди и играют в мобильные визуальные новеллы, в самом чистом виде! Дейтинг, отношения с другими персонажами — причем без лишней обертки из плохо прописанного сюжета в набивших оскомину сеттингах.
Вскоре я узнал о том, что Love Island — никакое не вымышленное телешоу, а вполне себе настоящее, а игра «Love Island The Game» разработана по лицензии. Сначала я разочаровался. А потом меня осенило. Получалось, что идея « истории — симуляции вымышленного телешоу » существовала только у меня в голове. Если игра по Острову Любви была жестко ограничена в плане лицензии и исходного материала, то наше вымышленное дейтинг-шоу могло с стать каким угодно, с любыми правилами, локациями и персонажами. К примеру, мы могли отправлять участников в путешествия, в новое место в каждом сезоне! (в первом сезоне наши персонажи таки провели три дня в джунглях).
Я провел дополнительный ресёрч в поисках похожих игр, но ничего подобного на рынке не обнаружил. Тогда я решил рискнуть. Так появилась концепция нашей игры Couple Up! Love Show.
Пять парней и пять девушек прибывают в поместье, где им предстоит жить вместе в течение 14 дней. Основная задача каждого — найти свою идеальную пару и построить отношения. Кто остался без партнера, тот выбывает из шоу.
Ежедневный досуг участников состоит из общения, плетения интриг, времяпрепровождения с партнерами, а также совместных игр и испытаний, которые устраивают для них организаторы.
С точки зрения сценарной работы такой сеттинг предоставляет много интересных возможностей. Разберем каждую по отдельности.
1. Персонажи — они как луковицы. У них есть слои!
Если вы с первого эпизода сразу вводите девять новых персонаже й (не считая протагонистки), вам стоит позаботиться о том, чтобы все они были уникальными и запоминающимися. Шаблонными болванками обойтись не выйдет.
Участникам шоу предстоит общаться друг с другом на самые разные темы, делиться историями из своего прошлого и вести беседы, достаточно увлекательные, чтобы игрок не скучал. Следовательно, каждому персонажу нужны яркие личностные черты и понятный бэкграунд, который эти черты сформировал.
Более того, каждый должен иметь цель — зачем он пришёл на шоу? Формальная цель ясна — все пришли искать любовь. Но что за этим кроется на самом деле? Кто-то хочет засветиться на ТВ и раскрутиться. У кого-то задача устроить себе веселое летнее приключение. Кто-то просто отчаялся устроить личную жизнь во внешнем мире.
Мне очень хотелось, чтобы у каждого персонажа был свой секрет. В первых эпизодах разговоры с ним раскроют только то, как этот персонаж хочет себя презентовать. Чтобы докопаться до того, что же он за человек на самом деле, вам придется установить доверительные отношения.
К примеру, есть Адам. Весельчак, шутник, душа компании. Во всех общих сценах Адам — основной источник юмора и дурашливых историй. Однако в шутках Адама периодически мелькают мрачные нотки, особенно когда разговор заходит о его семье. Если вы выберете другого партнера, настоящий Адам вам за всё прохождение так и не откроется.
2. Продвижение по сюжету или игра в симулятор бога
Когда персонажи прописаны и понятны, написание сюжета начинает отдаленно напоминать игру в какой-нибудь Sims. У вас есть группа людей в закрытом пространстве. Ситуация для всех общая, однако справляется с ней каждый по-разному. А еще каждому хочется чего-то своего.
Такое положение дел позволяет двигать сюжетную линию двумя приемами:
3. Эффект дивана Друзей
Не знаю, есть ли научное название у этого эффекта, но уверен, что каждый с ним знаком. Когда хочется самому оказаться по ту сторону экрана, рядом с любимыми персонажами, в том самом легендарном месте, где они неизменно собираются в каждой серии. Посидеть за столом учебного кабинета вместе с гриндейлской семеркой из «Сообщества», выпить в пабе МакЛаренс с ребятами из «Как я встретил вашу маму» или зайти в бар, где после работы отдыхают служащие бруклинского участка 9-9.
Чтобы превратить локации Поместья в такое волшебное пространство, я уделял много времени сценам досуга участников вне испытаний и любовных интриг. Например, утро седьмого дня начинается с батальной сцены подушками, а на десятый день ребята развлекались, играя в «пол — это лава».
Такие сцены дополнительно помогают героям проявить себя, дают разрядку между важными сюжетными моментами… ну, и в конце концов, это весело.
Дополнительно я старался создать впечатление, что игрока здесь ждут. Персонаж ведущего (у нас это бесплотный Голос) всегда радуется, когда игрок заходит в новый эпизод.
4. Разветвления истории
Ключевой момент всей задумки заключается в том, что игрок может выбирать своего партнера. Делать выбор фиктивным в такой игре никак нельзя, это убило бы всю ценность сеттинга.
Здесь я попал в ловушку джокера по мере того, как выстраивалась следующая логическая цепочка:
Я начинал сезон весьма осторожно, очень боялся не справиться с объемами и запутаться. Из-за этого первые эпизоды были достаточно линейной колбасой. Но чем глубже в сезон, тем шире становилось дерево разветвлений.
Кульминация наступила в эпизоде 33, где на каплинге (ритуале объединения в пары) игрок мог потенциально сойтись с 7 разными партнерами, и на выходе формировалось 11 комбинаций, кто из участников покидает шоу.
Я пишу и собираю историю прямо внутри Unity в кастомном редакторе графов, который был написан на базе бесплатного фреймворка xNode. Не буду выносить в статью, как мы пришли к такому техническому решению, поделюсь только опытом использования при работе с развилками.
Отдельно отмечу, что, насколько мне известно, обычно для игр жанра Interactive Story сценарии пишутся по-другому — в цельных скриптовых доках. На сайте у мастодонта жанра, компании Episode, есть полноценный сервис для создания истории под их приложение любым желающим. Кто интересуется, можно зайти и потыкать.
Итак, есть простые развилки, которые меняют только несколько строчек диалога — с ними все понятно. Написал три варианта ответа, протянул после каждого отдельную ветку, затем свёл к общему исходу.
Можно делать такие развилки короткими, а можно делать их массивными, существенно меняя содержание разговора. Однако полноценной интерактивности в такой развилке немного, потому что игра в итоге не запомнит выбор игрока, а значит, он не окажет влияния на историю.
Чтобы запоминать выборы игрока или определенные нелинейные игровые ситуации, мы используем особый граф Branch и два вида данных: булевые и цифровые (bool и float соответственно). Для удобства я дальше буду называть bool’ы — маркерами, a float’ы — параметрами.
Маркеры регистрируют, случилось какое-то событие или не случилось. Я, будучи, сторонником ручной проработки, полагаюсь в первую очередь именно на них, потому что это позволяет персонажам в своих речах отсылаться к тем или иным событиям и упоминать выборы, совершенные ранее игроком.
Цифровые параметры удобны, чтобы отслеживать общий уровень отношений с персонажами или, например, начислять игроку очки в конкурсах и испытаниях.
К примеру, вы сказали комплимент персонажу Шарлотте. Ей это понравилось, в графе Branch мы добавляем к параметру charlotteRelationship 1 балл. В будущем мы проверим, сколько у нас баллов отношений с Шарлоттой и, в зависимости от результата, она будет с нами вежлива или груба.
Хотя цифровые параметры очевидно более системны, большинство важных развилок в истории я вешал всё же на булевые маркеры. На мой взгляд, когда персонажи могут припомнить вам какой-то конкретный поступок, который вы совершили, или сказанную вами фразу — это классно.
Во многих случаях, я комбинировал параметры и маркеры. С одной участницей игрок может полсезона собачиться и быть в очень натянутых отношениях, но затем игроку представляется возможность спасти эту участницу от выбывания из шоу. И если вы ее спасете, она это запомнит и уже не станет злиться на вас так, как раньше.
Возможные комбинации пар я менеджерил тоже на булевых маркерах. Это чрезвычайно увлекательный процесс, который выглядит приблизительно следующим образом:
Маринка выбирает первой и всегда выбирает Сережу. Создаем маркер marinkaSerezha. Главгероиня выбирает второй и может выбрать кого угодно кроме Сережи, который уже занят. Создаем маркер под каждый выбор героини. Третьей выбирает Наташка. Наташка хочет выбрать Толика. Если Толик свободен, Наташка выбирает его. Если Толика уже выбрала главгероиня, Наташка выбирает Игоря…
Во второй половине сезона я решил усложнить себе жизнь, и игрок теперь не только выбирал себе партнера, но и косвенно влиял на выборы других персонажей. Теперь условная Наташка могла сойтись или не сойтись с условным Олегом в зависимости от того, что ей посоветовал игрок. Комбинаций стало еще больше.
К последним эпизодам я уже абсолютно преисполнился в своем познании и с трудом понимал, что происходит. Практически все участники находились в квантовой суперпозиции, в том плане, что в половине таймлайнов этот человек выбыл из шоу, а в другой половине он отлично себя чувствует и уверенно идет к финалу.
Если бы не графы, я бы, наверное, поломался. Основной минус сценарной работы с редактором графов — громоздкость — компенсировался его основным плюсом — наглядностью. Понятия не имею, как я бы работал с таким количеством переменных и развилок в доке со скриптами, где всё идёт одним сплошным полотном.
Игрок мог закончить игру с одним из семи возможных партнеров. У каждого из них при этом был свой характер, свой бэкграунд, своя манера разговаривать. С каждым нужно было выстроить свой уникальный конфликт. Продублировать один текст семь раз было нельзя (хотя из-за нехватки времени таким методом я тоже нередко грешил).
Усложнял дело тот факт, что вторая половина сезона писалась, когда игра была уже в открытом бета-тесте. Даты релиза новых эпизодов были анонсированы, и аудитория их ждала. Последние три месяца для меня стало привычным делом сидеть двое суток подряд без сна перед очередным релизом и с горящей задницей набрасывать десятки веток, чтобы успеть к сроку.
Весь сезон был написан, в общей сложности, за полгода. По ощущениям — словно жизнь прожил. Получившийся сценарный продукт пока далек от идеала и полон огрехов, но я работаю над ошибками.
В истории есть явные проблемы с обязательными для жанра элементами. К примеру, страстные постельные сцены — я так и не научился их писать, чтоб получался не кринж. Однако похоже, что отчасти эти проблемы компенсировались другими вещами, которые я заботливо вкладывал в игру: шутейками, взаимными подколами и кул стори от персонажей, мемами и отсылками к поп-культуре, возможностью выбора.
Аудитория первый сезон Couple Up! восприняла тепло. Большинству игроков, оставшихся в игре после первых эпизодов, история понравилась. Я, конечно, допускаю, что аудитории жанра Interactive Story от сюжета много и не надо, но всё равно считаю это успехом, поскольку ничего подобного раньше не делал.
Сейчас мы работаем над повышением удобства нашего внутреннего редактора и параллельно готовимся к работе над вторым сезоном с новым набором персонажей.
А еще, под новые сезоны я намерен собирать авторскую группу, так что если ты творческая личность с хорошим английским, и давно хочешь попробовать себя в качестве сценариста — пиши в личку.
Всем большое спасибо за внимание! Надеюсь, вы нашли в этой статье что-то полезное для себя.
Я поверхностно читанул, вполне клёво всё. Лайк точно, но вот дизайн конечно кринж. выглядит довольно посредственно. играть я бы точно не хотел. так что на мобилки это зайдёт :0
арт проигрывает топовым мобилкам в жанре так-то.
Классная статья.
весь последний год занимаюсь созданием конкурентого приложения, тоже маленькой командой) Кому интересно My Fantasy: Make Your Story.
мне кстати кажется вы как-то мне даже писали в фб или на конфе подходили. хм.
Помню-помню, как же, на Games Gathering слушал вашу лекцию и потом в фб мы немного общались)
Вашу игру чекал после этого, очень круто работа с аудиторией в приложении настроена, прямо мощно.
Спасибо большое, за фидбек и советы 😌
Когда искала такую вакансию, чтобы реализовать давнее хобби, у всех были требования издавшаяся книга и 3 летний стаж. А тут наркоманка прошла по конкурсу. Правильно шутят райтеры, что без белого порошочка тут не преуспеешь.
Ого! Вы можете уже смело сами написать историю про поиск писателя) а если по теме, то я бы посоветовала вам опубликовать вакансию на ingamejob, gdjibb, отправить в Нарраторику и ещё всякие геймдев-сообщества, там сценаристов и игровых писателей должно быть много)
Так, ладно, а теперь к самому важному!
Признаёмся, кого бы вы пошли романсить:
1. Шатенка
2. Блондинка
3. Рыжая
Добавляю к списку брюнеточку. С ней даже можно в игре замутить 😉
у кого ватрушка сочнее
Я сам-то выбираю Шатенку. )
1. Остальные как-то ультравсрато выглядят.
Спасибо за статью, интересно, а такой вопрос, я вот в подобных случаях использовал mind maps (Freemind, Mindjet Mindmanager), но средства Unity не задействовал, все собираюсь, так вот, насколько там широк функционал именно в плане работы с ветвлениями и влиянием выборов игрока в достаточно глубоких диалогах и для работы с очень ветвистой логикой сюжета? У меня работа над детективной историей намечается, большой упор на глубину в разговорах, но вот как-то привык к интеллект-картам.
Наш редактор написал наш разработчик именно под наши нужды, на базе открытой библиотеки нодов, которую вообще используют под разные вещи.
Спасибо огромное!
♥️♥️♥️
Вроде же в киберпанке сценарий хвалили в целом, нет?
(все откладываю покупку на когда время появится)
Интересно было почитать, спасибо.
Постельные сцены пожалуй всегда кринж, от этого никуда не деться (прув ми вронг)
Спасибо!
Флоты сделали на всякий случай, чтобы обеспечить больше гибкости. Не были уверены, насколько серьезно будем эти числа дробить.
Отличный текст, с подходом у вас все хорошо, кажется. Удачи!
Интересно было прочесть. Смущает арт немного (анатомия гуляет), но в технической и логической части работа проделана огромная. Спасибо за статью!
Сам порой поигрывую в такого рода игры,так что послежу и за вашей игрой.Из них интересными в плане прописывания истории героев,конечно же Romantic Club,но и Choices,хотя если еще поглядеть порой хорошие попадаются😉
Choices огромные красавчики. Фактически, всем остальным дорогу протоптали. Ну и там у них же авторы пишут, которые профессиональные издающиеся писатели.
Классная идея! Наконец-то кто-то начал креативить в этом жанре. Если не секрет, то какое самое большое количество вариантов выбора (который действительно влияет на сюжет) вы давали игроку? Интересно оценить масштабы ))
Для глаз игрока прямо важные-важные выборы редко идут больше двух вариантов на раз.
Несколько раз бывало, что по 3 или 4. Например, в 12 эпизоде можно было из четырех партнёров выбирать.
Но тут есть такая фишка, что выборы нередко основаны на предыдущих действиях игрока.
И он может видеть перед собой только два варианта, а я пишу шесть, потому что там три комбинации по два варианта, идущие из разных предпосылок.
Спасибо за материал. Как раз было интересно (с возможным прицелом на будущую работу), насколько там серьезные ветвления требуют работодатели и в целом workflow.
Вам спасибо! Совет дельный, там и так сейчас часть строк свернута. В нодах сразу задаются эмоции, одежда, имена (если отличаются от стандартных, типа «Незнакомец» вместо имени персонажа). Будем думать еще, можно ли как-то оптимизировать пространство.
Стало интересно, а какой софт еще подходит для написания сложных и ветвистых сюжетов помимо вышеупомянутого?
Заинтересовала нодовая структура
Я выше писал, для ветвлений и логики повествования я юзал Freemind, Mindjet Mindmanager, а еще писатели и сценаристы вроде любят Scrivener.
Нашел в закладках статью со списком сервисов и фреймворков. В начале работы рассматривали некоторые варианты оттуда. Twine тоже с майндмапами работает вроде бы.
Я пользовался Miro и Twine, оба вполне удобны. Второй позволяет сразу затестить ветки.
Twine 2, Ink, Yarn spinner
А что за программа, в которой сценарий пишешь? (на первой картинке)
Для того, чтобы это узнать надо всего лишь.
И потом показывает вполне шаблонных болванчиков.
Большой вопрос, хочет ли ЦА видеть персонажей с харизмой думгая в такой игре. Узнавание великая вещь. Плюс это арты, может в тексте они раскрываются как неординарные личности (вряд ли).
Спасибо, интересная история. Для меня лично главный вывод — что сделать большую вариативность (точнее, альтернативность игры) довольно сложно даже в таких небольших мобильных играх: чем больше у тебя персонажей и отношений между ними, тем сильнее ветвится история и тем сложнее всё это учесть и реализовать. В текстовых играх ещё более-менее можно, но если есть озвучение, то уже сильно вряд ли.
Где-то не так маркеры проверишь, и у игрока в сцене появляется персонаж, которого в шоу быть уже не должно. Или игра останавливается и дальше не идёт, потому что идёт триггер на событие, которое у игрока в его прохождении не происходило.
Жанр вообще не мой, но прям поиграть захотелось.
Спасибо, отличная статья!)
Ого! Вам огромное спасибо за такой теплый отзыв! Мне невероятно приятно и я просто счастлив, что вы поиграли, и даже прошли, и даже остались довольны.
Отдельная благодарность за репорт ошибок, исправлю!
Лео и Шарлотта в части сценариев не сходились тоже из-за ошибки в скрипте, я ее буквально пару дней назад обнаружил и устранил. Даже спустя несколько месяцев после завершения сезона все еще вылезают такие бока))
Интересно, а если взять какой нибудь NoSQL для хранения и заполнения документов взаимоотношений между персонажами и событиями, а потом одним хитровыезаковырнутым запросом получать результат для действий?
Проблема не в запросах, а в том что на все возможные запросы нужно текст написать. А запросы растут в геометрической прогрессии.
Как я понял из текста, ничего кроме романтики в жанре интерактивных историй сделать нельзя?
Можете чекнуть игру Stories: Your Choice. Там как раз в таком формате истории разножанровые не про любовь.
Сам там полностью ни одну историю не прошел, но слышал очень хорошие отзывы.
Однако дело в том, что если навскидку сравнить их бизнес-метрики с романтическими играми, то сравнение будет не в их пользу.
This page is out of date
Some places to look are:
Please do not create new links to this page.
Руководство для начинающих
Добро пожаловать в Руководство для начинающих по использованию движка визуальных новелл Ren’Py. Здесь мы, на примере создания с нуля игры Знакомство с Визуальными Новеллами, рассмотрим процесс написания простой визуальной новеллы.
Начало работы
Запустим центр управления Ren’Py. Для этого нужно запустить renpy.exe (renpy.sh для пользователей Линукса) из папки, в которую распакован архив с ним. В левом верхнем углу белым будет написано название активного проекта. Справа — ряд кнопок, поделённый на две секции:
Мы хотим создать новую игру, потому выберем «Новый проект». ЦУ попросит выбрать шаблон проекта — выбираем template за неимением других опций. Затем ЦУ попросит ввести название проекта. Вводим. Следом ЦУ попросит выбрать цветовую схему оформления проекта. На вкус и цвет. В результате вернёмся в главное меню ЦУ с только что созданным проектом в качестве активного (обратите внимание на левый верхний угол). Можно запустить его кнопкой «Запуск», чтобы полюбоваться на интерфейс. Но лучше приступить к собственно написанию игры.
Где, что и как писать
Приступим к собственно написанию игры, для чего выберем «Править скрипт». В результате файлы с кодом проекта откроются для редактирования во входящем в поставку Ren’Py редакторе SciTE. Редактор многовкладочный, поэтому трём имеющимся изначально (от шаблона) файлам «script.rpy», «options.rpy» и «localize.rpy» будут соответствовать три одноимённые вкладки. Нам в данный момент нужна та, что озаглавлена «script.rpy».
RenPy_1.JPG
Мы увидим следующее: Самая первая строчка — это комментарий. Комментарием является любое сочетание символов, предварённое символом # и завершающееся с концом строчки. Комментарии не воспринимаются обработчиком и никак не отражаются в игре. Используются они для оставления каких-то пометок-пояснений себе. Или для временного исключения из обработки какой-либо строки.
Начиная со строчки 3 идёт блок init.
Отступы и блоки — основа основ
Здесь надо пояснить базовую особенность языка Ren’Py: для определения контекста, к которому принадлежит строчка, используются отступы (конкретнее — сочетания из четырёх пробелов). Все строки, имеющие одинаковый (или больший) отступ, принадлежат одному контексту, или блоку. К примеру:
Зачем нужен блок init?
В любом проекте есть информация, такая как используемые изображения и персонажи, которая должна быть определенна до собственно начала истории. Такая информация объявляется в блоке init. Он может находиться в коде где угодно, но обычно его помещают в самое начало. Этот блок начинается со строчки:
записанной без отступа, и все строчки с отступом, следующие за ней, принадлежат блоку init. Строчек этих может быть любое количество. Заканчивается блок первой же строкой БЕЗ отступа. И эта строка, конечно же, блоку init уже не принадлежит.
Метки.
Дальше обратим внимание на строчку 12:
Поехали!
Можно приступать к работе. Для начала удалим блок init и всё в блоке label start, чтобы не мешалось. Теперь нам нужно заставить Ren’Py сказать первую реплику. Для этого в блоке label start напишем просто:
«Интернациональный Колледж Цифровых Искусств.»
(Не забываем про отступ!) Подобная конструкция называется «высказывание» (say statement). Ren’Py автоматически осуществляет перевод строки, если выведенное высказыванием в текстовое окно сообщение в одну строчку не вмещается. Но если есть нужда перейти на новую строку в каком-то определённом месте, то в этом месте нужно поставить сочетание символов \n. Вот так:
«Мне повезло, что я учусь здесь. \nОсобенно, что на игровом направлении.»
Каждое высказывание обновляет содержимое текстового окна.
Если в тексте высказывания необходимо использовать двойные кавычки » их необходимо предварить символом \. Вот так:
«Сейчас по расписанию \»Визуальные новеллы\». Новый курс. Интересно, о чём же нам там поведают?»
Если сейчас сохранить изменения, запустить проект и выбрать «Начать игру», увидим этот текст в текстовом окне. На фоне чёрного экрана. Не особо хорошо, не правда ли? Что ж, добавим фоновый рисунок. Но для этого изображение, что послужит фоном, сначала нужно объявить в блоке init. Получим в итоге следующий скрипт:
image bg uni = «Images/uni.jpg»
Фоновые изображения должны быть того же размера, что и выбранное для игры разрешение. По умолчанию — 800х600 пикселей, наверное, самое удобное. Формат файла для фоновых изображений — JPEG или PNG. Теперь выведем это изображение в виде фона перед тем, как выводить текст. Для этого на следующей после label start строчке напишем (сдвинув высказывания на строчку вниз):
Сначала идёт ключевое слово scene, затем псевдоним изображения, которое нужно использовать как фон. Смена фона на другой также производится этой командой. При применении команды в таком виде предыдущее фоновое изображение вместе со всеми прочими визуальными элементами немедленно заменяется на указанное в команде. Однако процесс перехода можно сопроводить эффектами. В Ren’Py есть ряд предопределенных эффектов, например fade («упрозрачнивает» старое изображение в чёрный фон за полсекунды, затем «упрозрачнивает» за полсекунды чёрный фон в новое изображение), dissolve («растворяет» старое изображение в новое за полсекунды) и pixellate (пикселизует за полсекунды старое изображение, затем за полсекунды распикселизует новое). Для применения эффекта надо только приписать к нужной команде вывода изображения ключевое слово with и название нужного эффекта. Проще это увидеть самому. Потому выведем этот фон с эффектом dissolve. А после высказываний сменим фон на другой с эффектом fade. Надо только не забыть объявить изображение в блоке init. Получим такой скрипт:
Украшаем текст.
Кто сказал «Гав»?
Дальше идут простые высказывания, описывающие ситуацию — в зал вошла преподавательница. Но вот она обращается к нам, и в соответствующем высказывании неплохо было бы как-то её назвать, показывая, что реплика — от её имени. Поскольку имени её мы не знаем, обозначим её как «. ». Для этого используется следующий формат высказывания:
Эти реплики выведутся со строкой «. » вверху текстового окна. Важно: если в первой строке (т.е. между первыми и вторыми двойными кавычками) используются русские буквы, то её необходимо предварить английской буквой ю («u»)! Так, если нужно вывести реплику главного героя — от первого лица — то высказывание будет выглядеть так:
Вообще говоря, символом u следует предварять любую строку, содержащую символы кириллицы, но опыт показывает, что текст реплики в высказывании в подобном не нуждается.
Так, теперь, когда нам известно имя преподавателя, указывать его как «. » нельзя, а каждый раз набирать «Профессор Наталь» неудобно. Здесь на помощь приходят такие объекты Ren’Py, как «персонажи» (character object). Персонажи позволяют использовать в именных высказываниях вместо длинных имён короткие псевдонимы. Но сначала персонаж нужно объявить в блоке init. Делается это следующей строчкой:
Сначала идёт знак доллара, затем псевдоним персонажа, затем знак равно, ключевое слово Character и аргументы в скобках. В данном случае — имя персонажа (в кавычках), которое будет отображаться во всех его репликах. (Обратите внимание, поскольку имя персонажа дано кириллицей, его необходимо предварить символом u) Для облегчения написания кода псевдоним персонажа лучше делать как можно короче. Чаще всего имена персонажей выделяют цветом. Для этого нужно добавить в объявление персонажа аргумент color:
$ e = Character(u’Эйлин’, color=»#c8ffc8″)
Также можно заставить все реплики этого персонажа выделяться определённым цветом. Для этого нужно добавить в объявление персонажа аргумент what_color:
$ e = Character(u’Эйлин’, color=»#c8ffc8″, what_color=»#c8ffc8″)
Можно также автоматически применять теги ко всему тексту всех реплик персонажа. Для этого нужно добавить в объявление персонажа аргументы what_prefix со строкой открываемых тегов и what_suffix со строкой закрывающих тегов. Так, чтобы выделить всё, что скажет Эйлин жирным и курсивом, нужно записать:
$ e = Character(u’Эйлин’, color=»#c8ffc8″, what_prefix = ««, what_suffix = ««)
Правда, лучше было бы это реализовать с помощью аргументов стиля:
$ e = Character(u’Эйлин’, color=»#c8ffc8″, what_bold = True, what_italic = True)
Вообще, строка-значение аргумента what_prefix перед обработкой реплики приписывается движком к началу текста реплики, а строка-значение аргумента what_suffix — к концу. Персонажи ещё много чего могут, но мы сейчас ограничимся наиболее часто используемым минимумом:
$ p = Character(u’Профессор Наталь’, color=»#ff6666″)
Теперь все высказывания вида
p «Прежде всего, что такое \»визуальная новелла\»?»
будут выводиться от имени профессора Наталь.
Портретное сходство.
Всё это хорошо, но неплохо было бы видеть профессора на экране, когда она что-либо говорит. Здесь в игру вступают изображения персонажей. Размером они обычно х (т.е. если для игры выбрано разрешение 800х600, то изображение персонажа будет размером от 200х600 до 266х600). Также, вся область изображения, не занятая собственно рисунком персонажа, должна быть прозрачной! Выбранный формат файла для изображений персонажей — PNG. Объявляются изображения персонажей так же, как и фоновые изображения:
image prof norm = «prof_norm.png»
image prof smile = «prof_smile.png»
В подавляющем большинстве случаев для одного и того же персонажа нужно несколько изображений, с разными выражениями лица или в разной одежде. В данном случае применяются два изображения: с обычным выражением лица и с улыбкой. Можно заметить, что псевдонимы, использованные для этих изображений, совпадают первым словом. Это так называемый ярлык изображения (image tag). С его помощью удобно группировать изображения, а также скрывать любое из группы, независимо от того, какое именно сейчас на экране. Сообществом Ren’Py принято фоновые изображения отмечать ярлыком bg. Показывается изображение персонажа в игровом коде строчкой:
Сначала ключевое слово show, затем псевдоним изображения. Введённая в таком виде команда выведет изображение по центру игрового окна по горизонтали, нижний край изображения совпадёт с нижним краем окна. В Ren’Py есть предопределённые позиции для изображений: справа (at right) — правый край изображения совпадает с правым краем экрана; слева (at left) — левый край изображения совпадает с левым краем экрана; по центру (at center) — изображение отцентрировано горизонтально; за пределами экрана справа (игроку не видно) — at offscreenright; за пределами экрана слева (игроку не видно) — at offscreenleft. Во всех случаях нижний край изображения совпадает с нижним краем игрового окна. Чтобы показать изображение в нужной позиции, необходимо приписать название этой позиции к команде, выводящей нужное изображение, после псевдонима. Лучше всегда указывать позицию для вывода. Итак, чтобы вывести изображение профессора по центру, нужно написать:
show prof norm at center
Также, к изображениям персонажей тоже применимы эффекты, таким же образом, как и к фонам. То есть, приписыванием ключевого слова with и названия эффекта в конец команды вывода изображения (после указания позиции). Помимо эффектов появления можно показать изображение с эффектом выезда за полсекунды из-за края экрана: moveinright, moveinleft, moveintop, moveinbottom. Соответственно, справа, слева, сверху и снизу. Также есть эффект увеличения за полсекунды из точки: zoomin. Так, чтобы профессора по центру с выездом справа, нужно написать:
show prof norm at center with moveinright
Изображения без приписки эффекта выводятся мгновенно, то есть при последовательном выводе без эффектов изображений с одинаковым ярлыком игрок увидит только последнее. А с припиской — по одному, то есть в результате исполнения такого скрипта:
scene bg uni with fade
show prof norm with moveinleft
show prof smile with dissolve
сначала сменится фон с эффектом fade, затем слева въедет изображение профессора, а потом оно растворится в свою улыбающуюся версию. Можно сказать, они сформировали очередь, и пока одно изображение с эффектом не выведется, следующее за ним не начнёт показываться. Если, конечно, игрок не нажмёт на какую-нибудь кнопку, что прерывает все эффекты и заставляет движок сразу отобразить конечный результат. Если же нужно отобразить всю сцену, состоящую, скажем, из фона bg, изображения персонажа ааа слева и изображения персонажа bbb справа, с применением ко всей сцене сразу эффекта dissolve, то следует после команд на вывод изображений без эффектов написать строчку with dissolve:
scene bg
show aaa at left
show bbb at right
with dissolve
По историческим причинам это не одно и то же, что и:
scene bg
show aaa at left
show bbb at right with dissolve
Данный скрипт выведет фон и первое изображение персонажа моментально, затем второе изображение персонажа с эффектом dissolve.
Ren’Py следит за тем, что выведено, и при выводе нового изображения с тем же ярлыком, что и у уже находящегося на экране, старое изображение автоматически скрывается. Однако Ren’Py не следит за позициями, и поэтому при попытке вывести новое изображение в позицию, уже занятую изображением с другим ярлыком, новое изображение наложится на старое. Во избежание подобных эксцессов ненужные изображения следует скрывать. Делается это командой hide с ярлыком изображения, которое нужно скрыть, или же его полным псевдонимом. Так, чтобы немедленно скрыть любое изображение профессора, нужно использовать строчку:
В команде hide также может быть использован эффект, любой кроме zoomin и группы moveinчто-то. Зато есть их эквиваленты: moveoutright, moveoutleft, moveouttop, moveoutbottom — убирающие изображение за полсекунды с экрана вправо, влево, вверх или вниз соответственно; и zoomout, уменьшающий за полсекунды целевое изображение в точку.
Выбери свою судьбу!
Ладно, пока это может подождать. Пойдём дальше. Профессор объясняет, что такое визуальная новелла. Вот, она останавливается, словно ожидая вопросов. Самое время игроку повлиять на ход новеллы. Но как? Самый часто используемый метод — меню. Перед игроком возникают несколько вариантов реакции (например, варианты реплики в разговоре, или варианты действия в игровой ситуации), игрок выбирает один, и от этого выбора зависит дальнейшее течение повествования. В Ren’Py меню реализуются так: Сначала идёт строчка
открывающая блок, т.е. все последующие строчки до конца меню идут с отступом на четыре пробела больше. Дальше может быть строчка-сообщение, которое будет находиться в текстовом окне, когда меню на экране. Это простое высказывание. Затем идут варианты меню — строки, заканчивающиеся двоеточием. Каждый вариант открывает свой блок, в котором записываются результаты выбора этого варианта. Например:
Если реакции для какого-то пункта меню вообще не предусматривается, то есть данный пункт ничего не делает, в его блоке следует написать pass, как это сделано в примере с пунктом №2. Варианты могут быть любой длины, и их может быть любое число, главное, чтобы они все поместились на экране. Результаты выбора пункта меню также могут содержать любое число строк и состоять из любых команд, в том числе и из других меню.
А я помню…
Сначала знак доллара и пробел, затем имя переменной (одно слово, т.е. без пробелов) затем символ присвоения — знак равно, затем присваиваемое значение (в данном случае, False — «ложно»; «истинно» будет True). C цифровыми и строковыми переменными обращаются так же:
$ string_var = u»Это строка.»
$ ppoints = 0
С помощью цифровых переменных организуются концовки, базирующиеся на очках. Скажем, если игрок к исходу новеллы набрал менее половины из возможных очков, его ждёт плохая концовка, если более половины, но не все, то хорошая, а если все возможные, то наилучшая. Или, концовка зависит от того, какая из нескольких переменных имеет наибольшее значение (Скажем, в переменных хранятся значения атрибутов — силы, ума и удачи. Если наибольшее значение имеет атрибут силы, то игрок стал чемпионом мира по тяжёлой атлетике. Если ум, то игрок получил Нобелевскую премию по всем наукам. Если же удача, то игрок выиграл в лотерею миллиард рублей. И ещё какие-нибудь концовки в случае ничьих).
В нашем случае мы воспользуемся логической переменной для отметки, был ли задан вопрос, и цифровой для хранения набранных игроком очков. Присвоим им начальные значения (False и 0 соответственно) в блоке init. В блоке результатов выбора пункта меню с вопросом присвоим логической переменной значение True (тогда если игрок выбрал другой пункт меню, логическая переменная останется с False). В этом же блоке заведём ещё меню (скажем, преподаватель спрашивает игрока, как он сам считает, каков ответ на его вопрос) и в блоке результатов пункта меню с правильным ответом увеличим значение цифровой переменной на единицу. Делается это следующей строчкой:
Если в случае, если условие ложно, делать ничего не нужно, то else со своим блоком просто не пишут.
Можно также создать цепочку проверок, каждая следующее из которых осуществляется, только если все предыдущие оказались ложны:
Заодно в блоке результатов первого или второго пункта во второй раз увеличим значение цифровой переменной на единицу.
Вызовите доктора!
Для пущего интереса вновь сделаем в одном из пунктов ещё одно меню. Но на этот раз не будем загромождать блок результатов пункта, а вынесем реализацию этого меню в другое место. И в нужный момент передадим туда управление, чтобы дальше новелла исполнялась с этого места кода. Для этого нужно во-первых обозначить нужное место меткой, а во-вторых перейти по этой метке. В Ren’Py возможно два варианта переходов: прыжок, когда управление просто передаётся на указанную метку и исполнение игры идёт с обозначенного меткой места, и вызов, когда управление передаётся на метку, а по окончании управление возвращается на строчку, следующую за вызовом. Нам, нужен именно вызов. Сначала пишем реализацию вынесенного куска скрипта, которую будем вызывать: после окончания меню, откуда будет идти вызов, пишем:
label submenu_priority:
return
Обратите внимание: Блок метки, в котором записана нужная нам реализация, нужно закончить ключевым словом return — эта команда и вернёт управление в точку вызова. Также, надо удостовериться, что обычным образом в этот блок игра никак не попадёт. Для этого как раз перед меткой submenu_priority сделаем конец игры. Осуществляется это той же командой return. Можно объяснить сей факт так: игра вызывается из главного меню и в конце возвращает управление туда. Теперь нужно выполнить сам вызов. Для этого в блоке результатов пункта меню, где надо осуществить вызов, пишем:
Только, когда вы закончите писать скрипт, если используете вызовы, ОБЯЗАТЕЛЬНО запустите вспомогательный инструмент «Добавить From к Call’ам» из пункта «Инструменты» ЦУ Ren’Py! Без этого структура вызовов рискует не заработать в конечном варианте игры, что вы будете распространять.
Спой, светик, не стыдись…
Хм, если оставить всё как есть, конец у данной игры выйдет какой-то оборванный. Лучше сделаем так: После того, как игрок задал второй вопрос (первый, если в первом меню он выбрал пункт «Ничего не спрашивать»), звенит звонок, преподаватель отпускает всех и идёт определение концовки. Но как заставить звонок прозвенеть? Логично будет проиграть звуковой файл. Ren’Py делает это по команде:
Звук должен быть в файле формата WAW и лежать в рабочей папке проекта. (Конечно, можно завести в рабочей папке отдельную подпапку для звуков, так же, как и для картинок, только тогда надо будет добавлять имя папки перед именем файла). Данная команда проигрывает указанный звуковой файл единожды. При этом если до этого проигрывался ещё какой-либо звуковой файл, его проигрывание прерывается. Во время проигрывания звука игра не останавливается. Поэтому, если по задумке во время воспроизведения звука больше ничего не должно происходить, стоит воспользоваться командой паузы:
Сначала знак доллара, затем ключевое слово renpy.pause, потом в скобках длительность паузы в секундах. Правда, при нажатии игроком на какую-либо управляющую клавишу или кнопку мыши пауза прерывается, как и любой эффект. Также Ren’Py умеет воспроизводить фоновую музыку. Это делается следующим образом:
play music » имя_файла_с_музыкой.ogg «
Музыка может быть в формате OGG, MP3 или MIDI и лежать там же, где могут лежать все остальные ресурсы. Данная команда проигрывает указанный музыкальный файл постоянно, то есть при достижении конца воспроизведение начинается сначала. При этом если до этого проигрывался ещё какой-либо звуковой файл, его проигрывание прерывается. Если нужно остановить проигрывание музыки, применяется команда:
Аналогично, если нужно остановить проигрывание звукового файла, применяется команда:
Всё хорошо, что хорошо кончается.
Всё, что осталось, это определить, какую концовку заработал игрок. Поскольку мы считали достижения игрока в очках и максимум, достижимый в данном примере — 2, то определение сводится к цепочке проверок, начиная с максимума. Также, неплохо был бы вывести сообщение об обретенной концовке не в тестовом окне, а, скажем, по центру экрана. Это достигается путём использования специального персонажа centered. Собственно код, определяющий концовку, будет выглядеть так:
Ветвление как форма размножения.
show prof norm at right
show yuki norm at left
Заодно это автоматически уберёт образ преподавателя из центра, где он находился раньше, вправо.
Одновременно на экране может находиться сколь угодно много изображений персонажей, только при большом их числе многие будут перекрываться. Впрочем, обычно на экране присутствует не более трёх, в трёх предопределённых позициях. Вот поэтому изображения персонажей делают не шире трети экрана.
Герой с соседкой разговариваются, и всё внимание героя сосредотачивается на ней. Здорово было бы изобразить это сдвигом изображения профессора за границы экрана, а соседки — в центр. Можно реализовать это, скрыв изображение профессора с эффектом moveoutright, и затем показав изображение соседки в центре:
hide prof with moveoutright
show yuki norm at center
Но лучше было бы всё это совершить единым движением. Этого можно добиться, показав изображение профессора вне экрана справа, изображение соседки — по центру, и применив к ним эффект move. Он находит изменяющие своё положение изображения и сдвигает за полсекунды их из старого положения в новое. Нужный кусок кода выглядит так:
show prof norm at offscreenright
show yuki norm at center
with move
hide prof
Нужно не забывать скрывать ненужные изображения.
По мере разговора игроку будет предлагаться реагировать на высказывания собеседницы, и, если реакция её не устроит, лицезреть прекращение ветки, плохие окончания и конец игры. Если же все реакции окажутся подходящими, игрок придёт к хорошей концовке. Подобное построение сюжета носит название линейного с препятствиями (в отличие от вариативного у ветки из первого файла скрипта, где разные реакции игрока пускали сюжет по различным линиям в рамках единого сюжета, или ветвящегося, если брать эту игру в целом, где сюжет в зависимости от решений игрока идёт по практически независимым веткам).
Конец игры в данной ветке можно обставить обычным return’ом, но, вероятно, лучше сначала сделать титры. А ещё лучше, чтобы титры предваряли завершение и первой ветки. Для этого разместим титры (обычные высказывания с прославляющим создателя и всё, с помощью чего он создал подобный шедевр, текстом) в блоке метки (скажем, credits), помещённом в первом файле после определения концовки, но до завершающего игру return’a. А в концовках ветви из второго файла поместим команды прыжка по этой метке. Тогда первая ветка попадёт в титры своим ходом (ведь прерывающий ход игры return стоит после блока с титрами), а вторая ветка — прыгнув по метке титров. И конец игры будет происходить в одном месте.
Завершающие штрихи.
Ну вот, работа со скриптом игры завершена. Теперь не мешало бы подправить разные мелочи, вроде заголовка окна или фона главного меню. За это и многое другое отвечает файл options.rpy. Все опции снабжены подробным комментарием. Первое, что нужно сделать, это поменять config.developer = True на config.developer = False. Это запретит пользователю применять приёмы, предназначенные для облегчения жизни разработчика, такие как быстрая перезагрузка игры по нажатию Shift+R или вывод значений всех переменных по нажатию Shift+D. Следующее, это установить нужный заголовок. Находим config.window_title и вписываем в кавычки нужное название. В нашем случае строчка будет выглядеть так:
config.window_title = u»Знакомство с Визуальными Новеллами»
Затем нужно установить фон для главного меню и внутриигрового меню (доступно во время игры по нажатию Esc). Для этого присваиваем строки с именами нужных файлов переменным mm_root и gm_root. В нашем примере:
mm_root = «Images/uni.jpg»
gm_root = «Images/uni.jpg»
Дальше стоит задать, будет ли игра иметь звуковое, музыкальное и голосовое сопровождение, присвоив значения True, если да, или False, если нет, следующим переменным: config.has_sound (звук), config.has_music (музыка) и config.has_voice (голос). Вообще, в этом блоке есть ещё и переменные, отвечающие за звуки интерфейса, но по умолчанию они закомменчены. Самая интересная — это config.main_menu_music, управляющая музыкой, которая должна играть в главном меню.
С помощью этой группы переменных можно поменять положение главного меню:
# style.mm_menu_frame.xpos = 0.5
# style.mm_menu_frame.xanchor = 0.5
# style.mm_menu_frame.ypos = 0.75
# style.mm_menu_frame.yanchor = 0.5
Если, конечно их раскомментить (убрать решётку).
xpos и ypos определяют точку на экране, а xanchor и yanchor — точку собственно главного меню, которая будет соответствовать точке привязки на экране. Если значения — целые числа, то это расстояние в пикселях от верхнего левого угла экрана и главного меню соответственно. Если же, как по умолчанию, десятичных дроби, то они воспринимаются как доли ширины и высоты экрана и главного меню соответственно.
Напоследок необходимо сказать ещё о двух переменных. Только их значения, по уму, следует устанавливать в самом начале работы над игрой. Ибо они контролируют разрешение экрана игры, от которого зависят размеры игровых изображений. config.screen_width устанавливает ширину экрана, а config.screen_height — высоту. Важно: стоит придерживаться стандартных расширений, иначе при переключении в полноэкранный режим могут быть глюки. По умолчанию установлено:
config.screen_width = 800
config.screen_height = 600
Вот, в сущности, и всё. Теперь осталось только хорошо протестировать игру, отловить все дырки в игровой логике и просто очепятки, и можно готовить к выпуску. Также необходимо не забыть запустить из пункта «Инструменты» ЦУ «Добавить From к Call’ам» («Add From to Calls»), если в игре используются вызовы (call) и «Проверить скрипт (Lint)», обнаруживающий шероховатости, могущие плохо сказаться на работе игры на некоторых платформах.
В любом случае, для отправки «на золото» служит команда «Выпуск игры» («Build Distributions») из всё того же пункта «Инструменты». Сначала игру ещё раз проверят Lint’ом, после чего спросят, хотим ли мы продолжать (если Lint что-то нашёл, стоит выбрать «Нет» и исправить; иначе можно смело жать «Да»). Затем последует риторический вопрос «Хотите ли вы, чтобы Ren’Py создал распространяемые архивы для Windows, Linux x86 и MacOS X» (опять «Да»). Потом спросят имя игры (сразу введено имя проекта и в подсказке предлагается дописать версию) — вводим что надо, затем жмём Enter. Наконец спросят, файлы каких расширений вы не хотите включать в финальную версию — можно смело жать Enter ничего не меняя. Теперь нужно немного подождать, и можно забирать готовые архивы из папки Ren’Py. Поздравляю, создание визуальной новеллы завершено.
Узнаем как создать визуальную новеллу самостоятельно: полезные советы и рекомендации
Сейчас довольно популярным стал такой игровой жанр, как визуальная новелла. Разрабатывают новеллы не только профессионалы своего дела, но и любители. Как самому сделать визуальную новеллу? Какие особенности у этого жанра? Какие программы можно использовать для создания визуальных новелл?
Что такое визуальная новелла
Перед тем как ответить на вопрос о том, как создать визуальную новеллу, стоит немного углубиться в суть понятия. Визуальная новелла – это жанр компьютерных игр, который характеризуется не очень высокой интерактивностью. В процессе игры на экран выводятся изображение и текст, игроку же предстоит переходить от одного диалога или действия к другому. Изредка игроку будет предоставлен выбор, от которого зависит дальнейший ход игры. Этот жанр появился в Японии, а потому большинство визуальных новелл выполнены в стиле аниме.
Иногда визуальные новеллы отождествляют с симуляторами свиданий. Выполнены они в одном стиле, но имеют разную суть. В визуальной новелле важен сюжет, и от выбора игрока зависит дальнейший ход истории. В симуляторе свиданий же главной является стратегия игрока, направленная на его общение с окружающими персонажами и завоевание симпатии.
Игровой процесс
Игроку в визуальной новелле предстоит делать выбор, который и будет влиять на дальнейшее развитие событий в игре. Обычно это какое-либо действие, либо выбранный из перечня фраз ответ. Зачастую визуальные новеллы имеют несколько концовок, и именно выбор игрока приведет к одной из них.
В визуальных новеллах довольно много текста, что помогает глубже раскрыть сюжет и персонажей. Некоторые новеллы могут включать в себя и мини-игры, которые необходимо пройти, чтобы продолжить основную игру. Визуальные новеллы в Японии озвучиваются профессиональными актерами, специально для них пишется музыка.
Чаще всего повествование в игре идет от первого лица. Игроку предстоит пройти своеобразный квест, прежде чем добиться основной цели или дойти до концовки.
В процессе игры на экране мы можем увидеть набор фонов и спрайтов персонажей (движущееся изображение). Главный герой остается «за экраном». Под изображением находится строка, в которой появляется текст. В значимые моменты на экран выходят более детализированные арты, которые изображают происходящее событие. Открыть все арты можно, только пройдя игру несколько раз и принимая каждый раз разные решения.
Визуальные новеллы на русском языке
Это жанр интерактивного искусства, быстро набирающий популярность в России. Происходит это за счет переведенных на русский язык иностранных визуальных новелл (в большинстве случаев японских). Но есть и попытки создать «свой продукт». Можно выделить следующие довольно известные игры:
Также стоит отметить большое количество любительских проектов. Потому многие поклонники жанра задаются вопросом: как создать визуальную новеллу самому? Существует ли такая возможность вообще? С ростом популярности жанра увеличивается количество визуальных новелл, созданных в России. Проводятся конкурсы среди создателей новелл, под проекты создаются целые команды. В целом жанр имеет большие перспективы в России, а игры имеют большой спрос среди обывателей.
Как создать визуальную новеллу
Стоит помнить, что тремя главными составляющими визуальных новелл являются: графика, текст и звук.
В визуальной новелле должно быть много текста, причем он должен вызывать желание прочитать его, а не пропустить и идти дальше. Увлекательный сюжет – главное преимущество данного жанра перед другими. Потому важно изначально хорошо продумать и спланировать канву сюжета. Также стоит хорошо продумать варианты выбора игрока: они должны влиять на ход истории и ее концовку.
Графика является важной составляющей визуальной новеллы. В каком стиле она будет выполнена, зависит от пожеланий и целей автора, однако не стоит забывать, что плохая графика вряд ли вызовет желание провести несколько часов за игрой. Графика должны быть приятна глазу.
В Японии диалоги в игре озвучивают сэйю (актеры озвучивания), но вполне можно обойтись и без этого. Однако очень важной составляющей визуальной новеллы является музыка. Именно она призвана поддерживать атмосферу и помогать концентрироваться игроку на происходящем.
Сценарий
В первую очередь при создании нового проекта необходимо продумать сценарий будущей игры. Важным этапом создания хорошего сценария является написание плана. Как только вы придумаете, о чем именно будет ваша история, необходимо сделать небольшие наброски: пересказать в них кратко весь сюжет и будущую концовку или концовки. Также важно уже на этом этапе примерно понимать, где именно игроку предстоит сделать выбор, ведь от этого будет зависеть дальнейшее развитие сюжета.
Не менее важными в визуальных новеллах являются персонажи, которые будут взаимодействовать с главным героем. Автор должен знать о своих персонажах чуть больше, чем читатель, вот почему важно заранее хорошо продумать персонажей: их характер, мотивацию, достоинства и недостатки.
Визуальные новеллы в основном состоят из диалогов, вот почему важно сделать их живыми, интересными и не топорными. Не стоит добавлять в них слишком много «воды». Персонажи должны общаться между собой, как живые люди.
Графика
Важной составляющей визуальной новеллы является графика. При работе над новым проектом важно продумать не только захватывающий сюжет, но и примерно представить, какая будет использована стилистика в игре. Если вы сами обладаете художественными навыками, то можете осилить прорисовку игры с помощью различных графических редакторов. Однако, если рисовать не умеете, следует подумать о привлечении художника со стороны.
В графике новеллы есть три составляющие:
Вы можете создать фоны сами или поискать их на разных сайтах с картинками. Не стоит только забывать о лицензии на использование и авторском праве. Лучше хорошо изучить правила площадки, которой вы собираетесь воспользоваться.
То же касается и спрайтов. Можно поискать их на просторах Интернета, нанять художника или нарисовать их самому.
Программное обеспечение
Благодаря популярности игр появилось множество программ для создания визуальных новелл. Большинство из них на японском языке, но есть и русифицированные.
Можно перечислить некоторые из программ, служащих для создания визуальных новелл:
Таким образом, создание визуальной новеллы – это трудоемкий и довольно сложный процесс, который, однако, вполне можно освоить в одиночку. Для этого достаточно обладать определенным количеством знаний и умений, а также трудолюбием и фантазией.
Источники информации:
- http://habr.com/ru/post/483818/
- http://anivisual.net/blog/2021-10-19-774
- http://dtf.ru/games/1092092-kak-ya-sozdaval-na-unity-svoyu-vizualnuyu-novellu-tolko-odin
- http://stopgame.ru/blogs/topic/104070/razrabotka_vizualnoy_novelly_v_odno_lico_slaboumie_i_otvaga_ili_istoriya_uspeha
- http://habr.com/ru/post/303476/
- http://dtf.ru/flood/20845-kak-pravilno-delat-vizualnye-novelly-kpd-vn-chast-1
- http://dtf.ru/gamedev/635732-kak-ya-pisal-vetvistyy-scenariy-dlya-mobilnoy-vizualnoy-novelly
- http://www.renpy.org/wiki/renpy/rus/doc/tutorials/%D0%A0%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE_%D0%B4%D0%BB%D1%8F_%D0%BD%D0%B0%D1%87%D0%B8%D0%BD%D0%B0%D1%8E%D1%89%D0%B8%D1%85
- http://autogear.ru/article/385/903/kak-sozdat-vizualnuyu-novellu-samostoyatelno-sovetyi-i-rekomendatsii/