Игры Michael Kechinov
1 822

Как я делаю Snek Fite, «змейку» для нердов

Пошаговая тактика с программируемым поведением и режимом «батл-рояль». Ремейк известной Snake Battle 1992 года.

В закладки

Меня зовут Михаил, я программист *хлопают*, руковожу разработкой проектов и продуктов в IT и еще люблю умные игры. Недавно с моей небольшой командой (конкретно с дизайнером) мы сделали играбельную версию Snek Fite — это тактические пошаговые бои змей. Немного расскажу об игре, конструктивные комментарии приветствуются.

История

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

В общем, оригинальная игра появилась где-то в 70-х, а разные вариации выходили на всех устройствах, где есть дисплей. «Змейка» для Nokia 3310 — это вообще легенда мобильного геймдева. Ее даже сделали для переизданной версии 2017-го года.

А в 1992 российская студия Gamos (та самая, которая потом выпустит «Братьев Пилотов» с самым хардкорным в мире квестом про холодильник) издала игру Snake Battle.

Ее, кстати, и сейчас можно скачать на сайтах со старыми игрушками.

Концепт

Snek Fite — это идейный наследник классики. Тут есть клетчатое поле и движение змеи в трех направлениях, стены и таймер с обратным отсчетом.

Игровой экран, ранний концепт

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

Вот так сейчас выглядит режим «королевской битвы» (FFA для девяти змей на одном экране):

Дизайн

Тут пока все очень просто. От слова совсем. Первое проявление дизайна — это змеиные шкурки. Змеи должны отличаться, поэтому сейчас игроку выдается змея с рандомной окраской и узором.

Таблица самых опасных, у всех своя раскраска

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

Платформа

Игра браузерная, живет по адресу snek.app. Можно играть хоть на чем, Snek Fite не блокирует кроссплей, как некоторые. Можно, например, выяснить, у кого змеи умнее — у маководов или линуксоидов. Кстати, хорошая идея, надо записать на будущее.

Подготовка к бою

Игра не столько про программирование змей, сколько про их обучение. Писать код в прямом смысле не нужно, но у каждой змеи в «снекариуме» игрока есть визуальный редактор программной логики. Там вы задаете змее паттерны поведения, потом тестируете их в бою, анализируете, находите ошибки и слабые места, исправляете и снова проверяете. Если все делать правильно, постепенно змея перестает бегать по кругу, впадать в циклы и гоняться за собственным хвостом или долбиться в стены. А это уже почти победа.

Сейчас редактор выглядит вот так:

Текущая версия редактора поведения змеи

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

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

Вот такую ситуацию я называю «круг смерти» — это когда две змеи косплеят Уробороса: начинают нарезать круги, бесконечно гоняясь за хвостами друг друга.

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

Бой

Главный игровой экран выглядит просто: выбор режима битва, автобитва вкл/выкл и, собственно, история боев.

В игре пока три режима.

Дуэль. Все просто, один на один — пока время не закончится (это всегда 1000 ходов). Если вашу змею укоротили в самом начале матча, отчаиваться не стоит — у нее все еще есть шансы отгрызть свое обратно и прихватить лишнего. Главное — правильные действия в конце матча.

Стандартный змеецид. Deathmatch для четырех змей. Правила те же, веселья побольше.

Королевская битва. Тоже FFA-карта для девяти змей одновременно. Выигрывает длиннейший.

Недавно добавил кнопку «Реванш» в список самых опасных змей. Если играли с кем-то из лидеров — можно снова бросить ему перчатку.

Код и производительность

Сейчас все просто — на бэкенде Ruby-on-Rails и PostgreSQL. Кстати, уже сейчас на 5000 боях бэкап базы весит 15 гигабайтов, хотя казалось бы — откуда? Записывается каждый ход каждого боя и эти данные публичны — можно анализировать, учить свою нейронную сеть или просто пытаться понять, как думает змея оппонента и почему она реагирует в текущей ситуации именно так, а не иначе. Например, вот реплей одного боя.

Бои просчитываются в фоне. На дуэль или бой четырех змей уходит около 15 секунд. Королевская битва считается минуту. Это не проблема — при росте числа игроков планирую перенести все на отдельный сервер и будет быстрее. Один игрок говорит, что у него на ПК битва считается за пару секунд

Затраты времени

Первую версию я сделал часов за восемь. Она могла регистрировать змей, программировать их с помощью BPI (basic programming interface) и запускать бой на четыре змеи.

Сейчас затрачено часов 80–100, я особо не считаю. Просто трачу максимум час в день. Проект несложный, в основном все время уходило либо на модуль расчета боя, либо на BPI — я решил там использовать Vue.JS, не имея никакого опыта работы с ним. Вот и разобрался.

Зачатки маркетинга

Про результаты говорить пока рано, тестирую разные гипотезы. Реклама в Фейсбуке с таргетингом на играющих программистов, например, принесла 501 человека, из которых 54 дошли до регистрации, справились с ней 10 человек (казалось бы, там три поля и даже почту подтверждать не нужно, но тем не менее). Из этой храброй десятки трое поиграли. Стоимость одного игрока — 362 рубля. Работаю над этим.

Снейк одобряет

Наблюдение: много трафика из Непала и Бангладеша.

Что еще

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

В общем, если понравится и появятся идеи, чего вы хотите от Snek Fite, пишите в наш публичный GitHub. Ну или если захотите помочь в разработке. На GitHub, кстати, есть план по фичам.

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

Написать
{ "author_name": "Michael Kechinov", "author_type": "self", "tags": [], "comments": 30, "likes": 59, "favorites": 13, "is_advertisement": false, "subsite_label": "games", "id": 22633, "is_wide": false, "is_ugc": true, "date": "Wed, 04 Jul 2018 10:13:45 +0300" }
{ "id": 22633, "author_id": 70294, "diff_limit": 1000, "urls": {"diff":"\/comments\/22633\/get","add":"\/comments\/22633\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/22633"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64953, "possessions": [] }

30 комментариев 30 комм.

Популярные

По порядку

Написать комментарий...
0

Все так, да.

Ответить
3

Крутая была игруха. Помню мы с сестрой давным давно играли, только было нифига не понятно как программировать эту змею :)
Думал тоже когда-нибудь сделать ремейк (я бы назвал его CyberSnake), но видимо уже не.

Ответить
0

У нас open source. Можно принять участие в разработке.

Ответить
3

По рекламе:

1. Если уже пытаешься лить траф с Фб, то сделай авторизацию через него. Будет лучше конверсия в регистрацию.
2. Лучше лить не на страницу с регистрацией, а на демо-экран, где можно посмотреть как у тебя все это работает и желательно дать игроку попробовать сделать что-то самостоятельно, а уже потом просить регу.
3. Убери всплывающие окна, это жутко бесит.

По игре:

Дичь какая-то) Может для программистов это занимательно, но я вообще не вдуплил в чем прикол этой пошаговой змейки. Поработай над объяснением преимуществ для массового игрока.

Ответить
2

Змейка-батлрояль?) А лутбоксы будут?))

Ответить
2

Конечно. Но позже.

Ответить
2

Моя любимая змейка, после змейки на консольке Brick Game

Ответить
1

Кстати да... вот это был тот самый Nextgen который меня поразил. И какой там год был? 2004-2005? Правда еще чуть позже вышла PSP, и вот после нее моя жизнь в плане ощущения игр изменилась навсегда...

Воистину спасибо игровой индустрии за мое счастливое игровое детство. Это было незабываемо.

Ответить
1

Да, 2004. Помню как раз закончил школу, взял n-gage qd в кредит на родителей и пошел работать, чтобы кредит отдать ) А какое там промо видео было на диске, ах.. ностальгия.

Ответить
2

Аудитория сильно широкой не будет, но так-то годнота ведь.

Ответить
0

Да, это для терпеливых программистов. Но думаю, тысяч 100 по миру наберется в сумме.

Ответить
2

Считаю неправильным то, что в комментах до сих пор нет самой важной картинки.

Ответить
1

Зашла ради мемов про снеков, осталась ради игры. Серьезно, кричу как ребенок над СНЕКАРИУМОМ и СНЕКОЦИДОМ.

Ответить
0

Спасибо. Мы постоянно придумываем новую терминологию. Будет ещё.

Ответить
1

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

Ответить
0

Да, это одна из ближайших фич. Редактор требует серьезной проработки.
Спасибо.

Ответить
1

Для не программистов, что конкретно делают блоки Must, mustnot, optional

Ответить
0

Похоже мой ответ не в этой ветке добавился. Он ниже.

Ответить
1

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

Ответить
0

Оно проверяет автоматически зеркальную версию.

Ответить
0

Пока пытался вспомнить игру про программируемые танчики, в которую рубился в институте (кажется, предыдущая инкарнация современной http://robocode.sourceforge.net) , нашел http://programminggames.org - целая википедия на вашу тему! Может и Snek Fite туда добавить ?

Ответить
1

Супер, спасибо. Добавлюсь.

Ответить
0

А так и должно быть что две змеи бесконечно едят хвосты друг друга аки уроборос ?

Ответить
0

Так и живем - бой заканчивается на 1000 ходе. Кто длиннее, того и тапки.

Ответить
1

Но лучше запрограммировать змею так, чтобы она могла разрывать кольцо

Ответить
0

Подробно описано здесь: https://snek.app/welcome/rules?locale=ru
А кратко:

MUST означает, что содержимое ячейки должно быть обязательно на поле. В документации пример №1 и №2
MUST NOT - ячейка считается совпавшей, если на поле в этой ячейке что угодно, кроме того, что указано в правиле.
OPTIONAL - совпадением считается совпадение хотя бы одной ячейки такого типа. В документации Пример №3

Ответить
0

Из мануала:
сравнивает его с первым паттерном своего поведения, вращая его по необходимости.

Можно подробнее про вращение? Если совпадает и начальный и повёрнутый вариант? В каком порядке "повёрнутые" сравниваются?

Ответить
0

case get_current_direction
when 'N'
%w[N E W]
when 'E'
%w[E N S]
when 'S'
%w[S W E]
when 'W'
%w[W N S]
end

В зависимости от того, куда смотрит голова, вращение происходит в этом порядке, как в коде.

Ответить
0

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } } ]
Игру с лучшим стелсом никто не заметил
Подписаться на push-уведомления