JustPaste.it

Хакер - PICO-8. Играем и кодим на легендарной приставке, которой никогда не было

nopaywall

f1be72232cf9ef3cdb3e123e46e9e2f2.jpg

https://t.me/nopaywall

Если ты когда-нибудь пытался сделать игру, то знаешь, как это непросто и как много требуется времени и сил. Но так было не всегда. Pico-8 и другие фэнтезийные ретроконсоли — это попытка вернуть старые времена, когда игры делали на коленке и получали от этого максимум удовольствия. Давай посмотрим на Pico-8 поближе, разберемся, что и как делает сообщество, и полюбуемся на красивые демки, которые умещаются в твит.

Я занимался разработкой игр последние шесть лет, но прошлой зимой открыл для себя кое-что удивительное — мир фэнтезийных ретроконсолей. Если ты не знаешь, что это такое, то представь эмулятор старой приставки или домашнего компьютера. Ну, например, Super Nintendo или ZX Spectrum. Теперь представь, что этой машины никогда не существовало и всё, что у нас есть, — это эмулятор. Добавь к нему встроенный редактор кода, спрайтов, карт, звуковых эффектов и музыкальный трекер. Готово! Это и есть рецепт фэнтезийной консоли.

Одна из первых (или даже первая) фэнтезийных приставок — это Voxatron. Но настоящую популярность обрела не она, а ее младший брат — Pico-8. Этот проект начинался как редактор кода для Voxatron, но оказался настолько удачным, что не просто обрел самостоятельность и затмил предшественника, а перерос в целый феномен. За Pico-8 последовали и другие фэнтезийные консоли. В их списке, кстати, есть и мой (пробный и ныне замороженный) проект — neko8.

 

3a8f544cea2821e9e97e7b7eb7b0b2dd.jpg

INFO

Pico-8 стоит 15 долларов, но многие фэнтезийные консоли распространяются бесплатно. Например, LIKO-12 и TIC-80. Они еще довольно сырые, но если не хочется покупать Pico-8, то на них можно взглянуть.

При этом Pico-8 — это не «вещь в себе». Недавно появился замечательный пример популярной игры, созданной для фэнтезийной консоли и затем покорившей другие платформы. Эта игра называется Celeste. Ее первую версию двое разработчиков написали на Pico-8 всего за четыре дня. Позже полная версия будет выпущена в Steam, портирована на все современные консоли и соберет восторженные отзывы критиков.

 

Лимиты

Что делает Pico-8 такой особенной и чем, если говорить о разработке игр, она отличается от того же Unity? Как ни странно, лимитами. Консоль ставит очень жесткие рамки для разработки. По некоторым характеристикам Pico-8 можно сравнить с домашним компьютером восьмидесятых:

  • дисплей 128 на 128 пикселей, поддерживает 16 цветов;
  • 32 Кбайт памяти;
  • четыре звуковых канала.

С другой стороны, отсутствие ограничений по производительности и поддержка Lua в качестве встроенного языка программирования делают Pico-8 монстром по сравнению с настоящими старыми машинами.

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

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

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

Возьмем для примера игру Dank tomB, созданную @krajzeg. Автор умудрился запихнуть в картридж не только динамическое освещение, но и кучу других механик, таких как невидимые блоки, двигающиеся платформы, выключатели, которые можно активировать на расстоянии…

Я думаю, стоит уточнить, что Pico-8 не дает тебе никакого стартового кода. Ты не можешь подключить никакие библиотеки и все делаешь сам.

 

Небольшое путешествие по Pico-8

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

Итак, предположим, что ты купил Pico-8 на официальном сайте, скачал и запустил. Тебя встречает мигающий курсор терминала. Можешь набрать help, чтобы увидеть полный список команд.

 

Виртуальные картриджи

Каждый проект хранится на картридже — специальном файле. Консоль поддерживает два формата картриджей — текстовый (.p8) и PNG (.p8.png). Во втором случае при просмотре файла ты увидишь изображение картриджа и скриншот сохраненной игры, а ее код будет спрятан внутри.

То есть если ты возьмешь вот эту картинку и сохранишь к себе, то потом ты можешь загрузить ее в Pico-8 и запустить игру.

Вот такая вот темная магия стеганографии!

Давай установим несколько демок:

instal_demos cd /demos ls
3a8f544cea2821e9e97e7b7eb7b0b2dd.jpg

INFO

Любую папку можно открыть в файловом менеджере за пределами Pico-8, если написать folder.

В папке с картриджами появится подкаталог demos/, в котором лежат несколько примеров картриджей. Давай загрузим картридж jelpi.p8.

load jelpi.p8 run

Кстати, чтобы быстро запустить загруженный картридж, достаточно нажать Ctrl-R.

Pico-8 поддерживает до шести кнопок управления, назначение которым задает картридж. Обычно это стрелочки, X и Z/C. Чтобы прекратить выполнение программы на картридже, нужно нажать Escape.

Теперь начинается самое интересное! Давай заглянем «под капот» этого платформера. Из режима терминала жмем Escape и попадаем в режим редактирования загруженного картриджа (чтобы переключиться обратно, снова жми Escape).

Мы можем изменить здесь всё. Например, в начале есть пара переменных:

-- config: num_players 1 or 2 num_players = 1 corrupt_mode = false max_actors = 128

Давай изменим значение corrupt_mode на true и запустим картридж опять! Ладно, может, не стоило менять эту переменную…

Этим наши возможности не ограничиваются. Помимо редактора кода, можно использовать и все остальные — переключай вкладку и увидишь спрайты игры, карты, музыку и звуки. Можешь менять всё, что пожелаешь!

 

PocketCHIP

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

Увы, у создателей PocketCHIP, похоже, какие-то неурядицы: сначала они перестали принимать новые заказы, а теперь страница магазина и вовсе недоступна. Так что заиметь такую штуку сейчас можно разве что на вторичном рынке. Будем надеяться, что ситуация исправится!

 

Практика

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

Вот что у меня получилось в итоге.

Теперь разберем, как это было сделано. Чтобы создать новый картридж, используй команды reboot и save mycart_.

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

  • _init вызывается в самом начале, после загрузки кода;
  • _update вызывается каждый кадр перед _draw, отвечает за логику;
  • _draw вызывается каждый кадр, отвечает за отрисовку;
  • _update60 — аналог _update, но, если она определена, картридж будет работать на 60 fps (вместо 30 стандартных).

Остальные полезности можно подсмотреть в этой шпаргалке.

Вот пример простого картриджа (комментарии на русском, не пытайся вставить их в редактор Pico-8).

function _init() -- инициализируем глобальные переменные str="hello, world!" t=0 end function _update() t+=0.01 -- обновляем время end function _draw() cls() -- очищает экран local y=cos(t)*16+64 -- высота, на которой будет нарисован текст print(str,10,y) -- печатаем текст end

Важное замечание: тригонометрические функции в Pico-8 работают в диапазоне от нуля до единицы, а не от нуля до пи.

94ce2f9b42d3d78ef4ec91a971b7d507.jpg

WWW

Тем, кто не знаком с Lua, могу посоветовать замечательную вводную статью Learn Lua in 15 Minutes.

Давай применим наши знания тригонометрии и заставим точку вращаться по кругу.

function _draw() cls() local x=cos(t)*32+64 -- t — угол, 32 — радиус, 64 — центр local y=sin(t)*32+64 cicrfill(x,y,3,8) -- 3 — это радиус, 8 — цвет end

Что это за магическое число 8? Pico-8 имеет шестнадцатицветный экран, то есть никаким RGB и тем более RGBA здесь и не пахнет. Каждому числу от 0 до 15 соответствует цвет, например 8 — красный.

Одна точка хорошо, а десять лучше! Давай добавим еще:

-- в _init() cnt=10 -- в _draw() cls() for i=1,cnt do local a=t+i/cnt -- угол зависит от времени и i local d=32+sin(t+i%2*0.5)*20 -- пусть радиус будет меняться local x=cos(a)*d+64 local y=sin(a)*d+64 circfill(x,y,3,8+i%2) -- добавим чуть-чуть больше цветов end

Что за знаки процента, спросишь ты? Оператор % возвращает остаток от деления. Например 4%2 = 0.

Уже неплохо, так ведь? Чтобы не выглядело так монотонно, будем вращать красные точки в одну сторону, а желтые — в другую.

local m=(i%2==0 and 1 or -1) local a=(t+i/cnt)*m

И все-таки точки не выглядят так эффектно, как многоугольники. Pico-8 рисовать их не умеет, но это и не так сложно исправить. Давай создадим функцию shp(), которая будет принимать координаты фигуры, количество сторон, радиус, угол поворота и цвет:

function shp(x,y,cn,r,a,c) color(c) for i=1,cn do local an=a+i/cn -- угол сейчас local oan=a+i/cn-1/cn -- угол, который был при прошлой вершине line(cos(an)*r+x,sin(an)*r+y, cos(oan)*r+x,sin(oan)*r+y) -- и уже известный нам способ вращения точки -- функция line(x1,y1,x2,y2,c) рисует линию из точки (x1;y2) в точку -- (x2;y2) с цветом c end end -- в _draw() -- заменим вызов circ() на нашу функцию: shp(x,y,6-i%2*2,16,t+i/cnt,8+i%2) -- количество граней зависит от делимости i -- ну и добавим чуть-чуть декора: local ox,oy=calc((i/cnt+t*2)*m,8) circ(x+ox,y+oy,4,9+i%2) -- этот круг будет показывать угол вращения фигуры

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

function _init() t=0 cnt=10 end function _update() t+=0.01 end function _draw() cls() for i=1,cnt do local m=(i%2==0 and -1 or 1) local a=(i/cnt+t)*m local d=32+sin(t+i%2*0.5)*20 local x,y=calc(a,d) x+=64 y+=64 shp(x,y,6-i%2*2,16,t+i/cnt,8+i%2) local ox,oy=calc((i/cnt+t*2)*m,8) circ(x+ox,y+oy,4,9+i%2) end end function calc(a,d) return cos(a)*d,sin(a)*d end function shp(x,y,cn,r,a,c) color(c) for i=1,cn do local an=a+i/cn local oan=a+i/cn-1/cn line(cos(an)*r+x,sin(an)*r+y, cos(oan)*r+x,sin(oan)*r+y) end end
 

Tweet Jam

В комьюнити Pico-8 существует интересный формат для создания картриджей — tweet jam. По сути, код картриджа должен уместиться в 280 знаков (лимит твиттера, за вычетом тегов #tweetjam и #tweetcart, с которыми обычно постится код). Поверь мне, в эти триста знаков можно уместить настоящие произведения искусства! Вот несколько примеров.

Написана мной.

poke(0x5f2c,7)t=0pat={1,2,4,8,9,10,15,7}cls()function _draw()camera()for i=1,500 do circ(rnd(64),rnd(64),1,0)end camera(-64,-64)t+=0.001for i=1,130 do a=t+i/5000 x=sin(33*a)*cos(9*a)*64 y=sin(40*a)*sin(7*a)*64 circfill(x,y,3,pat[mid(0,#pat,flr(i/20))+1])end end

Написана @guerragames.

t=0 ::_:: t+=.001 cls(7) for p=0,1,.0005 do d=.7*p a=d*cos(p*t*8+t*10)+p*sin(t*10)-t*10 r=p*128 x=r*cos(a) y=r*sin(a) circfill(x+64,y+64,1+.9*sin(p*t+a*t*6),0) end flip() goto _

Написана @SeanSLeBlanc.

for i=1,16 do pal(i-1,sub("01289821",i/2,i/2),1) end cls() ::q:: z=t()/3 y=64 x=64 for i=0,128,.05 do x+=cos(i/30+z*2)*i/128 y+=sin(i/30+z*2)*i/128 circ(x,y,1,i*(1+sin(i/128+z)/2)*2) end flip() goto q
 

История Pico-8

Создатель Pico-8 — Джозеф Уайт, известный также по псевдониму zep. Он родился в Новой Зеландии и затем переехал жить в Японию. Когда Уайта спрашивают, как появился Pico-8, он обычно начинает рассказ с того, что в детстве он увлекался программированием на компьютере BBC Micro, который его отец купил для работы.

«Было что-то особенное в рисовании большими красивыми пикселями и печати программ на громоздкой клавиатуре, что-то, что резонировало с моим восьмилетним мозгом», — рассказывает Уайт. BBC Micro поставлялся без софта, если не считать вшитого в ПЗУ BASIC, поэтому для каждого проекта Уайт сам создавал простенькие редакторы спрайтов, музыки и уровней.

До двухтысячных годов разработка игр так и оставалась для Уайта хобби, а на жизнь он зарабатывал работой в кафе. В 2004 году Уайт написал программу Lex500, которая внешне напоминала эмулятор Amiga500 и тоже имела встроенный интерпретатор BASIC. Затем последовал эксперимент с воксельной графикой, из которого в 2010 году родился проект Voxatron. Его демонстрация на YouTube вызвала живейший отклик, и Джозеф Уайт отложил все проекты ради того, чтобы сосредоточиться на Voxatron. Постепенно он собрал небольшую команду единомышленников.

Предполагалось, что Voxatron будет не просто игрой, а редактором, в котором каждый сможет делать свои игры и передавать другим. Хорошенько поломав голову, Уайт придумал называть такие игры картриджами. Позже эта идея перекочует и в Pico-8.

Собственно Pico-8 родился как попытка сделать скриптовый движок Voxatron на основе Lex500. Затем возникла идея использовать Pico для прототипирования будущей воксельной игры. Именно так в нем появился свой набор редакторов спрайтов и музыки. Кстати, разрешение 128 на 128 соответствует «срезу» объемного уровня Voxatron.

Другой занятный факт: Pico-8 назван в честь Pico Pico Cafe — заведения, которое Джозеф и его жена Нацуко Уайт открыли в Токио. Сейчас кафе по совместительству стало местом для тусовки независимых разработчиков и офиса Lexaloffe — фирмы Уайта, который большую часть времени просто проводит за одним из столов.

«Pico-8 стал минималистичной двумерной дистилляцией Voxatron», — пишет Уайт. Последним штрихом, который превратил Pico в законченную платформу, стал интерпретатор языка Lua. В первых версиях BASIC транслировался в Lua и выполнялся на ее виртуальной машине, но позже Уайт решил от него отказаться вовсе и оставить только Lua.

«Наверное, было бы намного проще, если бы я с самого начала спросил себя, какой должна быть вымышленная консоль. Вместо этого я продирался через лес расплывчатых идей и лишь потом понял, что то, что я делаю, — это что-то вроде приставки», — рассказывает Уайт.

Постепенно выкристаллизовалось и понимание более широкого контекста. Пожалуй, главный урок здесь заключается в том, что ограничения платформы неизменно влияют на то, какими получатся игры. «Точно так же, как игры для старых компьютеров имели определенный внешний вид и давали определенные ощущения, — рассуждает Уайт, — платформа может сама стать объектом дизайна и определять особенности игр, созданных на ней».

— Андрей Письменный по мотивам статьи Джозефа Уайта в Pico-8 Fanzine

 

Итог

Для меня Pico-8 — один из главных инструментов разработки. Консоль позволяет мне быстро воплотить в жизнь идеи и заставляет меня всегда думать об оптимизации. Я очень рекомендую и активно использую Pico-8 для игровых джемов (game jams), она идеальна для таких ивентов, как Ludum Dare.

Читайте ещё больше платных статей бесплатно: https://t.me/nopaywall