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
Скачивать чужих и добавлять своих игроков можно здесь

Ссылки
- Репозиторий на GoogleCode
- Документация в формате CHM для «простого» и «сложного» варианта игры.
- Бинарники игры. Примеры игроков прилагаются
- Исходники игры. Исходники примеров игроков прилагаются
- Сайт игры — место для обмена игроками
Записи игр в CodeCraft. Учасники — примеры игроков
- «Истребители камикадзе» против «Атаки влоб»
- «Истребители камикадзе» против «Защитной тактики»
- «Истребители камикадзе» против «Атаки Крейсер-корвет-истребитель»
- «Защитная тактика» против «Атаки влоб»
- «Защитная тактика» против «Атаки Крейсер-корвет-истребитель»
- «Атака Крейсер-корвет-истребитель» против «Атаки влоб»
- «Атака Корвет-крейсер-истребитель» против «Атаки влоб»
- «Атака Корвет-крейсер-истребитель» против «Защитной тактики»
- «Истребители Чаки Норрисы» против «Атаки влоб»
- «Истребители Чаки Норрисы» против «Защитной тактики»
- «Сбалансированные отряды» против «Защитной тактики»
- «Все подстроено» против «Атаки влоб». Заглавное видео
Приятной игры
Комментарии (69)
Mad_Fish
09.12.2009 10:01Надеюсь, скоро закончу портирование под OpenGL. Так что пользователи Linux не будут обделены (теоретически, ещё и под MacOS должно будет работать, но у меня мака нет).
wolf13h
09.12.2009 10:01А почему не портировать на Silverlight через www.codeplex.com/Xn4Sl например? будет работать почти везде.
wolf13h
09.12.2009 10:01а плагины написать с помощью MEF или вообще туда запихать DLR и писать расширения на IronPython и IronRuby.
VlK
09.12.2009 10:01Вам большущий респект, но еще больший будет MadFish, если сможет сделать задуманное вне .NET :) Будет тогда совсем хорошо и приятно.
Mad_Fish
09.12.2009 10:01Будет на C + Mono. Надеюсь, это достаточно идеологически приемлемо.
Можно было бы и чисто на С или С++, но тогда нет бинарной переносимости плагинов. Увы.VlK
09.12.2009 10:01Наверное, идеологически чище всего было бы сделать на C++/SDL с каким-нибудь приятным скриптовым языком. :)
В общем-то все равно, лишь бы запустить под Ubuntu можно было.
К счастью, Столлман далеко и не слышит меня :)
k0t0vich
09.12.2009 10:01Прикольная вещь! Появилась задумка портировать CodeCraft на Actionscript — это позволит подгружать игроков онлайн ( в виде swf модулей) и вообще сделать некую MMO битву программистов)
Единственное, конечно, надо будет по оптимизации графики пройтись.
Разрешите попробовать портануть?k0t0vich
09.12.2009 10:01В дополнение:
Можно реализовать некую «прослойку» ( 3 уровень абстракции) для написания алгоритмов посредством динамически подгружаемых скриптов ( вроде lua или xml Based) Парсер скрипта реализует заложенные ранее стратегии.
Для 4 уровня абстракция превращается в набор чекбоксов)Mad_Fish
09.12.2009 10:01Чтобы сделать это всё на Actionscript, нужно будет всё переписать. Мне кажется, в том виде, в котором оно сейчас, формат десктопного приложения подходит лучше.
Но никто вам не мешает создать свой проект. :)
cry_san
09.12.2009 10:01Может я параноик, но, пожалуйста, оптимизируйте размер фонового изображения (code-background.png) на сайте игры 77.90.249.194/CodeCraft/. иначе получается что я загружаю не сколько нужную мне информацию, сколько этот фон.
Траф не безлимитный, зарплата маленькая :)Mad_Fish
09.12.2009 10:01А ведь говорил я AntonEtalon-у, что лишний там фон. Но он мне не поверил. :)
youROCK
09.12.2009 10:01Мне лично скорее было жалко тратить >100 Мб на XNA и на .NET 3.5 :). Не говоря уже о том, что под wine оно не работает, и что пришлось в винду перезагружаться.
AntonEtalon Автор
09.12.2009 10:01ок. Это мой первый топик, косяки неизбежны
micbsv
09.12.2009 10:01Можно решить проблему с размером.
Сделайте вертикальный градиент фоном шириной в один пиксел и растяните CSS-ом по горизонтали.
Символы накидайте простым текстом со светлым цветом.
И все будут счастливы ;)
danmiru
09.12.2009 10:01Если честно, немного нелогично. Много мелочей, но для начала о самых крупных.
Одно орудие у истребителя — еще ладно, но у крейсера?
И еще, одно из преимуществ истребителя именно в том, что он меньше и попасть по нему труднее. Особенно из главного калибра крейсера.
А в целом — да, очень интересно )Mad_Fish
09.12.2009 10:01Рассматривайте это как шахматы. Тут всё скорее символично, а не реалистично.
Ведь цель была — простота.
dotneter
09.12.2009 10:01>OpenGL
Почему бы не сделать на Moonlight?
Думается мне графические навароты в таких играх не самое главное.
CheatEx
09.12.2009 10:01Автор раньше в Homeworld не зависал случаем?)
AntonEtalon Автор
09.12.2009 10:01Угадано)
Зависал немного в подобные Homeworld'у вещи)CheatEx
09.12.2009 10:01То-то я смотрю терминология знакомая…
AntonEtalon Автор
09.12.2009 10:01Правильно!
На ролике «Истребители Чаки Норрисы» против «Атаки влоб» в конце боя 12 истребителей нападают на 5 крейсеров и сливают двоих. А ведь алгоритм у «Чаков Норрисов» прост как полено: если на истребитель точно нацелен нос вражеского крейсера — сваливать влево
AmirL
09.12.2009 10:01Баланс не очень. Судя по роликам самая эффективная тактика стоять кучкой и ждать.
AlexVS85
09.12.2009 10:01Идея и реализация супер. Загорелся попробовать, сегодня же ночью.
… но после такого комментария и перепросмотра роликов остыл.
Возможно ли разбить врага, который ушёл в глухую оборону (с взаимной поддержкой всех классов кораблей, а то на роликах побеждали только если эшелоны не защищают друг друга)?
В чём преимущество мелких юнитов (кроме скорости), какая-то тактика позволит победить пятерым истребителям крейсер?AntonEtalon Автор
09.12.2009 10:01Баланс — дело тонкое)
Возможно ли разбить глухую оборону? Возможно. Любую оборону можно разбить, можно даже провести эксперимент. Если будет выложен годный оборонный алгоритм, я в ответ напишу еще более годный атакующий его. Если сумею, конечно.ttools
09.12.2009 10:01Можно сделать двухраундный сет: сначала одна сторона защищается, потом другая. если после заданного таймаута в раунде нет определенного победителя — победила защита
lifehouse
09.12.2009 10:01слышал еще на CodeCamp '09 о ней…
молодцы, что еще работаете над ней.
тогда поразило что идея создания игры возникла как подарок другу на ДР… так ведь?
Rayslava
09.12.2009 10:01В общем, ждем линукс версии.
За продолжение идеи pRobots — респект и уважуха ;)
Mad_Fish
09.12.2009 10:01Да, кстати, если будет у кого-то желание помочь с графикой (дизайн кораблей, и прочего), то обращайтесь, будем очень рады.
Shemet
09.12.2009 10:01Я думаю баланс нужно свести к Камень>Ножницы>Бумага, точнее Крейсер>Корвет>Истребитель.
kurokikaze
09.12.2009 10:01А с тремя типами юнитов он другим особо быть не может :)
Shemet
09.12.2009 10:01Может быть просто что крейсеры самые сильные и выносят всех по любому, просто они медленные.
Или что корветы имеют хороший баланс между силой и маневренностью и выносят всех без шансов.
Важно явно этот баланс поддерживать.kurokikaze
09.12.2009 10:01Ну когда что то одно сильнее это уже явно не баланс :) При трёх типах юнитов на самом деле могут быть два варианта — либо они все одинаковы, либо «камень-ножницы бумага».
Mad_Fish
09.12.2009 10:01Так и планировалось. У истребителя есть шансы завалить крейсер, но только если ИИ, управляющий им, будет очень хитро маневрировать, уклоняясь от выстрелов.
Shemet
09.12.2009 10:01Можно добавить, пассивный уворот для истребителей.
Или чтоб крейсеры стреляли редко но сильно. Тогда истребители будут имень сильное преимущество над крейсерами.
j3d1
09.12.2009 10:01— а почему мелочевка такая медленная?
— нужно сделать чтоб по мелочевке сложнее попасть было
— нужно учитывать повреждение отдельных участков коробля
— дальность растояние и разнообразие орудий у больших кораблей должно быть больше
— было бы супер если была возможность human vs human по сетке (:AntonEtalon Автор
09.12.2009 10:01— Чтобы было время развернуться, построиться, на поведение соперника отреагировать и т.п. Есть ускорение времени, Page Up.
— Например, по мелочевке алгоритма «Чак Норрисов» попасть сложно. Игрок должен сам сделать истребитель хитрым
— Я думал об этом. Скорее всего это не нужно, чтобы не усложнять. Пешка или бьет ферзя или не бьет
— Идея для аддона
— Даj3d1
09.12.2009 10:01в догонку
— было бы все таки прикольно еслиб ещё летали астероиды\планеты за которые можно спрятаться от залпа ( и чтоб они влияли притяжением на снаряды и корабли)
— и human vs human + свои боты, например ты рулишь одним отрядом какие нить хитрые действия, а боты другими короблями управляют
(имхо) конечно
youROCK
09.12.2009 10:01Мне не очень понравилась идея писать роботов на C#, потом компилировать, ставить студию… И то, что это windows-only тоже не очень понравилось :).
Поэтому я решил написать свою систему «с блекджеком и шлюхами», в которой ботов нужно будет писать на Javascript :).
Вот, что уже есть:
datapoliten.ru/misc/yavascriptw/ (демо)
svn://datapoliten.ru/yavascriptw — исходники в SVNyouROCK
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.
k0t0vich
09.12.2009 10:01smartCPU — умнее чем simpleCPU?
Почему же он всегда проигрывает? :)youROCK
09.12.2009 10:01Ну, пока у SimpleCPU не было строчки «unit.turnToEnemy(enemies);», он был тупее, чем SmartCPU :). Ну и к тому же всё это было написано за где-то часа 3-4, так что на сам искусственный интеллект я времени потратил немного, прямо скажем :).
jcdenton_dx
09.12.2009 10:01Мегареспект за двухуровневую абстракцию. Сейчас все сохроним и будем пытаться.
beetleinweb
09.12.2009 10:01Что даёт маневрирование в стратегическом смысле? В тактическом-то понятно, уклонение, сложность попадания, но глобальное маневрирование, стройными колоннами…
В реальном бою, полагаю, выигрыш в том, что лобовая броня толще, а танк или корабль в профиль значительно больше, чем в фас. Кроме того, попав под перекрёстный огонь, практически невозможно найти укрытие (в море неактуально). Также имеет значение, что с фланга ведётся огонь почти безнаказанно, не надо самому искать укрытие. Ну и фактор внезапности.
А здесь? Я понимаю, что это «шахматы», но и в шахматах стратегия обуславливается реальной выгодой. Никто не будет брать врага в клещи только потому, что это красиво смотрится на карте, так ведь?AntonEtalon Автор
09.12.2009 10:01Mad Fish тоже так считает. Он говорит, что его юниты летать будут просто стаями, без всяких там строев. Но я отвечаю, что вне боя в куче юнитов бардак, и чтобы не протаранить друг друга они тормозят. Да и в полете разделяются. Сторем летят вместе и не толпятся.
Сначала я думал и воевать строем, попробовал — м-да, в куче лучше. Теперь на время боя строй отменяется.
На счет флангов — надо напасть не с одного фланга, иначе он будет уже фронтом и толку ноль. А во время разворота врага его можно успеть просто убить, да и окружив площадь периметра войск атакующего больше. Думаю, выгода есть.
ramovsky
09.12.2009 10:01Готов посоревноваться, но после нового года. В конце года — завал по работе. Кто как?
Kinjeiro
09.12.2009 10:01Приятного времени суток!
А проект еще существует? Ведутся ли какие баталии?AntonEtalon Автор
09.12.2009 10:01Пока желающих оказалось гораздо мене чем несколько.
Но планы по развитию (в сторону упрощения для игроков) есть.
anonymous
Mad_Fish
Это сильно усложнило бы как саму игру, так и написание плагинов. А цель была — сделать всё достаточно просто.