CodeCraft принадлежит к жанру Programming game. Многие из вас наверняка знают о проекте HabraWars или о других Programming games. То есть желание написать среду для битв программистов возникало у многих. Вот у меня, например, возникла эта идея.
Ее отличительные черты:
  • Игровой мир — баталия двух флотов космических кораблей.
  • Необходимость стратегического превосходства над соперником
  • Управление возможно как отдельными юнитами, так и группами
  • 3 типа юнитов
  • Тактический и стратегический вид
  • 2D
  • Игроки — плагины в виде библиотек
  • 2 уровня абстракции для взаимодействия с игрой. О них позже
  • Удобная отладка
  • Максимально упрощен процесс написания игроков
  • Есть документация, мануалы, примеры


Почему же я решил, что среда для битв программистов должна быть именно такой?

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






История



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

Простота



На практике стала понятна необходимость крайнего упрощения управлением юнитами. Поэтому сейчас доступна возможность писать только то, что интересно. Я создал стандартные реализации для поведения юнитов и групп юнитов – библиотеку EtalonAI.
Например, код

foreach (UnitPilot pilot in friends) <br>  pilot.AttackClosest();<br><br>* This source code was highlighted with Source Code Highlighter.


уже является адекватным алгоритмом ведения боя. Так же юниту можно приказать держать позицию, атаковать конкретного врага, лететь в указанные координаты, либо ждать приказов. Юнит имеет список близких к нему юнитов, юнитов, врагов, которые в него целятся. А так же все юниты доступны в списках friends и enemies.
Для контроля группы юнитов можно создать отряд. В примере создается отряд из десяти истребителей

DestroyersSquad1 = new SquadronColonel(friends[0], game);<br>for (int i=0;i<10;i++)<br>  DestroyersSquad1.AddUnit(friends[i]);<br>


Далее, весь отряд можно отправить в заданную точку

DestroyersSquad1.GoToOrder(new GameVector(-3000, -2000));<br>


Можно приказать передвигаться «через атаку»

DestroyersSquad1.AttackOrder(new GameVector(-3000, -2000));<br><br>


Можно задать тип строя – линия, прямоугольник, клин или стая(без строя).
DestroyersSquad1.SetFormationTypeLine(WidthBetweenUnits, AngleForward);<br>

Создание своей геометрии построения тоже возможно.
Также есть приказы для атаки ближайшего врага, тарана врагов (кстати, полезное дело — истребителями затаранить вражеский крейсер)

Так же просто можно исследовать противника – класс EnemyAnalyzing периодически проводит кластеризацию врагов – то есть вы можете легко узнать, на какие отряды соперник разделил флот

Работа с геометрией так же учтена – класс вектора GameVector содержит методы для поворота, операторы векторной математики перегружены. Есть класс Angle, который позволяет складывать углы, не опасаясь получить тыщу градусов, находить разность, расстояние между углами и т.д. подробнее – см. документацию.

Конечно, стандартизация до такой степени исключает возможность создания уникального поведения юнита, особо крутого джедайско-чакнорриского истребителя, но ведь игра по идеологии стратегическая. К тому же, как сказано выше, есть два уровня абстракции взаимодействия с игрой: первый – высокоуровневый, где игрок указывает, кого атаковать или место, куда лететь отряду и каким строем; на втором уровне игрок указывает непосредственно линейное ускорение, ускорение поворота юнита и момент выстрела. Так юниты и контролировались до дня рождения. Получается, возможность помаяться и сделать Чака Норриса остается.

Отладка



Для отладки предусмотрено несколько способов
  • Вывод текста от имени игрока. У класса игры есть метод SetText(string text). Можно использовать перенос строки \n
  • Вывод текста от имени юнита. У юнита есть поле Text, содержимое которого будет выведено на экран. Также можно использовать перенос строки.
  • Вывод геометрии. У класса игры есть поле GeometryViewer, класс которого имеет методы для рисования прямоугольника, круга, линии и точки. Задается цвет (прозрачность допускается) и сама фигура. Кстати, структуры фигур тоже собственные, имеют методы расчета пересечений.




Файл настроек позволяет
  • Включить или отключить вывод отладочной информации
  • Запускать программу в полноэкранном или оконном режиме
  • Изменять количество юнитов каждого типа для каждой стороны отдельно (например, так я узнал, что 100 истребителей «стоят» 13-15 корветов)

Как написать игрока


Написание «Hello world» и адекватного алгоритма занимает всего пару минут. Игрока можно написать на любом .NET языке.
Для этого нужно:
  • Подключить библиотеку MiniGameInterfaces.dll и, по желанию, EtalonAI.dll для приятного написания.
  • Наследовать класс AI, в нем перегрузить метод Init и Update.

Вот и все.Это почти полное руководство

Подробности



Игра была написана на С# с использованием XNA, так что, пардон, Windows-only. Писал ведь не рассчитывая кому-нибудь кроме друзей показать, а все-таки C# — это сплошные удобства. Mad Fish сейчас занимается портированием игры для Linux.
Клавиши управления
  • Page up и page down – увеличение, уменьшение скорости симуляции
  • Home и end – отдаление и приближение камеры.
  • Стрелки – перемещение камеры
  • Пауза – пауза
  • Esc – выход


Заключение



Надеюсь развивать проект и далее. Например графику по-человечески сделать и все такое.Mad_Fish в настоящее время портирует CodeCraft на OpenGL, и говорит, что надо от Microsoft не зависеть)
Но самое интересное — это конечно же загрузить игрока, написанного кем-то из вас; посмотреть на его тактику; придумать как его победить; загрузить своего игрока, побеждающего его и ждать ответа соперника.0
Скачивать чужих и добавлять своих игроков можно здесь



Ссылки




Записи игр в CodeCraft. Учасники — примеры игроков


Приятной игры

Комментарии (69)


  1. anonymous
    09.12.2009 10:01


    1. Mad_Fish
      09.12.2009 10:01

      Это сильно усложнило бы как саму игру, так и написание плагинов. А цель была — сделать всё достаточно просто.


  1. Mad_Fish
    09.12.2009 10:01

    Надеюсь, скоро закончу портирование под OpenGL. Так что пользователи Linux не будут обделены (теоретически, ещё и под MacOS должно будет работать, но у меня мака нет).


    1. halyavin
      09.12.2009 10:01

      Через Mono?


      1. Mad_Fish
        09.12.2009 10:01

        Да, на Mono. С сохранением бинарной совместимости с плагинами Windows-версии.


    1. VlK
      09.12.2009 10:01

      Портирование? То есть все же нужен будет Mono?


    1. stepio
      09.12.2009 10:01

      MacOS — не проблема. Если будет желание, сможем попробовать :)


      1. Mad_Fish
        09.12.2009 10:01

        Конечно будет. :)


    1. wolf13h
      09.12.2009 10:01

      А почему не портировать на Silverlight через www.codeplex.com/Xn4Sl например? будет работать почти везде.


      1. wolf13h
        09.12.2009 10:01

        а плагины написать с помощью MEF или вообще туда запихать DLR и писать расширения на IronPython и IronRuby.


      1. Sone
        09.12.2009 10:01

        Linux не очень с SilverLight дружит.


        1. wolf13h
          09.12.2009 10:01

          С чего вы взяли помоему MoonLight очень прилично работает/ Не идеально конечно но достаточно хорошо/ Как в прочем и все в мире десктоп линукса/


  1. sse
    09.12.2009 10:01

    Респект и уважуха по всем профессиональным фронтам :)


  1. Enoty200shtyk
    09.12.2009 10:01

    Завидую я вам. Видно есть время и увлечение…


  1. VlK
    09.12.2009 10:01

    Вам большущий респект, но еще больший будет MadFish, если сможет сделать задуманное вне .NET :) Будет тогда совсем хорошо и приятно.


    1. Mad_Fish
      09.12.2009 10:01

      Будет на C + Mono. Надеюсь, это достаточно идеологически приемлемо.
      Можно было бы и чисто на С или С++, но тогда нет бинарной переносимости плагинов. Увы.


      1. VlK
        09.12.2009 10:01

        Наверное, идеологически чище всего было бы сделать на C++/SDL с каким-нибудь приятным скриптовым языком. :)

        В общем-то все равно, лишь бы запустить под Ubuntu можно было.

        К счастью, Столлман далеко и не слышит меня :)


  1. k0t0vich
    09.12.2009 10:01

    Прикольная вещь! Появилась задумка портировать CodeCraft на Actionscript — это позволит подгружать игроков онлайн ( в виде swf модулей) и вообще сделать некую MMO битву программистов)
    Единственное, конечно, надо будет по оптимизации графики пройтись.
    Разрешите попробовать портануть?


    1. k0t0vich
      09.12.2009 10:01

      В дополнение:
      Можно реализовать некую «прослойку» ( 3 уровень абстракции) для написания алгоритмов посредством динамически подгружаемых скриптов ( вроде lua или xml Based) Парсер скрипта реализует заложенные ранее стратегии.
      Для 4 уровня абстракция превращается в набор чекбоксов)


      1. Mad_Fish
        09.12.2009 10:01

        Чтобы сделать это всё на Actionscript, нужно будет всё переписать. Мне кажется, в том виде, в котором оно сейчас, формат десктопного приложения подходит лучше.

        Но никто вам не мешает создать свой проект. :)


      1. AntonEtalon Автор
        09.12.2009 10:01

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


  1. n3m0
    09.12.2009 10:01

    Да, вещь классная! Вам респект! Ждем работы под Линукс


  1. cry_san
    09.12.2009 10:01

    Может я параноик, но, пожалуйста, оптимизируйте размер фонового изображения (code-background.png) на сайте игры 77.90.249.194/CodeCraft/. иначе получается что я загружаю не сколько нужную мне информацию, сколько этот фон.
    Траф не безлимитный, зарплата маленькая :)


    1. Mad_Fish
      09.12.2009 10:01

      А ведь говорил я AntonEtalon-у, что лишний там фон. Но он мне не поверил. :)


    1. youROCK
      09.12.2009 10:01

      Мне лично скорее было жалко тратить >100 Мб на XNA и на .NET 3.5 :). Не говоря уже о том, что под wine оно не работает, и что пришлось в винду перезагружаться.


    1. AntonEtalon Автор
      09.12.2009 10:01

      ок. Это мой первый топик, косяки неизбежны


      1. micbsv
        09.12.2009 10:01

        Можно решить проблему с размером.
        Сделайте вертикальный градиент фоном шириной в один пиксел и растяните CSS-ом по горизонтали.
        Символы накидайте простым текстом со светлым цветом.
        И все будут счастливы ;)


  1. danmiru
    09.12.2009 10:01

    Если честно, немного нелогично. Много мелочей, но для начала о самых крупных.

    Одно орудие у истребителя — еще ладно, но у крейсера?

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

    А в целом — да, очень интересно )


    1. Mad_Fish
      09.12.2009 10:01

      Рассматривайте это как шахматы. Тут всё скорее символично, а не реалистично.
      Ведь цель была — простота.


  1. Tolsi
    09.12.2009 10:01

    На Win7 не запускается :(


    1. Tolsi
      09.12.2009 10:01

      Извиняюсь, работает
      ps читаем Manual.doc из Documentation.zip


  1. dotneter
    09.12.2009 10:01

    >OpenGL
    Почему бы не сделать на Moonlight?
    Думается мне графические навароты в таких играх не самое главное.


  1. CheatEx
    09.12.2009 10:01

    Автор раньше в Homeworld не зависал случаем?)


    1. AntonEtalon Автор
      09.12.2009 10:01

      Угадано)
      Зависал немного в подобные Homeworld'у вещи)


      1. CheatEx
        09.12.2009 10:01

        То-то я смотрю терминология знакомая…


        1. AntonEtalon Автор
          09.12.2009 10:01

          Правильно!
          На ролике «Истребители Чаки Норрисы» против «Атаки влоб» в конце боя 12 истребителей нападают на 5 крейсеров и сливают двоих. А ведь алгоритм у «Чаков Норрисов» прост как полено: если на истребитель точно нацелен нос вражеского крейсера — сваливать влево


  1. ttools
    09.12.2009 10:01

    Класс! Удачи по всем фронтам!


  1. AmirL
    09.12.2009 10:01

    Баланс не очень. Судя по роликам самая эффективная тактика стоять кучкой и ждать.


    1. AlexVS85
      09.12.2009 10:01

      Идея и реализация супер. Загорелся попробовать, сегодня же ночью.
      … но после такого комментария и перепросмотра роликов остыл.
      Возможно ли разбить врага, который ушёл в глухую оборону (с взаимной поддержкой всех классов кораблей, а то на роликах побеждали только если эшелоны не защищают друг друга)?
      В чём преимущество мелких юнитов (кроме скорости), какая-то тактика позволит победить пятерым истребителям крейсер?


      1. AntonEtalon Автор
        09.12.2009 10:01

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


        1. ttools
          09.12.2009 10:01

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


  1. anonymous
    09.12.2009 10:01


  1. lifehouse
    09.12.2009 10:01

    слышал еще на CodeCamp '09 о ней…
    молодцы, что еще работаете над ней.
    тогда поразило что идея создания игры возникла как подарок другу на ДР… так ведь?


    1. AntonEtalon Автор
      09.12.2009 10:01

      Да. Точнее подарок себе)


  1. Rayslava
    09.12.2009 10:01

    В общем, ждем линукс версии.
    За продолжение идеи pRobots — респект и уважуха ;)


  1. Mad_Fish
    09.12.2009 10:01

    Да, кстати, если будет у кого-то желание помочь с графикой (дизайн кораблей, и прочего), то обращайтесь, будем очень рады.


  1. Shemet
    09.12.2009 10:01

    Я думаю баланс нужно свести к Камень>Ножницы>Бумага, точнее Крейсер>Корвет>Истребитель.


    1. kurokikaze
      09.12.2009 10:01

      А с тремя типами юнитов он другим особо быть не может :)


      1. Shemet
        09.12.2009 10:01

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


        1. kurokikaze
          09.12.2009 10:01

          Ну когда что то одно сильнее это уже явно не баланс :) При трёх типах юнитов на самом деле могут быть два варианта — либо они все одинаковы, либо «камень-ножницы бумага».


    1. Mad_Fish
      09.12.2009 10:01

      Так и планировалось. У истребителя есть шансы завалить крейсер, но только если ИИ, управляющий им, будет очень хитро маневрировать, уклоняясь от выстрелов.


      1. Shemet
        09.12.2009 10:01

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


  1. DarwinTenk
    09.12.2009 10:01

    На днях олько закончил читать книгу. «Военная тактика». Спасибо =)


  1. j3d1
    09.12.2009 10:01

    — а почему мелочевка такая медленная?
    — нужно сделать чтоб по мелочевке сложнее попасть было
    — нужно учитывать повреждение отдельных участков коробля
    — дальность растояние и разнообразие орудий у больших кораблей должно быть больше
    — было бы супер если была возможность human vs human по сетке (:


    1. AntonEtalon Автор
      09.12.2009 10:01

      — Чтобы было время развернуться, построиться, на поведение соперника отреагировать и т.п. Есть ускорение времени, Page Up.
      — Например, по мелочевке алгоритма «Чак Норрисов» попасть сложно. Игрок должен сам сделать истребитель хитрым
      — Я думал об этом. Скорее всего это не нужно, чтобы не усложнять. Пешка или бьет ферзя или не бьет
      — Идея для аддона
      — Да


      1. j3d1
        09.12.2009 10:01

        в догонку
        — было бы все таки прикольно еслиб ещё летали астероиды\планеты за которые можно спрятаться от залпа ( и чтоб они влияли притяжением на снаряды и корабли)

        — и human vs human + свои боты, например ты рулишь одним отрядом какие нить хитрые действия, а боты другими короблями управляют

        (имхо) конечно


        1. ramovsky
          09.12.2009 10:01

          Вот меня всегда удивляют люди, которые не довели до совершенства алгоритм на простых условиях и просят усложнить.
          Или я не прав?


          1. j3d1
            09.12.2009 10:01

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


  1. anonymous
    09.12.2009 10:01


  1. youROCK
    09.12.2009 10:01

    Мне не очень понравилась идея писать роботов на C#, потом компилировать, ставить студию… И то, что это windows-only тоже не очень понравилось :).

    Поэтому я решил написать свою систему «с блекджеком и шлюхами», в которой ботов нужно будет писать на Javascript :).

    Вот, что уже есть:

    datapoliten.ru/misc/yavascriptw/ (демо)
    svn://datapoliten.ru/yavascriptw — исходники в SVN


    1. youROCK
      09.12.2009 10:01

      Пример робота:

      var SimpleCPU = function(friends, enemies)
      {
        var T = this;
        
        T.make_turn = function()
        {
          var unit;
          
          for(var k in friends)
          {
            unit = friends[k];
            
            unit.shoot();
            
            unit.turnToEnemy(enemies);
            unit.move();
          }
        }
      };


      * This source code was highlighted with Source Code Highlighter.


    1. k0t0vich
      09.12.2009 10:01

      smartCPU — умнее чем simpleCPU?
      Почему же он всегда проигрывает? :)


      1. youROCK
        09.12.2009 10:01

        Ну, пока у SimpleCPU не было строчки «unit.turnToEnemy(enemies);», он был тупее, чем SmartCPU :). Ну и к тому же всё это было написано за где-то часа 3-4, так что на сам искусственный интеллект я времени потратил немного, прямо скажем :).


  1. jcdenton_dx
    09.12.2009 10:01

    Мегареспект за двухуровневую абстракцию. Сейчас все сохроним и будем пытаться.


  1. beetleinweb
    09.12.2009 10:01

    Что даёт маневрирование в стратегическом смысле? В тактическом-то понятно, уклонение, сложность попадания, но глобальное маневрирование, стройными колоннами…

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

    А здесь? Я понимаю, что это «шахматы», но и в шахматах стратегия обуславливается реальной выгодой. Никто не будет брать врага в клещи только потому, что это красиво смотрится на карте, так ведь?


    1. AntonEtalon Автор
      09.12.2009 10:01

      Mad Fish тоже так считает. Он говорит, что его юниты летать будут просто стаями, без всяких там строев. Но я отвечаю, что вне боя в куче юнитов бардак, и чтобы не протаранить друг друга они тормозят. Да и в полете разделяются. Сторем летят вместе и не толпятся.

      Сначала я думал и воевать строем, попробовал — м-да, в куче лучше. Теперь на время боя строй отменяется.

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


  1. ramovsky
    09.12.2009 10:01

    Готов посоревноваться, но после нового года. В конце года — завал по работе. Кто как?


  1. Kinjeiro
    09.12.2009 10:01

    Приятного времени суток!
    А проект еще существует? Ведутся ли какие баталии?


    1. AntonEtalon Автор
      09.12.2009 10:01

      Пока желающих оказалось гораздо мене чем несколько.
      Но планы по развитию (в сторону упрощения для игроков) есть.