Змагається з C ++ для програмування ігор


21

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

Це просто тому, що це швидко? Це якась інша особливість у мові, наприклад парадигма ОО або переносимість? Це через всі створені з часом бібліотеки? Або якесь поєднання всіх цих (та інших) причин?

Якби хтось міг би мене заповнити, я був би дуже радий. :-)


7
Швидкість для мене є достатньою причиною, тим більше, що скарги кожного на мову насправді не мають для мене сенсу.
Бенджамін Ліндлі

Швидкий здогад: Більшість ігор написані для Windows. Мови C та C ++ активно підтримуються Microsoft. І нарешті, C ++ є кращим через метапрограмування OOP та шаблонів.

@ Метт Спасибі, не знав, що вона існує. Чи можу я перемістити тему туди, або я повинен її видалити і відтворити там?

Про це вже запитували кілька разів.
Zan Lynx

1
@ Бенджамін: Тоді я смію сказати, що ви недостатньо написали на C ++ або ви ніколи не використовували більш виразну мову, як Python (або навіть C # з LINQ). Однак, навіть якщо з якоїсь божевільної причини ви віддаєте перевагу написанню коду з 20 рядків для того, що можна зробити для багатьох інших мов у 1, вкрай погана граматика C ++ означає, що для збирання програм потрібно значно довше, ніж слід, та належних інструментів IDE (рефакторинг тощо). їх складніше, якщо не неможливо створити.
BlueRaja - Danny Pflughoeft

Відповіді:


29

Численні причини:

  • Великий, який ви пропустили: це портативний, спрощує порти вашого ігрового двигуна до iOS, XBOX, PS3, будь-що
  • Це швидко
  • Усі SDK підтримують це на самому світі
  • Доступно багато бібліотек
  • Усі, хто пише ігри, знають це, тому легко найняти досвідчених розробників ігор для своєї команди
  • Вбудовувати таку мову сценаріїв ігрового двигуна, як Lua, нереально

Добре, дякую за ваші відповіді всім, ви покрили все, що мені потрібно, я думаю. :-)
KasMA1990

14

Є кілька причин, які я хотів би зазначити на додаток до того, що підніс @Graham.

  • Спадковий код - у багатьох студіях є багато коду С ++, йдеться про вашу згадку про бібліотеки.
  • C ++ справді є високомобільним асемблером прямий доступ до апаратних засобів (настільки ж прямих, як можна принаймні працювати над поверхнею Операційної системи) і досить швидко. Якщо ви хочете, в C ++ ви можете перейти безпосередньо до мови складання для контролю рівня інструкцій (не те, що це завжди розумно, просто неможливо з Java, C #, Python тощо)
  • DirectX і OpenGL в основному підтримують C ++, більшість інших мов мають "прив'язку" до базових бібліотек через проміжні шари, тобто не кажучи, що вони не швидкі або не можуть робити багато одних і тих же речей, але це додає шару програмного забезпечення між вашу гру та обладнання.
  • Як згадує @Graham, багато програмістів знають це, тому його легко знайти досвідчених розробників, а також його досить портативний, порівняно з C #, який застряг у .NET Framework (є Mono, але він, як правило, відстає на покоління позаду впровадження Microsoft .)

Ви не маєте на увазі низького рівня?
поштовх

5
C ++ - low-levelмова; але high-levelасемблер, ІМО.
Нейт

3
Я не погоджуюсь. C ++ - мова високого рівня, вбудована програма може повернутися до C (що є мовою низького рівня).
foo

7
C ++ - мова високого рівня, як і C. Асамблея - низький рівень. Тепер C ++ є вищим, ніж C, як і C #, ніж C ++, а Ruby / Python вище C #.
AA Grapsas

4
Чому слід застарілий код застаріти (не амортизувати)? "Спадковий код" просто означає, що він старий, не те, що він поганий.

8

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

Складне розуміння полягає в тому, що при виборі мов програмування існує загальний компроміс між ефективністю для комп'ютера та ефективністю для програміста. Тобто, що для вас важливіше, як швидко комп'ютер запускає код або як швидко програміст записує код?


3

У C ++ ви можете виділити локальні змінні, які зникають після закінчення функції. Зазвичай вони виділяються на стек.

Змінні стека не сприяють питанням динамічного розподілу пам'яті фрагментації та накладних витрат. Розміщення кімнати на стеці - це швидко і просто (просто налаштування покажчика). Динамічне розподіл пам’яті зазвичай включає пошук контейнера для адекватного блоку пам’яті, маркування пам’яті та позначення її як зайнятої. Розміщення включає додавання блоку пам'яті до контейнера та, можливо, його об'єднання з існуючими блоками. Набагато більше накладних витрат, ніж просто зміна вказівника.

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

Швидкість C ++ пов'язана насамперед з його прямим перекладом у виконуваний код. Java та C # складаються з проміжного коду, який потім інтерпретується віртуальною машиною. Взагалі мови інтерпретації є більш повільними, ніж безпосередньо перекладені.


1
-1 (якщо я міг) - локальні примітиви виділяються на стеці і в Java, і в C #, а в C # ви можете створювати виділені стеки structs. Більш того, надзвичайно малий приріст швидкості цієї мережі вам недостатньо майже для виправдання однієї мови над іншою. Про справжню причину заявляє @Graham Perks: це те, про що, як очікується, знають розробники ігор, тож це те, чого дізнаються нові розробники ігор, і на які нові SDK орієнтовані. Є безліч мов (наприклад, перехід), які так само швидко чи швидше, і майже не такі зручні для написання.
BlueRaja - Danny Pflughoeft

C ++ не дуже добре в розподілі стеків; насправді дуже важко виділити STL-сумісні об’єкти на стеку. Наприклад, останній великий двигун, над яким я працював, знаходився в C, і у нас був рядок, який можна було запустити на стеку з певним фіксованим розміром (зазвичай 1 К). Якщо він виріс повз, він прозоро перемістився до купи. Можна зробити кілька подібних речей за допомогою спеціальних алокаторів std :: string в C ++, але код настільки складніший, щоб вийти правильно.

1
@Joe Wreschnig: C ++ чудово підходить для розподілу стеків, просто скиньте список мов асемблера. Однак більшість постачальників компіляторів не виділяють величезну кількість пам'яті на стек. Загальне розуміння досвідчених програмістів на C ++ полягає в тому, що величезні об'єкти динамічно розподіляються (купу), а не локальним сховищем (стеком). Величезні предмети на стеці можуть переростати в купу на деяких платформах, оскільки стек і купа ростуть один до одного.
Томас Меттьюз

1
Загальне розуміння більш досвідчених програмістів на C ++, особливо тих, що знаходяться на ігрових консолях, полягає в тому, що все, що не переповнить стек, виділяється або попередньо розподіляється. C робить це просто, оскільки розподільник не є частиною структурного типу об'єкта. Це також дозволяє звільнити щось неправильно, але, на мій досвід, це рідкісна проблема порівняно з тим, хто викручує реалізацію / сумісність розподільника, сумісного зі stdlib. Також є кілька хитрощів із розміщенням нових, але знову ж таки, це складніше, ніж еквівалент у C.

2
Ні. Перевага швидкості C ++ пояснюється його здатністю використовувати ваш власний написаний на замовлення менеджер пам'яті для розподілу купи . Кожна розумна мова виділяє місцевих жителів на стек.
забудьте

3

Ігри колись писалися машинною мовою, оскільки вони мали екзотичне обладнання, для якого не було компілятора. В апаратному забезпеченні також бракувало функцій, які програмісти C сприймають як належне, наприклад, ефективну 16-бітну цілочисельну математику.

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

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

Здавалося б, зараз, коли комп'ютери в 1000 разів швидше, ніж кілька років тому, мова високого рівня зменшить час розробки ($), зробивши C застарілим.

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

Вимоги до продуктивності в іграх жорстокі. Новий графічний кадр повинен бути викладений за 33 мс (або 16 мс!) Безвідмовно. Все, що робить обладнання, повинно враховуватися, щоб цей бюджет можна було виконати. Будь-яка мова, яка вимикається і робить щось із апаратним забезпеченням, яке програміст не розуміє і не очікує, дуже важко буде виконати цей бюджет. Це автоматичний мінус проти чогось високого рівня.

Ігрові програмісти не лише працюють мовою низького рівня, але й уникають структури даних та алгоритми високого рівня. Зазвичай ігри не мають пов'язаних списків і рідко мають дерева. Існує рух до уникнення покажчиків, коли це можливо *. Будь-який алгоритм з більш ніж O (N) часом або O (1) простором, як правило, не знаходить широкого застосування.

* Якщо вказівник не викликає пропущення кешу, то навіщо витрачати 32 біти на його зберігання? Якщо вказівник викликає пропущення кеш-пам'яті, найкраще позбудьтесь цього пропуску кешу.


1
"У C ++ немає жодної функції, яка, на мою думку, покращує ігри." ЛОЛ? OOP? Клас humanіз похідними playerта enemy?
orlp

2
@nightcracker: Basic is - спадщина прекрасно працює на C; стосунки, які ви описуєте, у будь-якому випадку краще реалізовувати, використовуючи has-a з причин продуктивності та чистоти.

3
Зростає консенсус щодо того, що функції OOP C ++ не підходять для ігор, оскільки ці функції функціонують на припущеннях, які є ворожими для кешування.
bmcnett

Навіть якщо ви вважаєте, що C ++ не має переваг перед C, ви, безумовно, повинні визнати, що повернення до C також не має переваг перед C ++.
Ден Олсон

@Dan Повернення до C пропонує перевагу в тому, що "найкращі практики", такі як не використання шаблонів або OOP, застосовуються за допомогою помилок часу компіляції, а не за допомогою переслідування молодших програмістів. Крім того, оскільки мова є простішою, імовірно, компілятором, і технічне обслуговування налагоджувача теж дешевше.
bmcnett

3

Кожна мова програмування має сильні та слабкі сторони в різних факторах. Прикладами таких факторів є:

  • Швидкість на певній платформі
  • Використання пам'яті на певній платформі
  • Яку функціональність вона відкриває легше
  • На яких платформах існує
  • Які міркування програміст повинен взяти на борт

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

Ще одним важливим фактором є віддавання переваги програмуванню мовою проблеми, а не мовою реалізації. Ігровий програміст хоче мати справу з людьми, орками та гоночними автомобілями, а не реєстром пам'яті ED0. Вони все ще хочуть зануритись у деталі реалізації, якщо їм потрібна продуктивність, але було б чудово, якби здебільшого вони могли мати справу з рівнем суб'єктів у своєму ігровому світі. Їм вистачає турбуватися про імітацію ігрового світу, не завжди дбаючи про те, як працює пов'язаний список.

C ++ дуже добре відповідає цим двом основним факторам. Ви можете мати переваги продуктивності збірки або C-коду з виразністю об'єктів. Щоб дізнатись, чому це природно підходить для ігор, порівняйте з іншими мовами:

  • Збірка: Це сировина. Те, що ви пишете, це в основному те, що робить процесор. Але на кожному етапі потрібно знати, що відбувається з регістрами та наслідками цього, і це ніколи не схоже на сутності у вашому ігровому світі. Програміст повинен скласти ментальну відповідність того, що робить їх код, порівняно з тим, що відбувається в грі. Це може бути досить розумовим накладним.
  • C: Тут ми маємо хороші показники, але ми можемо використовувати досвід гуру, щоб виконати стандартні речі (наприклад, виділити пам'ять, працювати на струнах і використовувати стандартні математичні функції). Ми наближаємось до виразності тут, але мова більш-менш змушує вас зосередитись на реалізації, оскільки ви дійсно можете працювати лише на звичайних типах даних. Все справді є чаром, інтом чи подібним. структури, покажчики та масиви можуть утримувати речі разом, але все-таки треба думати про внутрішні.
  • Java: Ми перестрибуємо через C ++ і дістаємось до Java. Java відштовхується від деталей впровадження. Насправді, більшу частину часу ти не отримуєш доступу до нижчих рівнів. Java абстрагує більшу частину деталей про реалізацію (наприклад, який процесор або ОС ви використовуєте) з тієї причини, що вона хоче бути платформою. Ви не можете отримати доступ до деталей, оскільки їх там немає. Ви не програмуєте на комп’ютер, ви програмуєте на платформу (платформа Java, яка, як правило, існує на більшості комп'ютерів). Більше того, Java має, мабуть, кращу мову для вирішення мови проблеми, ніж C ++. Не можна оптимізувати конкретний комп'ютер. Чи це робить практичну різницю, чи ні, зводиться до специфіки програми та комп'ютера.
  • Мова скриптових ігор: Під цим я маю на увазі щось на зразок UnrealScript або власні мови сценаріїв, прив'язані до ігрового двигуна. У них у вас немає доступу до основного двигуна. Ви делегуєте міркування щодо продуктивності двигуна, залишаючи себе вільно турбуватися про створення гри. Простіше написати гру, складніше оптимізувати її продуктивність самостійно.
  • Haskell (або улюблена незрозуміла мова): Будь -яка мова програмування, повністю завершена Тьюрінгом, еквівалентна будь-якій іншій. Отже, хоча ви можете написати будь-яку програму будь-якою мовою, ви робите компроміси, деякі об'єктивні, якісь суб'єктивні. Мова на зразок Haskell більше зосереджена на роботі в математичному дусі. Проблеми, на які вона спрямована, дещо відрізняються від проблем, що виникають в іграх. Це не означає, що він не може або не повинен використовуватися для ігор, він просто не підходить для нього.

Останній пункт - це щось історичне та політичне. Багато вогняних воєн велися між різними мовами програмування. Наприклад, C # може бути настільки ж підходящим для розробки ігор, але він з'явився після C ++. Або людям не подобається, що це від Microsoft. Деякі люди перейшли на C #, деякі - ні. Деякі люди все ще програмують ігри на BASIC, Pascal та C. Що б програмістам було комфортно, вони будуть дотримуватися. Ігрові програмісти в основному зручніше з C ++, можливо, тому, що вони виросли на C і C ++, і це відповідало їхнім потребам. Якщо комп'ютерна галузь перебуває у стані, коли продуктивність та сприйняття Java задовольняє достатньо людей, то, можливо, Java буде фактично стандартною мовою розвитку ігор.


2

Спадщина та імпульс.

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

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


2

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

Оскільки багато розробників - консолі + ПК, є сенс робити всі свої ПК на тій же мові та безпосередньо ділитися технологіями.

Оскільки саме там живе професійна галузь, і більшість всіх хоче стати частиною цього, більшість ігрових програмістів - це програмісти C ++.

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

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


2

FWIW: C # набирає популярності для розвитку ігор. Дивіться допис у блозі Мігеля де Ікази . Дуже цікаво читати, ІМХО.


2
Як звичайно, Мігель висуває свої улюблені (зазвичай маргінальні) технології, ігноруючи способи, коли C # насправді став великим гравцем у галузі, наприклад, XNA.

2

Хоча я досить сильно проти C, C і C ++, одна річ, яку вони РОЗДІЛУЮТЬ у небагатьох інших мовах, - це повний контроль над платформою, на якій вона працює, ви можете бути впевнені, що саме відбуватиметься постійно, ні GC, жодних збоїв.

Це не так важливо в наші дні, але це може бути для слабких платформ.

На ПК / Mac / Linux це, мабуть, найменш портативна мова, з якою ви стикаєтесь у ці дні, і бонус за швидкість вже не є великою різницею - Minecraft (Java) плавний і працює на досить мінімальних платформах (і будь-якій ОС) з єдиним виконуваним файлом - я ще не бачив програми для C / C ++ з низькою робочою силою з такою ж функціональністю і мало помилок, не кажучи вже про роботу на трьох платформах.

Тож на цьому етапі я б сказав, що більшість із них - це інертність і уявлення про те, що реальні ігри завжди робляться в C / C ++, хоча можливість "портувати" на iPhone та консолі є важливою (Хоча я досить впевнений, що більшість користувальницького інтерфейсу ігор вимагають багато зусиль, щоб перенести порт, за винятком Windows та XBox).


1
О, я не знаю, що це важливо лише для платформ, що не мають потужності. Інший спосіб поглянути на це - це те, що ігри завжди є на передньому плані продуктивності на будь-якій платформі: будь-яка нова потужність одразу ж збивається. Якщо ми говоримо про професійну розробку ігор, то продуктивність - це головна проблема: ти не пишеш Unreal, не максимізуючи кожен останній цикл, який може запропонувати машина. Кожен; одинарний; цикл. На кожному рівні - від доступу до графічного двигуна та диска до циклу інтерфейсу користувача.
Кріс Субаджо

@Chris: Найкращий спосіб, який я описав, щоб описати це програмістам, що не грають, - це те, що ігри - це область, де швидкість є конкурентною перевагою. Якщо ваш текстовий процесор запускається через 5 секунд, коли MS Word займає 10, або поповнює через 0,1 секунди, коли Word займає 0,2, це нічого не варто. Але якщо ваша гра може викачати навіть на 10% більше фрагментів або показати ще один детальний характер, це може бути величезною конкурентною перевагою.

Тоді хіба не було б дурним коли-небудь кодувати що-небудь, крім складання? Це, безумовно, було б принаймні на 10% швидше. Є момент, коли ви закликаєте торгувати продуктивністю заради ремонтопридатності та швидкості розвитку. Зазвичай ця точка є C ++ в наші дні. Було б добре, якби можливість переходити на платформу, як Minecraft, мала більше ваги.
Білл К

Так, але помилка полягає в тому, що кодування в монтажі відбувається швидше: поточні мікросхеми є досить складними, що програмісту важко послідовно перевершувати компілятор. Тільки в таких обмежених областях, як SPU на PS3, внутрішні петлі фізики та шейдери на графічних процесорах все ж є очевидними перевагами. Наразі C ++ - це найприємніше місце, із застереженням, що OOP не завжди є найкращим вибором: триваюча дискусія Struct of Arrays vs Array of Structs - це не зовсім мовна дискусія, але C ++ явно веде вас до AoS природно; Іноді ... ти справді просто хочеш С.
Кріс Субаджо

Етап ефективності програміста між асемблером і C / C ++ також на порядок більше, ніж крок ефективності програміста між C і C ++, або C ++ і C # / Java. Фред Брукс зазначив це 25 років тому.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.