Борьба за байты: что влезло и не влезло в Organic Matter
Много ли игры можно упихать в 37 килобайт? От чего пришлось отказаться при создании Organic Matter? Узнайте из этого выпуска дневников разработки! Спойлеры, слухи, скандалы… ну, вообще-то, в основном спойлеры.
Итак, работа над проектом понемногу шла к завершению, и тут после очередной доработки игра перестала запускаться. Я показал свои исходники Кесу ван Оссу (Kees van Oss), который уже помогал мне с кодом, и он ответил, что программа занимает слишком много места — перебор на целых 543 байта. Кес также любезно перечислил проблемные места, исправление которых могло помочь уложиться в рамки. Собственно, рамки как раз и стали одной из проблем: хотя текстов в игре было не так и много, вокруг каждого из них я сделал обрамление, чтобы они красивее смотрелись и лучше выделялись на фоне.
Рамочки без затей выводились символами кастомного шрифта. В результате получалось, что для оформления строчки длиной X нужно было потратить еще 2X+6 байт, не считая самой команды PRINT. Особенно отжирала память, конечно, речь заведующего космолабом, и Кес придумал для нее параметрические рамочки: число строчек и ширина для каждого блока болтовни считывались из оператора DATA, потом на основе этих параметров выводилась рамка, а потом в нее впечатывался текст. Для интересующихся — фрагмент кода:
LET I = 0; счетчик блоков текста
RESTORE
REPEAT 8
READ V; число строк
READ W; число символов =
LET M = 11; номер строки на экране, начинаем с 11-й
AT M,1
CHR 42: REPEAT W: CHR 61: ENDREPEAT: CHR 42; строка *====*
REPEAT V
ADD 1 TO M
AT M,1
CHR 124: REPEAT W: CHR 32: ENDREPEAT: CHR 124; вертикальные линии и пробелы между ними
ENDREPEAT
ADD 1 TO M
AT M,1
CHR 42: REPEAT W: CHR 61: ENDREPEAT: CHR 42; строка *====*
AT 12,3
IF I = 0
; PRINT "i don’t know who you are,"; этот текст пришлось вырезать
; AT 13,3 ;
PRINT "i suspect you were sent"
AT 13,3
PRINT "by the earth government."
ENDIF
IF I = 1
PRINT "we created this arboreal"
AT 13,3
PRINT "structure that powers our"
AT 14,3
PRINT "starlab."
; AT 15,3 ;
; PRINT "gives us food."; вырезано
ENDIF
<…>
ENDREPEAT
DATA 2 25 3 27 2 28 4 28 2 24 3 29 2 25 1 19 ;
К сожалению, вынести параметрические рамочки в отдельную функцию было нельзя, т.к. MPAGD поддерживает подпрограммы только на уровне машинного кода, а особо лезть в ассемблер я не хотел (это, конечно, первая ошибка того, кто хочет написать путную программу для «Спектрума», но не забудем, что изначально я вообще собирался просто сделать фейковый трейлер, не особо заморачиваясь). Тем не менее, некоторый выигрыш по памяти это решение принесло, однако в дальнейшем пришлось сократить и осмысленную часть речи начальника космостанции — в частности, реплику о том, что мутанты буквально растут, как груши, на дереве УОМ. Впрочем, для пояснения этой идеи я отгрохал в нижнем правом углу станции мутантский инкубатор и школу с ползающими мелкими личинками.
Пришлось отставить разговорчики и другим обитателям станции. Вначале я хотел, чтобы все персонажи, для которых доступна опция TALK, говорили хоть что-нибудь, но борьба за байты заткнула рты всем квестово неважным мутантам (а также лишила нас удовольствия пообщаться с туалетным указателем).
Стоящий слева профессор должен был просить у героя сдать кровь для опытов, но это взаимодействие в итоге реализовано не было.
Была у меня также мысль, что память станции хранится в повсеместно растущих ягодках, и после того как вы слопаете их определенное количество, у вас случается видение, рассказывающее очередной кусок сюжета. Задумка классная, но, чтобы она нормально работала, нужно было, чтобы съеденные ягоды оставались съеденными — иначе игрок сможет сожрать сколько угодно ягод, не исследуя станцию, а просто повторно приходя в один и тот же экран. Однако постоянство съеденности требовало дополнительных изворотов в коде. Дело в том, что по умолчанию все изменения на экране обнуляются, если вы выйдете с него, и даже в специальном режиме adventure исключение делается только для кирпичей, поставленных функцией PUTBLOCK, а те, что собраны с помощью GETBLOCKS (как те же ягодки) или прокопаны посредством DIG, все равно отрастают обратно. В общем, с этим я не стал возиться, поэтому съесть ягоды можно, но это ни на что не влияет.
Кстати, поскольку состояние спрайтов также не сохраняется, мне пришлось добавлять (через PUTBLOCK) блок с брызгами зеленой крови для застреленных мутантов, чтобы при перезапуске экрана они сразу же сталкивались с этим блоком и снова переходили в убитое состояние. Для движущихся мутантов так изящно эту проблему было не решить, поэтому я для себя решил, что их ряды постоянно пополняются — летающие прилетают из других частей станции, а мелкие ползуны вырастают на дереве.
Летающим мутантам вообще не повезло: изначально у них были «левый» и «правый» спрайт, но потом пришлось обходиться одним видом анфас (его, кстати, нарисовал мой сын). Кроме того, предполагалось, что если герой проявляет агрессию и станция входит в локдаун, летуны будут гадить на него, вызывая эффект, аналогичный нырянию в канализацию. Этот код (к счастью?) тоже уже не влез в игру.
В процессе дальнейшей оптимизации кода я понял, что у меня, например, обсчитывается столкновение ползучих мутантов с дверьми, хотя в процессе работы над игрой не осталось мест, где это могло бы произойти; точно так же был выпилен код для падения трупов, если мутант будет подстрелен в воздухе — с наземными мутантами такое просто не случается, а летуны в результате просто исчезают при попадании в них из бластера.
Тут пора заметить, что в MPAGD довольно сложно удалять уже созданные элементы, будь то тайлы, спрайты или комнаты. Во-первых, поскольку все они пронумерованы по порядку и обращение к ним происходит по номерам, выдергивание элемента из середины списка нарушает их нумерацию и в результате приходится переписывать соответствующий код. Поэтому вместо простого удаления спрайтов приходилось менять их со спрайтами из конца списка и удалять уже последние.
Во-вторых, из-за некоторой нескладности движка такое удаление может повлечь за собой неожиданные глюки. Так что лучше планировать все заранее, и мой любимый подход «придумаем всё по ходу разработки» тут, к сожалению, не очень эффективен.
В заключение расскажу, на какие жертвы НЕ пришлось идти. Я неоднократно порывался удалить одну или несколько комнат, и первыми кандидатами становились коридоры справа от пассажирского и грузового доков. Так, на каком-то этапе я решил убрать всю соответствующую вертикаль и, в частности, сжать первые два экрана в один:
Позже я подумал, что складской экран этажом ниже можно просто заменить некой пространственной аномалией, переносящей героиню из дока сразу к двигателю.
Но оба раза мой сын категорически сказал «нет» — и был абсолютно прав. Во-первых, эти экраны, пусть в них изначально ничего и не происходило, были важны для начального создания атмосферы, а во вторых они в MPAGD довольно хорошо пакуются, так что их удаление не больно-то помогло бы ужаться в рамки.
Кроме этого, я не удалял никакие из созданных блоков-тайлов, и наконец, из одного встроенного шрифта и одного кастомного мне удалось выжать целых три визуальных решения для текстов: «обычное» для служебных текстов/речи героя, «футуристическое» для речи роботов (заглавные буквы кастомного шрифта) и «органическое» для речи мутантов (строчные).
В итоге по-настоящему жалею я только о том, что не удалось вставить в игру больше текстов. Станция получилась небольшая, но симпатичная, обитатели её — достаточно разнообразными, и я даже смог сделать в игре два разных финала!
В следующем выпуске дневников речь пойдет о том, ради чего все и затевалось — о создании трейлера Organic Matter.
- 06 апреля 2021, 03:25
- 021
Тру инди геймдев!
Может тебе обратиться, к Сергею Смирнову (Gogin) он написал свой движок, на которой выпустил игру Nothing, как я понял там у него прям все тру...