Открыть главное меню

Разработка Blue Lacuna: 12 уроков, выученных Аароном Ридом

Оригинал статьи: Developing Blue Lacuna: 12 Lessons Learned by Aaron Reed

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

Это могли быть вы, за такую несмешную шутку, или Эндрю Плоткин, чей Hunter, In Darkness можно винить за открытие для меня современной IF. Это мог быть даже Грэхем Нельсон, !tiring swim across the Atlantic or no!, за создание серии все более правополушарных языков, которые позволяют все более никудышным программистам (читай: мне) писать игры.

Так или иначе, человеком, которого нужно было тогда бить, скорее всего был я. Я сделал много ошибок, разрабатывая Blue Lacuna, ошибок, которые можно было избежать, если бы другие авторы больших IF выступили со своими советами и рекомендациями.

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

Однако, если вы уже отправились или еще только планируете купить билет на путешествие по длинной дороге разработки полноразмерной IF, вас могут заинтересовать некоторые вещи, которые я узнал за месяцы (читай: годы) создания Blue Lacuna. Вы заметите, что многие эти вещи можно применить к любому большому проекту, связанному с программированием, потому что, чем больше становится ваша игра, тем меньше это похоже на баловство с текстовыми квестами и больше похоже на серьезное программирование, и неважно, сколько очаровательных естественно-языковых конструкций Грэхем добавит в Inform 7. Кстати, вы также заметите, что некоторые из советов специфичны для этого языка, но, надеюсь, честолюбивый человек сможет сделать нужные выводы в независимости работает ли он на Inform 6 или TADS, или жаждет создать первый квест в миллион слов на SUDS.

Содержание

№1 Разработайте стратегию сохранений.

Примерно через три месяца разработки Blue Lacuna, когда я построил большую часть карты, добавил большое количество описаний локаций, запрограммировал базовые паззлы и даже начал работать над вычурными ответами на взаимодействие с животными, я случайно потерял весь мастер-файл.

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

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

За прошедшие два года появилось много хороших утилит для автоматического сохранения, так что лень больше не служит оправданием для отсутствия бэкапа. Маки с 2007 года снабжены Time Machine, которая каждый час сохраняет все ваши данные на внешний носитель; бесплатный сервис Mozy, доступный для Маков и PC, автоматически сохраняет до 2 Гб данных на защищенном сервере. Многие FTP-программы имеют функцию автосинхронизации, которая может быть настроена на сохранение папки с вашего компьютера в папку на вашем веб-сайте. Есть много и других решений, но ключевые слова здесь автоматически и ежедневно; все, что требует от вас каких-то усилий, например, запись болванки, обречено на забытие в самый неподходящий для этого момент.

Автосохранение отличается от контроля версий, который тоже неплохо было бы иметь, но его настройка куда сложнее для не-гиков. Контроль версий отслеживает все изменения, внесенные в файл, и позволяет сравнить нынешнюю копию с любой предыдущей. К сожалению, хороших утилит для легкого контроля версий не так уж и много (честно, я ни одной не нашел), да и информовский IDE-формат не способствует легкой интеграции с подобными программами. (Встроенная система версий была бы замечательным дополнением к Inform 7, особенно с расширениями, которые вы используете).

№2 Не меняйте дизайн.

Blue Lacuna развивалась. И как развивалась. Она должна была начаться в Tomahna (вы, фанаты Myst, знаете, о чем я говорю) и быть интерактивной фан-фикшн. Семь сцен сновидений были закончены прежде, чем я изменил внутреннюю механику, и мне пришлось полностью их переписать. В окончательной версии было три эпилога, но за время разработки я написал как минимум в два раза больше концовок. Диалоговая система постоянно нуждалась в новых функциях, патчилась и патчилась пока не превратилась в почти некотролируемый бардак. Я продолжал придумывать новые действия, которые, как я думал, должен был делать Progue, и нырял в этот запутанный код, чтобы добавить их; в результате он вел себя не только необычным, но и невозможным, как я думал, образом.

В результате всего этого я проводил значительную часть своей жизни, в крайнем разочаровании и глубоком отчаянии уставившись на сообщения вида: "Progue, похрапывая, проплывает мимо вас по пустыне." Большую часть этого можно было избежать, если бы я с самого начала определился с тем, что он должен и чего не должен был делать, а потом придерживался разработанного дизайна вместо слепого программирования.

Какое-то количество проб, вычищений и переработки всегда сопровождает любой творческий проект. Для вашего дизайна и игровых идей естественно развиваться со временем. И Inform 7 поддерживает использование вами подхода повторений, "проб и ошибок".

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

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

Как только у вас появился дизайн, еще раз продумайте его. Есть ли в нем сценарные ветки или паззлы, или диалоги, или комнаты, которые вы не очень хотите программировать в ближайшем будущем? Это может знаком того, что они скучны или многословны, или проходятся как-то странно и вы должны изменить их прямо сейчас. Есть ли области, которые вы мысленно избегаете, думая: "Я разберусь с этим, как только сяду программировать." "Опасность!" Разберитесь с ними сейчас.

Также для того, чтобы выявить недостатки в дизайне, вы можете пригласить друзей и пробежать с ними по сценарию, как если бы это была ролевая игра: "Что ты будешь делать дальше?" Если ваш игрок сбивается с толку или скучает в некоторых секциях, или вы понимаете, что неудобно или сложно пройти через данную сцену, это знак того, что требуется еще одна переработка.

Весь смысл в том, чтобы как можно больше перепробовать и развить до того, как вы начнете программировать.

№3 Как можно раньше обзаведитесь поддержкой.

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

Конечно, они незаменимы при нахождении опечаток, неработающих паззлов, объектов, нуждающихся в лучшем исполнении и для общей полировки. Но есть довольно четкий лимит на объем изменений, который вы сможете внести на финальных стадиях своего проекта (смотри предыдущий пункт). Если у ваших тестеров проблемы с общей структурой, с персонажами, стилем, диалоговой системой, передвижением или механикой -- ну, вы поняли, с самой игрой -- все, что вы можете надеятся сделать, это прилепить несколько патчей на основные проблемы (которые скорее всего введут новые баги и будут не самым идеальным решением).

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

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

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

(Заметка: вы должно быть думаете, что не у каждого есть своя маленькая армия тестеров, выстраивающихся в очередь, чтобы потестить еще не законченную игру, как например у Дэвида Уилда. Без проблем. Найдите трех других людей, которые не Дэвид Уилд, и договоритесь быть тестерами в игровых проектах друг друга.)

№4 Проводите свои эксперименты сначала на маленьких играх.

В Blue Lacuna не меньше дюжины странных и экспериментальных элементов. Через несколько лет разработки, я решил, что мне нужно знать чужое мнение о них: подсвечиваемых ключевых словах, диалоговой системе, некомпасной навигации. Я решил отправить предварительную версию на Spring Thing 2008 с готовыми основными системами, но лишь с первой половиной сценария. Я надеялся, что участие в конкурсе послужит толчком к публичному обсуждению и отзывам, и так я увижу, что люди думают о моих экспериментах.

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

После обдумывания я понял, что если бы я выбрал одно из этих нововведений, использовал его в одной, более короткой игре и уже с ней участвовал в Spring Thing, то я, возможно, получил бы более сконцентрированное на плюсах и минусах эксперимента обсуждение. Затем я бы принял во внимание все советы и встроил этот кусочек в свою эпопею, или настроил и исправил его, если нужно.

В качестве альтернативы я мог анонсировать "открытую бету" (как недавно и с успехом поступила Эмили Шорт для Alabaster) или выпустить игру вне конкурса, где нет жестких рамок правил о природе содержания и допустимых темах для обсуждения.

Дело в том, что, во-первых, конкурсы IF-сообщества не место для незавершенных работ (не считая IntroComp). Во-вторых, мест для незавершенных работ в IF-сообществе явно не достаточно. Если хотите, можете создать несколько.

№5 Пишите, помня об отладке.

Inform 7 отлично подходит для клепания игр с минимальным знанием о программировании. Но не так хорош в поощрении использования проверенных временем полезных навыков (например, "не использовать глобальные переменные"), что становится все большей проблемой с увеличением проекта. Вдобавок, он скрывает процесс компиляции и выполнения за ширмой дружелюбного интерфейса, и это усложняет понимание причин возникающих проблем.

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

И при этом, вдвойне важно задумываться о предстоящей отладке, пока вы создаете дизайн и программируете. Напишите себе побольше вспомогательных глаголов, которые позволят изменять важные игровые переменные, быстро перемещаться во времени и пространстве, начинать и останавливать специальные события, менять внтуреннюю работу NPC. Воспользуйтесь существующими отладочными расширениями, такими как великолепный "Simple Debugger" от Майкла Хилборна, который позволяет вам создавать внутриигровые объекты в качестве "точек отладки", а потом просто включать и выключать вывод отладочной информации, связанной с этими объектами.

Для Glulx-игр вы можете использовать расширение "Flexible Windows" от Йона Ингольда для создания тестирующих команд, которые открывают окна с беспрерывно выводящейся отладочной информацией. В Blue Lacuna у меня была команда для отслеживания главного NPC, которая открывала пятистрочное окно вверху экрана, показывающее несколько дюжин переменных, связанных с его состоянием, местонахождением, внутренними переменными, с участием в диалогах и со всем остальным, что мне могло понадобиться. Позже я создал "god mode", в котором через внутриигровое меню мог менять большинство из этих переменных.

Наконец, познакомьтесь поближе с уже существующими отладочными инструментами. Они не очень хорошо задокументированы: на сайте I7 посмотрите документ "Appendix B", главу "Test Template" для полной информации. Бывают полезными ABSTRACT, ACTIONS, GONEAR, PURLOIN, RANDOM, RELATIONS, RULES и RULES ALL, SCENES, SCOPE, SHOWME и SHOWVERB. Используйте TEST и/или Skein, чтобы быстро проверять работоспособность частей вашей игры.

№6 Отправляйте багрепорты.

История моей переписки на Gmail говорит, что за время создания Blue Lacuna я отправил 104 багрепорта для Inform 7. Большинство этих багов было или исправлено в следующем билде, или прокомментировано полезной информацией о моей проблеме.

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

№7 Продвигайте вашу игру за пределами IF-коммьюнити.

Чтобы продвинуть Blue Lacuna, я создал веб-эксперимент blueful, который задал тон повествованию, позволил людям свыкнуться с мыслью о печатаньи текста для раскрытия истории и не требовал ничего устанавливать или скачивать. Чтобы запустить этот эксперимент, я оставил сообщение на Facebook и по почте разослал ссылку всем, кого я знал, а также на сопутствующих форумах (один для фанов Myst, другой для любителей квестов). Многим людям он понравился и они переслали ссылку своим друзьям, некоторые небольшие блоги подхватили, а затем и блоги побольше; сработало. В результате Blue Lacuna, ссылка на которую была дана в конце blueful, скачали почти 2500 раз. Это гораздо больше людей, чем бывает в любой выходной на ifMUD.

Вы много вкладываете в создание своей игры. Так почему бы не сделать усилие и не привлечь больше людей поиграть в нее. Опубликуйте ее онлайн-версию** в интернете. Отошлите на сайты с играми от независимых разработчиков. Участвуйте в фестивалях. Продвигайте ее в сообществах, интересующихся вашей темой - Питер Непстад с успехом продавал свою 1893 любителям истории.

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

(** смотрите Zplet, Parchment, Muttonate, Flaxo или ZMPP для игр на z-code; проворные разработчики, !willing to spread the web-terp love to TADS and Glulx will receive boundless quantities of adoration from casual gamers worldwide!.)

№8 Выпускайте свои инновации в виде расширений.

До того, как начать свой проект, просмотрите страницу с расширениями для выбранного вами языка. Всегда есть возможность шанс того, что нужная вам функция уже разработана и протестирована кем-то. Зачем заново изобретать колесо?

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

Разработка Blue Lacuna привела к созданию таких расширений, как "Intelligent Hinting", позволяющего отслеживать продвижение игрока по сценарию и автоматически предлагать подсказки; "Remembering", распознающего ссылки на виденные раннее, но не наблюдаемые в данный момент объекты; "Numbered Disambiguation Choices," исправляющее !the dreaded disambiguation loop!; "Poor Man's Mistype" и "Smarter Parser", которые при использовании вместе увеличивают количество правильно распознанных команд на 50%. Все они доступны на странице расширений для I7.

№9 Используйте принцип "Делать, не показывать, ни в коем случае не рассказывать".

Принцип "Показывать, а не рассказывать" в кинематографе означает, что, так как фильмы — это больше визуальный жанр, то гораздо эффективнее показать что-то на экране, чем объяснить это через диалоги. (В качестве грубого примера сравните фильм Бегущий по лезвию с озвучкой и без).

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

Сцены снов в Blue Lacuna, которые служат цели рассказать предысторию сюжета, прошли через три стадии. Изначально, предыстория подносилась просто в виде текстовых блоков от лица рассказчика. Быстро стало ясно, что такой подход слишком скучный и неинтересный.

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

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

Это может проявиться разными путями. Вместо того, чтобы прочитать письмо, можете ли вы встретиться с автором в личной беседе? Вместо того, чтобы рассказать игроку о том, что его герой страдает избыточным весом, можете ли вы отразить это в реакции на подъём по лестнице? Вместо того, чтобы вываливать на игрока экраны текста и "заставок", можете ли вы убедить его взять инициативу на себя и самому выполнить необходимые в данный момент действия?

Во время проработки дизайна, неустанно повторяйте себе: "Делать, не показывать, ни в коем случае не рассказывать".

#10: Watch Out for Nonstandard Game Modes

Inform 7 is filled with assumptions that each turn of your game will be more or less like any other: every turn do this, instead of going do that. The more elaborate your game becomes, however, the more likely it is that some turns will not be like every other. During conversation, say, you might want a lot of things to work differently; or during combat. A tense chase sequence or drama-filled interlude might not want to play by the same rules as the rest of the game.

It's easy, of course, to override the default assumptions for your nonstandard turns (Every turn when combat is happening, do this.) But it's not so easy to remember to go the other direction: to overrule your generic rules to not apply when they shouldn't. Whenever you introduce a unique environment, all of your existing "every turn" rules (and instead rules, and before rules, and procedural rules, and so on) will still apply. In a very large project, you may have written some of these conditions months ago and not thought about them since. Here's another case where careful planning early on can save you from obscure, hard-to-find bugs. If you've pinpointed from the beginning any unusual conditions or states, you can work that into all of your rules from day one. (Instead of smelling when the player has an undamaged nose, say "You love the smell of napalm in the morning.")

A huge portion of Blue Lacuna's bugs were related to cases where I didn't think through the ramifications of special scenes or states that were added later in development: conversation, dreams, flashbacks, visits to other worlds, pivotal events, and so on. Sometimes conditions written before I considered these states were changing variables or altering rulebooks in utterly inscrutable ways. Take the time to plan for this stuff early on, and you'll save mounds of debugging time.

Another point with special environments is to make sure you test the edge cases, such as the first and last moves the condition holds true. It's not always clear what order various rules will run in: whether a scene will begin before an "every turn" rule runs, or whether this "last every turn" rule will actually be the last every turn rule. Develop testing commands that can show you exactly what order things are happening in, and make sure sequences are playing out internally the way you expected them to.

#11: Program Consistently

Natural language is sloppy, but programming is exact. The more complex your project gets, the more you're programming, and the more your sloppiness will come back to haunt you. Here are a few examples of ways you can be more exact.

Name Space Issues: If you call something a "blue door" in one spot, something else a "door" in another, then in some third spot have a condition like "if the door is open", you and your game won't necessarily be in agreement over which door you mean, which can lead to very subtle and frustrating bugs. Name things verbosely if possible, and use an object's full name whenever you know there are similarly named objects elsewhere in your code.

Scenes: Because scene names often refer to characters or items that are their own objects elsewhere in your code, I've found it helpful to hyphenate scene names. That way Harry, Sally, and When-Harry-Meets-Sally will never conflict with each other. If you're already using dashed-words for something, you could try camelCase, underscored_words, Things Written In All Initial Caps or even THINGS WRITTEN IN ALL CAPS. These conventions will also help remind you at a glance what sort of thing a bit of code is dealing with.

Extensions: When writing extensions, err towards more specific names rather than less specific names. If you're creating a new "window" kind, this might lead to terribly confusing errors for authors opening custom Glulx windows, implementing Windows PCs, or adding locations called The Space Under The Window. Instead, name your kind something like "latchable window" or "decorative window" or "interior/exterior window."

Be Wary of Pronouns: You can say things like "It is open" in Inform 7 code, but take extra care that you and the game agree on what you mean by "it." Whenever you're mentioning more than one object within the same paragraph, be especially wary, and take pains to do an in-game test that verifies your code is functioning correctly.

Use One Syntax: You can say "now x is y" or "change x to y," but it's a lot easier to pick one of those and always use it. Inform 7 often allows a lot of variation in the way commands are phrased, but you'll have to remember less syntax and your code will be more readable if you pick your favorite way of phrasing each command and stick to it.

#12: Comment Everything

In a natural language environment, it may seem that comments are redundant. What's the point of writing them when the code is so readable, anyway?

Use comments to record your design philosophies. Explain why you're using a list instead of a table or vice versa, or why you decided to make something a rulebook rather than an activity. If something needs to be a "check" rule instead of a "before" rule, note why in a comment. If you review some piece of code you wrote months ago and think "Why on earth did I do it that way?" then you forgot to comment.

Use comments to record solutions to complex or subtle bugs. If you need to declare something in a certain place or in a certain manner, comment why. If you fixed a bug by using a phrasing other than the one you'd normally use, explain in a comment why you had to phrase it that way. That way you won't accidentally "fix" your code to something that doesn't work again.

Use comments to record concessions to extensions, to explain workarounds to problems, to cross-reference other bits of code that may be far, far away.


Writing IF is always a chore, but you will spend much less time at it if you do a little homework first. Commit to coming up with a full and detailed design before you start fiddling around with code. Develop new systems as extensions to force yourself to think through their design, and allow others to benefit from your work. Get other people involved in the testing and design as early as possible. Plan your code to be debugged and to hold up no matter how complex it gets.

If I'd had all this advice four years ago, I could have finished two or three games since 2005. Just think: we could all be playing Blue Lacuna 2: Electric Blue-ga-lue or Whom the Telling Changed With A Vengeance right now.

OK, now I really do need to be punched in the face.