Каковы проблемы и преимущества написания игр с функциональным языком?


81

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

Кроме того, с F # в качестве нового члена семейства .NET, его можно использовать напрямую, например, с XNA, что несколько снижает порог, в отличие от использования с LISP, Haskell, Erlang и т. Д.

Если у кого-то есть опыт написания игр с функциональным кодом, что оказалось положительным и отрицательным? Для чего он подходит, а для чего нет?

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


3
с одной из моих любимых игр (Rogue), написанной на LISP, этот вопрос (и его потенциал ответа) очень интересен для меня.
Джастин Л.

Не знал, что Роуг был написан на LISP, но нашел это интересным. Классическая игра. :)
Макмуттон

2
Не уверен, о чем ты говоришь. Роуг был написан в C. roguebasin.roguelikedevelopment.org/index.php?title=Rogue
Мейсон Уилер

2
Я уверен, что вы правы насчет оригинального Rogue в C, поскольку он был написан для Unix, но в Lisp есть несколько клонов Rogue : cl-user.net/asp/root-dir (не прямая ссылка Game) У него было так много спецсимволов, что, кажется, он сломал связь).
Циклоп

Ответы:


57

В настоящее время я работаю над игрой в Haskell. Я не могу говорить о функциональном программировании в целом, но конкретно о Haskell:

Добро

Это удивительные вещи, которые делают Haskell действительно выдающимся.

  • Чистота означает, что рассуждения о вашем коде намного проще. Вам не нужно беспокоиться о «текущем» значении переменной или о том, будет ли использование данной функции каким-либо образом конфликтовать с вашим глобальным состоянием. Это также означает, что с параллелизмом и параллелизмом гораздо проще работать (и во многих случаях тривиально). Эти вещи могут быть находкой для разработчиков игр.
  • Haskell позволяет очень легко писать на очень высоком уровне, используя абстракции собственного создания. Зачастую проще написать очень общий код, чем специализированный код на Haskell, и преимущества этого проявляются в меньшем времени разработки и более простом понимании кода. Это более верно в Haskell, чем в любом другом языке, который я знаю, что использование интерфейса похоже на использование совершенно нового языка (при сохранении преимуществ остальной экосистемы Haskell). То, что большинство языков называют языковыми функциями, Haskell называет библиотекой, и это не кажется вынужденным. Если вы когда-нибудь расскажете о своей игре в psuedocode, вы, вероятно, могли бы просто написать простой интерфейс и сделать его реальным кодом, и обычно это того стоит.
  • Это может противоречить другим ответам, но Haskell лучше справляется с императивным кодом, чем любой другой язык, который я знаю. Ограничения чистоты означают, что в Haskell существует разделение между понятиями «оценка» (сокращение выражений) и «исполнение» (выполнение побочных эффектов). Вы можете контролировать, когда и как побочные эффекты выполняются с легкостью, не имеющей аналогов в так называемых «императивных» языках. Несмотря на то, что я говорил о чистоте ранее, некоторые привязки C по-прежнему очень обязательны (OpenGL, я смотрю на вас), поэтому такой детальный контроль над императивным кодом очень приветствуется. Даже самые опытные программисты на Си, вероятно, оценят это, когда привыкнут к этому.
  • GHC генерирует довольно быстрые двоичные файлы. Они не такие быстрые, как двоичные файлы, сгенерированные из обычных компиляторов C, но находятся на порядок и намного быстрее, чем то, что вы достигли бы с интерпретированным языком. Даже если вы не можете написать свою игру на других языках высокого уровня, таких как Python, потому что она будет слишком медленной, есть хороший шанс, что вы можете сделать это в Haskell.
  • Несмотря на то, что в Haskell не так много библиотек, связанных с играми, как отмечается в разделе «Плохое» ниже, интерфейс сторонних функций Haskell является самым простым, что я когда-либо использовал. Вы можете связать с C, написав почти исключительно на Haskell.

Плохо

Это вещи, которые не очень хорошо , но могут быть разработаны вокруг , не слишком много усилий.

  • Время и усилия, необходимые для изучения Haskell, могут быть довольно высокими, если вы очень привыкли работать с нефункциональными языками. Сам язык не очень сложен, но когда вы учитываете общие языковые расширения и огромное количество библиотек (помните, многие вещи, которые вы могли бы рассмотреть в других языках - это библиотеки в Haskell), это выглядит гораздо более зловещим. На мой взгляд, оно того стоит, но другие могут не согласиться.
  • Некоторые люди много жалуются на лень. Если вы знаете, что делаете, вы не вызовете утечек пространства, которые трудно отследить (я не создавал утечку пространства уже пару лет), но у новичков с этим гораздо больше проблем. Было бы глупо с моей стороны расстреливать этих людей и утверждать, что это не проблема, но я утверждаю, что эта проблема легко решается с опытом.
  • В Haskell не так много хороших библиотек для создания игр, и не так много Haskellers пишут в нем игры, поэтому трудно найти ресурсы и помощь по этому вопросу.

Гадкий

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

  • Если вы пишете ресурсоемкую игру, сборщик мусора в GHC может вас сильно укусить. Это GC "Останови мир" от поколения к поколению, поэтому время от времени вы можете выбросить несколько кадров. Для некоторых игр это нормально, но для других это большая проблема. Я и некоторые другие разработчики игр, использующие Haskell, хотели бы видеть программный GC в реальном времени, реализованный для GHC, но, насколько мне известно, пока не предпринимается никаких усилий для этого. В настоящее время я не беспокоюсь об этом (и еще не видел пропущенных кадров), но по крайней мере еще одна команда прибегла к тому, чтобы поместить свой основной цикл рендеринга в C.

2
Что вы думаете о FRP?
Вэй Ху

4
@Wei Hu: Я большой поклонник идеи FRP, и я довольно тщательно ее исследовал, включая создание нескольких различных семантик и написание нескольких реализаций. Лучшие реализации все еще имеют серьезные ошибки семантики и / или реализации. Я бы сказал, что они жизнеспособны для разработки игр, но не имеют многих (пока) преимуществ перед традиционными подходами.
Джейк Макартур

1
Анонимный пользователь попытался отредактировать этот ответ, уничтожив «некрасивую» часть. «Сборщик мусора в Haskell теперь является параллельным, параллельным и генеративным по состоянию на 2011 год ( ghc.haskell.org/trac/ghc/blog/new-gc-preview
Яри ​​Комппа,

1
К сожалению, это не совсем так. Было установлено, что одновременный сборщик мусора слишком сложен, чтобы оправдать небольшое общее улучшение, и он не был объединен.
Джейк Макартур,

1
@ Hi-Angel Существует старый бэкэнд GHC, который генерировал C, но он ничем не отличается от генератора собственного кода или бэкэнда LLVM. Это все еще требует времени выполнения GHC. Кроме того, в C-бэкенде нет ничего особенного, что облегчит обход сборщика мусора. Если бы было так просто и дешево устранить GC, другие бэкенды, вероятно, сделали бы это тоже.
Джейк Макартур

19

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

В некоторых случаях возникали космические утечки, и хотя они вызывали небольшие проблемы, в общей схеме они были незначительными (например, по сравнению с обнаружением взаимоблокировок в Java-проектах аналогичного размера), и после их устранения они остались на месте.

Мы используем FRP, похожий на Yampa, и с ним, безусловно, связана кривая обучения, но как только это закончится, опыт очень положительный. Библиотеки не были для нас проблемой - все, что нам было нужно, было доступно. Задержки сбора мусора были особой проблемой, так как это для встроенной платформы. Мы использовали немного C ++ для управления анимацией. Производительность также была проблемой при использовании встроенной платформы (= медленный процессор). Мы сделали немного C, и мы также смотрим на новые технологии Haskell, такие как ускорение. Аниматор C ++ был на раннем этапе дизайнерским решением, и места, где код слишком медленный, - это очень маленькие области. В конце концов, мы хотим перевести все наши C на Haskell.

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


7
Прошло 5 лет с тех пор, как вы опубликовали этот ответ; Вы хотели бы обновить это? Как работает коммерческий игровой движок? Какие произведения оказались ценными? Удалось ли вам воспользоваться преимуществами параллелизма, как вы надеялись?
Леви Моррисон,

17

Дейв упоминает несколько отличных моментов, хотя я должен отметить, что Хаскелл решил обе свои проблемы. Безгражданство может быть обойдено с помощью монады состояния (EDIT: не совсем - см. Ниже) , а последовательность может быть обработана с помощью монады ввода-вывода (EDIT: или любой другой монады, в этом отношении ...) .

Проблемы, с которыми вы столкнетесь (и которые я пытался изучить как в программировании игр, так и в Haskell), в большей степени сходны с этими. (Все они специфичны для Haskell, поскольку я действительно еще не углублялся в какие-либо другие языки FP).

  • FP Кривая обучения: FP требует полного изменения мышления от итеративного программирования. Чтобы научиться думать с точки зрения карт и сгибов, а не петель, требуется умственная тренировка, если вы к этому не привыкли.
  • Кривая изучения Mathy: Haskell одновременно благословлен и проклят математической изощренностью его дизайнеров, потому что после изучения основ FP вы застряли с монадами, морфизмами, стрелами и множеством других соображений, которые, хотя и не являются жесткими сами по себе очень абстрактны.
  • Монады: этим щенкам нетрудно завладеть, особенно если вы принимаете утверждение Эрика Рэймонда о том, что они являются «хаком, превращающим композицию функций в способ принудительного упорядочения вызовов функций». К сожалению (хотя это становится лучше по мере того, как Haskell набирает популярность), многие объяснения монад либо нацелены на голову большинства программистов («они моноиды в категории эндофункторов!»), Либо по совершенно бесполезной аналогии (например, Удивительно точный пример Брента Йорги: « Монады как буррито !» Вы думаете, он шутит? Что никто не мог придумать такую ​​глупую аналогию в учебнике? Подумайте еще раз .)
  • Экосистема: если вам удалось преодолеть все другие препятствия на дороге, вы будете противостоять практической повседневной реальности работы с все еще в значительной степени экспериментальным языком. Да поможет тебе Бог, когда ты здесь. Вот здесь я и начал серьезно рассказывать о Scala, или F #, или о каком-то другом языке, где есть хоть какая-то гарантия взаимодействия с другими библиотеками. Однажды я заставил Haskell связать и загрузить библиотеки OpenGL в Windows. Это заставило меня чувствовать себя довольно хорошо. Затем привязки OpenGL были переизданы и сломали все, что я сделал. Это жизнь в Хаскел-ланде. Честно говоря, это может быть боль. Вы хотите обертку для двигателя Bullet? Это в Hackage - как оставьс ноября прошлого года. Вам нравится Ogre3d? Hackage имеет привязки только к подмножеству библиотеки . Суть в том, что если вы будете придерживаться языка, не имеющего преград для разработки игр, вы потратите гораздо больше времени на работу по основам сантехники, чем если бы вы просто следовали стаду и придерживались C ++.

С другой стороны, все быстро улучшается. И все действительно зависит от того, что вы хотите от опыта. Вы хотите создать игру и разместить ее на своем сайте в поисках славы и богатства? Придерживайтесь C ++ или Python. Но если вы хотите узнать что-то новое, что потребует от вас инноваций в ваших процессах, попробуйте функциональный язык. Просто будьте терпеливы с собой, пока вы учитесь.

У Антти Салонена есть интересный блог, в котором подробно рассказывается о его работе « снова-снова-снова-снова» с программированием игр на Haskell. Это стоит прочитать.

Редактировать (один год спустя): Теперь, когда я больше изучил монаду государства, я понимаю, что это не очень хорошее решение для государства, которое предназначено для сохранения вне определенной функции. Реальные решения безгражданства можно найти в Haskell в IOVar, ST, MVar (для безопасности потоков) или через что-то вроде Yampa, которое использует Arrows и FRP для управления внутренним состоянием, которое тем не менее скрыто от разработчика. (Этот список в порядке сложности, хотя первые три не особенно сложны, когда вы понимаете монады.)


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

5

Объектив Caml!

Использование функциональных языков может быть огромным преимуществом в большинстве видов разработки программного обеспечения, в основном потому, что они значительно сокращают время разработки. Я вижу большой потенциал для написания серверного бэкенда в игре или на уровне AI и логики на клиенте на функциональном языке. И как все знают, LISP использовался для создания сценариев NPC.

Если бы я попытался написать интерфейс игры на функциональном языке, я бы определенно выбрал Objective Caml , который является гибридным языком. Он является потомком ML и позволяет смешивать итерационные и функциональные стили, имеет целевую систему с объектами с состоянием. (Caml - это язык, на котором смоделирован F #.)

Привязки OpenGL, кажется, работают безупречно, и люди давно делают игры в OCaml. Язык может быть скомпилирован и потенциально очень быстр (он давно одержал победу над C в некоторых тестах, не так, как сейчас).

Есть также тонны библиотек. Все, от компьютерных наук до привязок ко всем видам библиотек.


4

На самом деле не является ответом ни на что, но я чувствую, что обсуждение игрового программирования на функциональных языках является неполным без упоминания о функциональном реактивном программировании (FRP) - http://www.haskell.org/frp/ - и его наиболее распространенной реализации ( Я думаю?), YAMPA - http://www.haskell.org/yampa/ .


3

Что касается преимуществ, посмотрите Чистую библиотеку игр (http://cleangl.sourceforge.net/) и платформерную игру. Как только вы разберетесь с синтаксисом (я призываю вас попробовать), вы увидите явную элегантность конструкций и то, насколько близко исходный код соответствует понятиям, которые они выражают. В качестве дополнительного бонуса, абстракция состояния и необходимость явной передачи состояния делает ваш код намного более дружественным к многоядерным процессам.

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


2

С моей точки зрения самые большие проблемы будут:

  • Отсутствие состояния функциональных языков. Идея в играх состоит в том, что каждая сущность имеет состояние, и это состояние изменяется от кадра к кадру. Есть механизмы, имитирующие это поведение в некоторых языках (например, функции с «!» В схеме plt), но это выглядит неестественно.
  • Порядок выполнения : В играх некоторые части кода зависят от других частей кода, которые должны быть завершены перед выполнением. Функциональные языки, как правило, не дают никаких гарантий относительно порядка выполнения аргументов функции. Есть способы имитировать это поведение (например, " (begin..." в схеме plt).

Не стесняйтесь расширять этот список (и, возможно, добавить некоторые положительные моменты ^^).


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

1

Вы можете написать свой код на C / C ++ и использовать встроенный язык, такой как Embedded Common Lisp, для своих сценариев. Хотя заставить их скомпилировать на другой платформе может быть сложно. Вы можете посмотреть Lisp In Small Pieces, чтобы узнать, как написать свой собственный язык сценариев. Это действительно не так сложно, если у вас есть время.


0

Я написал простые игры на LISP, и это было весело, но я бы не советовал. Функциональное программирование - это все о конечном результате. Так что это очень удобно для обработки данных и принятия решений, но я обнаружил, что это затрудняет создание простого чистого кода, такого как базовый цикл управления.

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


Моя первоначальная мысль может состоять в том, чтобы написать леса и обработку состояний с помощью императивного языка, а затем создать игровую логику и тому подобное с функциональными битами. С .NET и C # / F # это было бы очень легко, например, поскольку они используют одни и те же библиотеки и могут общаться друг с другом без какого-либо реального наказания, о котором я знаю.
Макмуттон

-1

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


11
Ты шутишь, что ли? FP - это общее программирование на стероидах. Возможность обобщать как типы данных, так и функции дает FP серьезную возможность управлять сложностью.
личность

Я согласен, одна из самых сильных сторон FP - это способность делать обобщенный код.
Макмуттон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.