Разумно ли писать игровой движок на С? [закрыто]

53

Несмотря на то, что C ++ кажется королем, из того, что мне сказали, C все еще широко используется в играх, особенно на консолях. Однако было бы неразумным писать весь игровой движок на C сегодня? Каковы, если таковые имеются, некоторые преимущества, которые C имеет по сравнению с C ++? Почему кто-то хочет использовать C над C ++?

Slurps Mad Rips
источник
1
Консольные игры используют C ++ FYI!
Алан Вульф
Я на самом деле думаю, что C будет проще писать игры в определенном масштабе, скажем, десятки тысяч LOC или около того, главным образом потому, что он позволяет вам просто сосредоточиться на битах и ​​байтах без сложных типов данных и строить очень быстро по сравнению с C ++. Но после определенного масштаба (скажем, достижения сотен тысяч LOC) я бы начал стремиться к C ++, где я фактически начал бы хотеть сложные типы данных, большую безопасность типов, возможно исключения, шаблоны и еще больше увеличиваться в масштабировать (скажем, миллионы), чтобы вещи, отличные от C ++, сочетались с кодом C и C ++.
C также имеет дополнительное преимущество, заключающееся в том, что он широко переносим даже для ABI, поэтому становится довольно легко взять существующий код C и затем начать использовать его на других языках, скажем, с FFI. C ++ немного неудобнее с искажением имен, неспособностью безопасно перебрасывать границы модулей, повторяемостью vtable, которая не одинакова для разных компиляторов, реализациями стандартных библиотек, отличающимися у разных поставщиков, и т. Д. В целом, я нахожу, что библиотеки C, которые я пишу, работают дольше, не требуя изменений и выходя из моды, хотя для написания чего-либо масштабного требуется больше времени.

Ответы:

49

Однако было бы неразумным писать весь игровой движок на C сегодня?

Это разумно, но вопрос в том, что он покупает? Скорее всего, вам не нужны экстремальные возможности переносимости, предлагаемые Си, и стыдно отказываться от всех возможностей, предлагаемых С ++, если вы не настроены философски против этого.

Каковы, если таковые имеются, некоторые преимущества, которые C имеет по сравнению с C ++?

Лучшее время компиляции?

Почему кто-то хочет использовать C над C ++?

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

необычайно щедрый
источник
3
До Id Tech 4
оптик
9
@Josh: легче отлаживать !? С-программы, как известно, трудно отлаживать, в основном из-за указателей и управления памятью. Программы на C ++ (при использовании настоящих идиом программирования на C ++, которые, по возможности, избегают указателей и управления памятью) , на несколько порядков легче отлаживать.
BlueRaja - Дэнни Пфлюгофт
14
С могут понять простые смертные. С ++, похоже, обладает множеством возможностей, и опытные программисты узнают о нем даже после десятилетия ежедневного использования.
Яри ​​Комппа
13
C ++ - большой язык, но его внушающая страх репутация распространена в основном людьми, которые только что прочитали страшные истории и не потратили время на их изучение. Есть чему поучиться, но за это вы получите много пользы. C ++ позволяет вам выразить много вещей, которые C просто не может.
Великолепно
2
@ BlueRaja-DannyPflughoeft, #define malloc(x) my_malloc(x) #define free(x) my_free(x)и теперь вы отлаживаете память. С C ++ вы никогда не знаете, что будет выделяться, когда, потому что есть так много способов выделить память (new, malloc, конструкторы классов и т. Д.)
YoYoYonnY
59

Я много работал с игровым движком pure-C, который поставлял несколько продуктов, так что это абсолютно возможно. Вот мой личный опыт работы с обоими C и C ++ движками:

  1. Использование структур pure-C позволяет вам воспользоваться знаниями о выравнивании структур, а затем вы можете использовать эту информацию для построения уровней персистентности и сериализации объектов. Движок, с которым я работал, имел несколько простых анализаторов заголовков, которые автоматически создавали эти метаданные о структурах, и это делало определенные типы операций с данными тривиальными. Разбор произвольных заголовочных файлов C ++ практически невозможен, и как только вы добавляете наследование и виртуальные функции, вы теряете способность точно знать, где что находится в памяти.
  2. Время компиляции значительно короче, потому что вы можете сохранять ваши заголовочные файлы очень компактными и использовать преимущества предварительных объявлений структур.
  3. Отладка может быть улучшена, потому что без использования шаблонов и наследования очень легко точно определить, что представляет собой определенный объект и что он делает.

Все эти преимущества также могут быть легко достигнуты с помощью ограниченного кода C ++, который воздерживается от использования шаблонов и наследования для сериализованных объектов, но решение CTO заключалось в том, что будет проще обеспечить простоту, если более запутанные элементы C ++ не будут доступный.

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

Бен Зейглер
источник
5
На самом деле ничто не мешает вам реализовать наследование в C. И если вы используете C99, вы можете объявить переменные в циклах for.
jsimmons
15
Собираемся не соглашаться с пунктом 3. Написание беспорядочного, сложного для отладки кода на C так же легко, как на C ++. Лучшая отладка не является чем-то присущим языку Си.
Дэн Олсон
7
Даже чистый код может быть труднее понять в C ++ - с перегрузкой, шаблонами, виртуальными функциями и исключениями, гораздо сложнее сразу увидеть, каким будет действительный поток управления.
Kylotan
6
@Dan: Просто имея больше вещей, C ++ сложнее отлаживать. Конечно, вы можете ограничить себя в использовании любого из этих вещей, и в этом случае его становится так же легко отлаживать, как и в С - потому что он становится С.
Меньше всего - причина, по которой мне нравится C. Например, в CI можно просто копировать биты и байты с memcpyчем угодно, потому что система типов не допускает таких вещей, как ctors и dtors. Я могу писать код, зная, что мне не придется откатывать побочные эффекты практически на любой строке кода, так как я не могу неявно выйти из функции, если я явно не вернусь из нее; нет никаких исключений, которые выбрасываются. Все это делает написание структур данных намного проще - в C ++ просто написание стандарта совместимо с vector
18

Я переписываю движок 2D игр, написанный на C ++ и Lua, на C и Lua. Пока что опыт был довольно хорошим. Очевидно, что выполнение векторных и матричных операций не выглядит так красиво в Си. Но кроме того, я нашел, что опыт довольно освежающий после более 10 лет, проведенных разработчиком на C ++.

C имеет ряд преимуществ перед C ++:

  1. Компилятор позаботится о том, чтобы код не выполнялся во время статической инициализации. Это делает полностью безопасным статическое размещение глобальных данных, таких как строки, используемые в качестве ключей, например
  2. Прозрачность. В C назначение или выделение или определение переменной не приведет к загрузке кода. C ++ автоматически сгенерирует для вас конструкторы копирования, так что вы будете иметь меньше контроля над тем, что выполняется при выполнении присваивания.
  3. Много отладки может быть проще из-за отсутствия искаженных имен функций
  4. Обычно нормально использовать memcpy в C, но это легко вызовет проблемы в C ++, потому что конструкторы копирования не будут запускаться. Учитывая, что memcpy намного быстрее, чем std :: copy, это важно.

Помимо этого, существует целый ряд преимуществ для понимания мышления. В C ++ я часто делаю вещи немного чрезмерно обобщенными и абстрактными. В CI обычно вырезают такие вещи, как методы get-set и часто предварительно выделяют массивы фиксированного размера, а не используют динамические массивы. Часто я получаю более короткий и более легко отлаживаемый код на C. Структуры данных обычно более плоские и их легче просматривать в отладчике.

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

Id software пишет, что большинство их движков написано на CI, вы можете посмотреть на Return to castle Wolfenstein, который был написан на C.

Я написал о своем опыте масштабирования C против C ++ и недостатках вектора STL по сравнению с простыми массивами.

Эрик Энгхейм
источник
11
К вашему сведению, в каждом экземпляре, который я проверял (например, darwin gcc и vc2008), std :: copy просто компилируется в вызов memcpy, если оба типа являются POD.
BRaffle
3
Кроме того, вектор RE: STL против простых массивов, почему бы не использовать красивые части вектора и использовать обычные указатели C вместо итераторов, если они вам не нравятся? Вы можете просто сделать & myvector [N]. Это как лучшее из обоих миров, если предположить, что ваш C-код распределяет память одинаково. Или, для циклов, проверьте BOOST_FOREACH. Делает это даже проще, чем C.
BRaffle
1
Спасибо за совет о std :: copy memcpy. Я этого не знал. Когда Александреску лечил это несколько лет назад, это было не так. Об итераторах C ++. В основном это философия, я пытаюсь запрограммировать, как C ++ должен был программироваться как для людей, с которыми я работаю, так и для использования возможностей C ++. В основном это было сделано для того, чтобы указать, что некоторые улучшения в C ++, такие как контейнеры STL, не всегда лучше, чем в старом C-стиле.
Эрик Энгхейм
7

Как кто-то еще отметил, C ++ дает преимущество больших плеч, на которых вы можете стоять (BOOST, STL и т. Д.). В конце концов, это личный выбор, но я бы выбрал C ++ из-за доступных ресурсов. Если в C ++ есть функции, которые вы не хотите использовать, не используйте их.

user266
источник
1
Обратите внимание, что 99% коммерческих и собственных игровых движков избегают Boost и STL по разным причинам (гарантия производительности, отладка, безопасность потоков, контроль).
Кай
42
И 99% статистики составляют.
BRaffle
Я чувствую, что должно быть в некотором смысле правилом цитировать всю статистику.
Мэтт Дженсен
3

Я не думаю, что кто-то использует C исключительно в наши дни, он обычно смешивается с языком более высокого уровня.

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

Таким образом, это может принести некоторые преимущества при написании критичных для производительности частей игры в стиле C, а не в традиционном C ++. Однако в последние годы я никогда не слышал о том, чтобы кто-то писал целую игру на Си.

На некоторых платформах, таких как iPhone, использование C ++ может увеличить размер исполняемого файла на определенный кусок килобайта (я забыл, сколько, извините), что является причиной, по которой некоторые разработчики iPhone предпочитают писать свой код в сочетании C и Objective. -С.

Сандер ван Россен
источник
3

Я дам вам еще пару причин, почему было бы неразумно писать игровой движок на C вместо C ++ сегодня: STL и BOOST.

Я не могу себе представить, как стоило бы написать еще одну listреализацию, если бы вы могли полагаться на код, который работает «из коробки» (и который вам не нужно писать!)

Лорис
источник
1
Любая большая студия на самом деле использует boost? Даже использование STL все еще обсуждается из-за портативности. По крайней мере, для консольных двигателей.
ломтики лайма
2
Лично я использую Boost.FunctionTypes для взаимодействия c ++ / lua (см. Gamedev.net/reference/programming/features/CPPLuaExport/… ) и библиотеку Boost для случайных чисел для генерации случайных чисел равномерного типа (для систем частиц). Кроме того, Boost.Foreach это аккуратно. Кстати, кого это волнует, если большие студии не используют BOOST? У меня есть рабочая сила для написания своих собственных библиотек STL с нуля, я не знаю.
Лорис
1
Да, но также понимают, что есть аналогичные библиотеки для Си.
jsimmons
2
Я полагаю, что в играх люди используют повышение в играх. Но это далеко от требования (или даже желательно) для многих из нас.
Дэн Олсон
6
Люди, во что вы верите, не имеет значения: либо вы знаете, либо не знаете .
о0 '.
3

Написание игрового движка на С разумно. Это быстро и может быть перенесено на несколько систем. Например, вы можете использовать для Android (с использованием NDK). Вы можете использовать его для iPhone (цель c - это просто расширение c). Вы также можете использовать его для основных ОС, таких как Linux, Mac или Windows. Если вы чувствуете себя комфортно с c, я предлагаю вам попробовать!

Люк Тейлор
источник
2

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

Что касается того, почему кто-то решил сделать это, я думаю, что это в основном связано с философией анти-C ++. Лично я все еще не думаю, что это хорошая причина, чтобы выбрать C вместо «C-style C ++». Сумасшествие typedef struct - достаточно веская причина, чтобы держаться подальше от C, и есть ряд других.

К сожалению, C и C ++ - довольно ужасные языки, когда мы приступаем к этому. Это одна из причин, по которой люди в последние годы пытаются сделать много кода в скрипте.

Если вы ищете примеры людей, работающих в C, вы можете игнорировать id, поскольку я помню, что читал, что они давно отказались от C. Cryptic Studios (Star Trek Online) все же разрабатывает свой движок на C. Насколько я могу сказать, да, это из-за философии больше, чем из-за какого-либо ощутимого преимущества.

Дэн Олсон
источник
0

И да и нет. Да, я сделал это несколько лет назад, но мне нужно было, чтобы моя игра работала в 3D на 64-битном удаленном сервере Unix (не Linux) с игроками на немых терминалах. Это было нетривиально. C может быть хорошим, если вы хотите интегрировать LUA, но я в конечном итоге заставил lua работать на C ++, поэтому я сказал бы, что да, но это возможно, но не делайте этого.

Джефф
источник
0

Может ли быть удачным ответом «использовать оба»?

Как я слышал, проекты panda3d можно оптимизировать, устраняя узкие места, используя какой-то cython или перекодируя эти части.

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

В идеале вы выполняете быструю часть движка с учетом высокого уровня, а затем используете язык сценариев или C ++, который будет использовать гораздо меньше гнезд / циклов.

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

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

jokoon
источник
0

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

Здесь вы можете найти список игровых движков, некоторые из которых написаны на C, возможно, вы можете получить представление о том, как создать игровой движок на C, изучив их исходный код.


источник
0

Код C обычно является допустимым кодом C ++.

Основные проблемы с C ++ - это неправильное использование ( Линус Торвальдс ненавидит его по этой причине , у него также были некоторые другие проблемы с переносимостью библиотек и т. Д. Он работает на уровне операционных систем и должен иметь возможность запускать программы на любой случайности). чип там).

Например, использование cstyle array [] почти не дает преимущества над c ++ std :: vector <> (или аналогичным контейнером).

Векторы являются безопасными с точки зрения типов и могут быть проверены с помощью границ (вы можете получить доступ к элементам, используя get () или [], даже если вы не используете метод массива с проверкой, вы все равно можете запросить размер, вместо того, чтобы перемещать его с помощью указателя).

Но векторы могут быть медленнее, если, например, вы не объявляете размер по умолчанию в конструкторе. Кроме того, добавление элементов в вектор может вызвать замедление, если затем потребуется изменение размера. C ++ 11 также добавляет много преимуществ, таких как равномерная инициализация (теперь вы можете объявлять и инициализировать векторы, используя один и тот же синтаксис), и есть конструкторы перемещения, которые могут позволить вам избежать копирования. Вы даже можете создавать свои собственные инициализаторы (если по какой-то причине вы хотели сделать что-то кроме использования malloc).

Или, конечно, если вам нужно изменить размер, то с векторами все еще проще это сделать, вам не нужно возиться с malloc, вручную копировать объекты и так далее.

C ++ дает вам объектно-ориентированный код. При компиляции это будет столь же эффективно, поскольку это просто абстракция для людей, работающих с кодом. Хотя такие вещи, как конструкторы, могут замедлять создание объектов. Но вам либо понадобится конструктор для установки значений по умолчанию, либо вы можете инициализировать объекты, не используя конструктор (исключая ()).

Но объектная ориентация делает программирование игр намного проще. Игры часто имеют дело с объектами.

Дэвид С. Бишоп
источник