Чи розумно писати ігровий движок на C? [зачинено]


53

Незважаючи на те, що C ++, здається, є королем, з того, що мені сказали, C все ще широко використовується в іграх, особливо на консолях. Однак чи було б написання цілого ігрового двигуна на C нерозумним сьогодні? Які існують, якщо такі є, які переваги C має над C ++? Чому хтось, можливо, захотів би використовувати C над C ++?


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 ++?

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


3
До Id Tech 4
оптик

9
@Josh: простіше налагодження !? C-програми, як відомо, важко налагоджувати, багато в чому через покажчики та управління пам'яттю. Програми C ++ (коли використовуються справжні ідіоми програмування на C ++, які, як правило, уникають покажчиків та управління пам'яттю, коли це можливо) на кілька порядків простіше налагодити.
BlueRaja - Danny Pflughoeft

14
C можна зрозуміти простих смертних. Здається, у C ++ є безліч функцій і кращих випадків, коли досвідчені програмісти дізнаються про навіть після десятиліття використання цього дня щодня.
Jari Komppa

13
C ++ - це велика мова, але її страхітливу репутацію поширюють здебільшого люди, які щойно читали страшилки та не вживали часу, щоб її вивчити. Є чому навчитися, але ви отримаєте багато цінності взамін за це. C ++ дозволяє висловити багато речей, які C просто не може.
чудовий

2
@ BlueRaja-DannyPflughoeft, #define malloc(x) my_malloc(x) #define free(x) my_free(x)і ви зараз налагоджуєте пам'ять. З C ++ ви ніколи не знаєте, на що буде виділено, оскільки існує так багато способів розподілу пам'яті (new, malloc, конструктори класів тощо)
YoYoYonnY

59

Я широко працював з ігровим двигуном чистого типу C, який поставив кілька продуктів, так що це абсолютно можливо. Ось мій особистий досвід роботи в обох двигунах C vs C ++:

  1. Використання структур чистого типу дозволяє скористатися знаннями про вирівнювання структур, а потім ви можете використовувати цю інформацію для побудови шарів стійкості та серіалізації об'єкта. Двигун, з яким я працював, мав кілька простих аналізаторів заголовків, які автоматично створювали б ці метадані про структури, і це робило певні типи операцій з даними тривіальними. Розбір довільних файлів заголовків C ++ по суті неможливий, і як тільки ви додасте спадкування та віртуальні функції, ви втрачаєте здатність точно знати, де знаходяться речі в пам'яті
  2. Час компіляції значно коротший, оскільки ви можете зберегти файли заголовків дуже компактними та скористатися перевагами декларацій структур.
  3. Налагодження можна вдосконалити, оскільки без використання шаблонів та успадкування дуже легко зрозуміти, що саме є певним об’єктом і що він робить.

Усі ці переваги також можна було б досягти так само легко, використовуючи обмежений код c ++, який утримується від використання шаблонів та успадкування на серіалізованих об'єктах, але рішенням СОТ було простіше застосувати простоту, якби більше заплутаних елементів C ++ не було в наявності.

Особисто я вважаю, що це було трохи екстремально, тому що я дійсно втратив можливість справедливого оголошення змінних для циклів і безліч цілком законних цілей використання для успадкування. Але насправді це не коштувало нам великої продуктивності, врешті-решт, все, що розглядається


5
Насправді ніщо не заважає вам реалізувати спадщину в C. І якщо ви використовуєте C99, ви можете оголосити змінні для циклів.
jsimmons

15
Якщо не погодитися з точкою 3. Написати безладний, важко налагоджуваний код на C так само просто, як і в C ++. Краще налагодження - це щось не властиве мові С.
Дан Олсон

7
Навіть чистий код може бути важче зрозуміти в C ++ - з перевантаженням, шаблонами, віртуальними функціями та винятками набагато складніше з першого погляду зрозуміти, яким буде фактичний потік управління.
Кілотан

6
@Dan: Просто маючи більше речей, C ++ важче налагоджувати. Звичайно, ви можете обмежити використання будь-якого з цих речей, і в цьому випадку

Менше матеріалів насправді є причиною, що мені подобається C. Наприклад, в CI можна просто копіювати біти і байти навколо з memcpyбудь-чим, тому що система типу не дозволяє речей, таких як копіювальні диски та диски. Я можу написати код, знаючи, що мені не доведеться відмовляти побічні ефекти майже в будь-якому рядку коду, оскільки я не можу неявно вийти з функції, якщо я явно не повернуся з неї; не є винятками, що їх кидають. Все це робить написання структур даних набагато простішим - у C ++ просто написання стандартної сумісності vectorдуже трудомістке, особливо якщо ви хочете зробити це ...

18

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

C має низку переваг перед C ++:

  1. Компілятор переконається, що в час статичної ініціалізації не запускається код. Це дозволяє абсолютно безпечно статично розподіляти глобальні дані, такі як рядки, що використовуються як ключі, наприклад
  2. Прозорість. У C присвоєнні або виділенні чи визначенні змінної не збирається викликати завантаження коду. C ++ автоматично генерує для вас конструктори копій, щоб ви мали менший контроль над тим, що виконується при виконанні завдання.
  3. Багато налагодження може бути простішим через те, що вони не отримують імен функцій, згаданих
  4. Зазвичай нормально використовувати memcpy в C, але це легко спричинить неполадки в C ++, оскільки конструктори копій не запускатимуться. Враховуючи, що memcpy набагато швидше, ніж значення std :: copy .

Крім того, є ряд переваг, щоб потрапити на C-спосіб мислення. У С ++ я часто опиняюсь, що роблю речі дещо надмірно генералізованими та абстрактними. У КІ зазвичай вирізають такі речі, як методи набору заданих параметрів, і часто попередньо виділяють масиви фіксованого розміру, а не використовують динамічні масиви. Часто я закінчую більш коротким та легким налагодженням коду в C. Структури даних, як правило, більш плоскі та простіші для перегляду в налагоджувачі.

Якщо чесно, я б ніколи не робив додаток виключно в C. Причиною, що це працює, є те, що я поєдную його з мовою вищого рівня, як Lua, яка може дуже добре доповнити C, якщо C не настільки сильна.

Ідентичне програмне забезпечення пише більшість своїх двигунів в CI вважають, ви можете подивитися на " Return to Castle Wolfenstein", який був написаний на C.

Я писав про деякий мій досвід щодо масштабованості C проти C ++ та мінусів вектора STL порівняно із звичайними масивами.


11
FYI, у кожному випадку, який я перевірив (що, я думаю, 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 ++ є функції, які ви не бажаєте використовувати, не використовуйте їх.


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
Чи справді якась велика студія використовує стимул? Навіть використання STL досі обговорюється через портативність. Принаймні для консольних двигунів.
нарізаний липою

2
Особисто я використовую Boost.FunctionTypes для взаємодії c ++ / lua (див. Gamedev.net/reference/programming/features/CPPLuaExport/… ) та бібліотеку збільшити випадкові числа для рівномірного генерування випадкових чисел (для систем частинок). Крім того, Boost.Foreach акуратний. BTW, кого турбує, якщо великі студії не використовують BOOST? У них є сила для написання власних бібліотек STL з нуля, я не знаю.
Лоріс

1
Так, але також розумію, що є подібні бібліотеки і для C.
jsimmons

2
Думаю, що багато людей використовують імпульс в іграх. Але це далеко не вимога (або навіть бажана) для багатьох із нас.
Ден Олсон

6
Люди, те, що ви вірите , не має значення: або ви знаєте, або не знаєте .
o0 '.

3

Писати ігровий движок на C розумно. Це швидко і може бути перенесено в декілька систем. Наприклад, ви можете використовувати для Android (з використанням NDK). Ви можете використовувати його для iPhone (Objective c - це лише розширення c). Ви також можете використовувати його для та для основних ОС, таких як Linux, Mac або Windows. Якщо ви відчуваєте себе комфортно з c, пропоную спробувати!


2

Звичайно, це розумно. Я особисто цього не зробив, і більшість фанатів C, яких я знаю, насправді просто записують C-подібний код у файли .cpp. Але мови досить схожі на те, де це насправді не має значення.

Щодо того, чому хтось вирішив би це зробити, я думаю, що це здебільшого зводиться до філософії анти-С ++. Особисто я все ще не думаю, що це є вагомою причиною вибирати C над "C-style C ++". Безглуздість типу typedef - це достатньо вагомий привід уникати C, і є ряд інших.

На жаль, і C, і C ++ є досить страшними мовами, коли ми переходимо до цього. Це одна з причин, що люди намагаються зробити багато своїх кодів у сценарії в останні роки.

Якщо ви шукаєте приклади людей, які працюють в C, ви можете ігнорувати ідентифікатор, коли я пам'ятаю, читаючи, що вони давно відмовилися від C. Cryptic Studios (Star Trek Online), однак, розробляє всі свої двигуни в С. Наскільки я можу сказати, так, це через філософію більше, ніж через якусь відчутну перевагу.


0

Так і ні. Так, я зробив це кілька років тому, але мені потрібна була моя гра для запуску в 3D на unix (не linux) 64-бітному віддаленому сервері з гравцями на німих терміналах. Це було нетривіально. C може бути приємно, що ти хочеш інтегрувати LUA, але я врешті-решт отримав луа для роботи в C ++, тому я б сказав, що так можна, але не робіть цього.


0

Можливо, можливою доброю відповіддю буде «використовувати обох»?

Як я почув, що проекти panda3d можуть бути оптимізовані, вбиваючи вузьке місце або використовуючи якийсь цитон, або перекодуючи ці частини.

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

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

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

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


0

C працював на Джона Кармака , ви можете отримати чимало переваг, використовуючи C, але поки ви не отримаєте там користь від них, це може зайняти певний час.

Тут ви можете знайти список ігрових двигунів, деякі з них написані на мові C, можливо, ви можете дізнатися, як зробити ігровий движок C, переглянувши їх вихідний код.


0

Код С зазвичай є дійсним кодом С ++.

Основні проблеми з C ++ - це неправильне його використання ( Лінус Торвальдс ненавидить його з цієї причини ; у нього також були деякі інші проблеми з переносністю бібліотек і так далі. Придбати він працює на рівні операційних систем, і він повинен мати можливість виконувати всі випадки чіп там).

Наприклад, майже немає переваги використовувати масив cstyle [] над c ++ std :: vector <> (або подібним контейнером).

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

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

Або, звичайно, якщо вам потрібно змінити розмір речей, тоді з векторами все ще простіше це зробити, вам не доведеться возитися з malloc, копіювати речі вручну тощо.

C ++ дає вам об'єктно-орієнтований код. Коли буде складено, це буде настільки ж ефективно, оскільки це справді просто абстракція для людей, які працюють з кодом. Хоча такі речі, як конструктори, можуть уповільнити створення об'єктів. Але вам буде потрібен або конструктор для встановлення значень за замовчуванням, або в іншому випадку ви можете ініціалізувати об'єкти, не використовуючи конструктор (відмовивши від ()).

Але орієнтація на об’єкти значно спрощує ігри з програмуванням . Ігри часто мають справу з предметами.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.