Наш опыт участия в 10К Apart, часть вторая: жмем дальше редактировать

Как мы уже писали , для соревнования 10K Apart, мы сделали настоящий rogue like rpg — « Mario The Fontanero ».

В комментариях нам дали несколько очень дельных советов, которые позволили нам сэкономить еще некоторое количество драгоценных байт. Добавив к ним пару собственных оптимизаций, мы выгадали достаточно места для того, чтобы добавить в игру несколько новых фич, по прежнему оставаясь в пределах 10 Кбайт:
  • Действие «Throw» . Теперь вы можете кидаться едой во врагов. Попадая в монстра, она наносит ему повреждение, но при этом исчезает.
  • Алхимия. Теперь можно смешивать еду с питьем в надежде получить что-нибудь новое. Так, «Jelly» + «Milk», например, даст в результате «Book of Healing» (этот рецепт вам очень пригодится на нижних этажах подземелья.)
  • В битве с кроликом придётся применить смекалку . Кролик теперь не нападает сам, а мирно пасётся. Но убить его стало гораздо сложнее!
  • Добавлен эффект confuse. Иногда главный герой конфузится от выпитого или в результате неудачных экспериментов.
  • Новый тайл для отображения починенной трубы . По многочисленным просьбам, мы добавили его, чтобы можно было отличить починенную трубу от сломанной.

А теперь, по традиции, поделимся с хабрасообществом описанием оптимизаций, которые помогли нам все это сделать:
  • whoozle переписал упаковщик в png так, чтобы он использовал greyscale png, в котором отсутствует палитра (это дало очень большую экономию, порядка 300 байт).
  • Парадоксально, но факт — увеличение ширины png дало значительный эффект! Мы увеличили png до 1024x17 и сэкономили ещё. И здесь опять IE9 подложил нам свинью: он перестал правильно определять размеры png и начал возвращать в скрипт странные размеры: 127x127. Пришлось жестко прописать размеры картинки прямо в загрузчике.
  • По совету bolk , мы отказались от pngcrush в пользу связки optipng+pngout, которая действительно даёт большую экономию за счёт своих продвинутых алгоритмов перепаковки.
  • Также lahmatiy нам подсказал, что замена «this.» (вместо слова «this») и «.length» на 1-2 буквенные символы (` и @@ соответственно) даст ещё больший выигрыш.
  • Ну и, в конце концов, мы просто переписали часть кода.

Итоговый размер игрушки остался практически прежним — 10231 байт, но играть в нее теперь стало намного веселее.
blog comments powered by Disqus

комментарии с хабра ( 70 )

  • Вот уж точно, совершенству нет предела :)

    ответить

  • Надеюсь, Ваше детище займёт первое место. Проголосовал.

    ответить

  • Кролик зло :D Не подкопил снарядов что бы его угрохать :)

    ответить

  • НЛО прилетело и опубликовало эту надпись здесь.
    • Ну опера не заявлена в условиях конкурса потому лишний вес не разумно добавлять, да и не грузил у меня турбо если честно сайт )

      ответить

    • Думаю, проверять изображение не обязательно, достаточно будет обернуть eval в try/catch. Но все это чистый (неупакованный) код, которого у нас осталось всего 9 байт :)

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

      ответить

  • шикарно, щас пройду снова, а уровни сложности не добавить уже? скажем
    easy=(hp,dmg)
    normal=(hp,dmg)*2
    hard=(hp,dmg)*3
    можно также реализовать факелы как в классической мории

    ответить

  • Забавная игрулька :)

    Если я выбрал какое-либо действие с предметами из инвентаря,
    например, кинуться яблоком, то я не могу его отменить?

    ответить

    • Во время выбора предмета, который вы собираетесь выкинуть или съесть, можно нажать любую не относящуюся к делу кнопку («вверх», например) и действие отменится. А во время выбора направления уже ничего отменить нельзя, да.

      ответить

  • Это толи баг толи фича, если поджидать монстра за углом и атаковать сбоку то он почти никогда меня не коцает, выпил совсем чуть чуть питья, еду не ел, только пару раз кидался на уровнях и вынес кролика бросками даже с ним не контактировал. Книжки не использовал.

    ответить

    • Ну и проголосовал естественно.

      ответить

    • Большинство монстров убивал с первого удара ещё до того, как они покоцают меня. Нужно сделать так, чтобы количество клеток между Марио и монстром всегда было чётным, тогда Марио будет бить первым.

      ответить

      • Если оно нечетно — достаточно нажать S и оно станет четным

        ответить

        • Ну с тем, как сделать его чётным, проблем вообще не должно быть)

          ответить

          • В стенку ткнуться или выпить-съесть-нахимичить что-нибудь, например

            ответить

  • А почему все такое маленькое? Вот так намного удобнее было бы.

    ответить

    • Эту бы картинку в топик

      ответить

      • Ее бы в игру, но что-то авторы топика игнорируют предложение.

        ответить

        • Нет, не игнорируем, такая идея была ещё в самом начале, но мы как-то забили, очень зря, конечно. :((

          ответить

          • А разве это не просто сделать? Я думала там есть какой-то простой параметр типа увеличения :)

            ответить

            • просто, но когда карта не влазит в экран, надо двигать view-port и всякое. :(

              ответить

  • В Firefox с вкл. настройкой «Искать текст на странице по мере его набора», если нажать не на ту кнопку, фокус уходит в поле поиска.

    ответить

  • PURE WIN!!!
    Got $199263280
    Being dead 0 times.

    ответить

  • Может запостите баг IE9 хотя бы в блог IE (лучше — в багтрекер)? Чтобы нам всем в дальнейшем не мучиться багами этого браузера.

    ответить

    • Как-то нехарактерно для m$ — считаться с разработчиками.
      Подскажите тогда адрес багтрекера, у нас есть ещё пара багов в заначке. :D

      ответить

  • можно и дальше жать
    позаменять всякие там return'ы например на тильду (51 раз) — ещё 300 байт js'a
    и например имя переменной distance удивляет: )

    ответить

    • замена ретурна как ни странно не дала никакого выигрыша. После зипа стало только больше. Мистика. :)

      ответить

  • Как убить кролика? :D

    ответить

    • закидать помидорами, например :)

      ответить

      • Как убить кролика если пришел на этот левл без единого помидора в кармане?:)

        Надо еще придумать что-то вроде индикатора хитпоинтов у монстров а то я кролика коцалкоцал на 1 хп, а скока осталось не понятно же

        ответить

  • Проголосовал! Желаю удачи!
    А мне вот вспоминается опыт программирования j2me midp1 под очень старые девайсы, сжатие и оптимизации на каждом шагу и тп

    ответить

    • Ыгы, со смехом вспоминаю Nokia S40.
      — Цвета пожаты до предела.
      — Все картинки сброшены в один файл.
      — Если в игре экранный буфер не нужен, а в меню — нужен (крайне редко — тем не менее, нашлась одна такая игруха), при нажатии на кнопку «Меню» отгружаются игровые данные и заводится этот самый буфер.
      — Меню предельно простые, неигровая графика большей частью векторная.

      Ну разве что грузилась быстро, укладывалась в «законные» пять секунд, на которые не обязательно ставить строку прогресса, достаточно индикатора «Ждите».

      ответить

    • Ещё оптимизации…

      — Если есть тригонометрическая таблица — в файл её!
      — Ну и, конечно, персонажи резались на мелкие кусочки, а потом в самописном софте из них собирали целые анимации.

      ответить

    • Мне почему-то вспомнился рассказ про 1 байт .

      ответить

  • отличный рогалик) нетхак напомнил.

    ответить

  • В рогалики не играл. Но всё равно забавно.
    Хорошо придумали с кроликом-убийцей.

    ответить

    • Это монти пайтон придумали)
      www.youtube.com/watch?v=XcxKIJTb3Hg

      ответить

      • По крайней мере в клипе не видел, как всё-таки его убить.
        Да, додумался быстро, подсказки рядом.

        ответить

        • Я расчитывал на то, что если босс от прямой атаки получает повреждение в 1hp, это явное указание на то, что ты делаешь что-то не так. Во всех j-rpg было такое :)

          ответить

          • Сорри, в JRPG тоже не играл. Но понятно сразу, что победить эту сволочь можно только окольным путём.

            ответить

          • Я имел в виду то, что остроумный способ убить монстра.

            ответить

  • сделайте изометрию ._.

    ответить

    • Не влазит в 10k, есть трудности с IE, хотя чем черт не шутит.
      Осталось порядка суток, не думаю мы что успеем. :)

      ответить

      • да пофиг на них, дайте нормально поиграть %-)

        ответить

  • вообще можно было еще байт 200 выиграть за счет return / indexOf / for / var / push и проч. Но, может быть, PNG и так уже ужал (8300 в PNG против 10000 кода).
    + все переводы строк можно было убрать в результирующем файле
    + массивы можно было записывать строкой, а потом ее разбирать

    P.S. так и не понял, как картинки/стили подгружаются

    ответить

    • Все эти оптимизации мы пробовали, кроме, наверное, indexOf. Никакая из них не дала ощутимого выигрыша, а иногда размер суммарный вырастал!
      Только что проверил — замена indexOf на `` дало ровно 1 (один) байт выигрыша. Бесполезняк )

      ответить

    • Стили лежат в том же упакованном javascript'е в виде строки: $('head').append($('<style>.... А картинки подгружаются сами после подключения css.

      Кстати, мы пробовали укоротить эту строку со стилями за счет автоматической подстановки вендорных префиксов ("-moz", "-webkit", "-o") у свойств border-radius, box-shadow, transform и т.п. Вроде сэкономили 100 байт, но после зипа наоборот стало весить больше, чем до оптимизации.

      ответить

  • ну и не забываем, что итеративный pngout -r позволяет выжать еще 6 байт

    ответить

  • Практически не сомневаюсь в вашей победе. Удачи.
    Сам собрался с силами и так же обновил свой «10k World», исправив ошибки с отрисовкой и перевод.

    ответить

  • Насчёт размеров картинок — проблемы ещё начинаются на мобилках, если PNG больше 960px в ширину. В данном случае пофиг, но на будущее стоит учитывать, а то я тут целый день волосы рвал почему вдруг мои CSS спрайты превратились в какашку…

    ответить

  • Похоже на баг- если нажимаешь «Give up» при починки труб- она всё равно чинится

    ответить

    • нет, это фича. по кнопке «give up» труба чинится, но тебе выплачивается только $1.

      ответить