Які типові підводні камені під час написання ігор з керованою мовою, як C #? [зачинено]


66

З якими підводними каменями ви стикалися, коли писали ігри для ПК з керованою мовою на зразок C # і як ви їх вирішували?


Це питання краще задавати в Stack Overflow, оскільки мало що стосується ігор.
Кріс Гарретт

31
@Chris: категорично не згоден: у питанні конкретно згадуються ігри! Проблеми, з якими ви стикаєтесь, коли вам потрібно оновлювати оновлення кожні 16 мс, дуже відрізняються від проблем, які ви отримаєте в більшості настільних програм.
Ендрю Рассел

Питання досить незрозуміле. Java та C # досить різняться, що стосуються обох дуже загальних порад. Усі відповіді поки що були C #. Також не згадується цільова платформа - хороші поради можуть відрізнятися залежно від пристрою (наприклад, програмування для мобільного телефону, zune, xbox, відмінне від програмування для ПК). Навіть було досить широким питанням, щоб хтось відповів, що керовані мови самі по собі є "підводним каменем".
paulecoyote

@paulecoyote: я змінив питання, щоб запитати лише про C #. Крім того, оскільки конкретної платформи не згадується, мова йде про ПК.
Майкл Клемент

Платформа @Michael припускає небезпечне припущення, оскільки вони настільки відрізняються між собою в реалізації, було б добре згадати Windows і відмовитись "як" і "Java" взагалі.
paulecoyote

Відповіді:


69

Я не знаю багато про Java, тому це з точки зору .net dev.

Найбільший на сьогоднішній день - сміття. збирач сміття .net на вікнах робить фантастичну роботу, і ви можете піти, не зважаючи на немовля. У xbox / winPhone7 це вже інша справа. Якщо ви отримуєте кіоски на кожні кілька кадрів, збирання сміття може викликати у вас проблеми. На даний момент він спрацьовує після кожного виділення 1mb.

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

  • Намалюйте вміст GC.GetTotalMemory()на екрані. Це дає приблизну кількість виділених байтів, які використовує ваша гра. Якщо він ледве рухається, у тебе все гаразд. Якщо це швидко йде, у вас є проблеми.
  • спробуйте виділити всі ваші об'єкти купи спереду. Якщо ви не виділите все до початку гри, кожен раз, коли ви потрапляєте на межі асигнувань, ви збираєтеся зупинитися. Ні асигнувань, ні колекцій. Так просто.
  • Після завантаження зателефонуйте GC.Collect (). Якщо ви знаєте, що більшість ваших великих асигнувань не виходить, лише приємно повідомити про це систему.
  • НЕ дзвоніть GC.Collect()кожен кадр. Це може здатися гарною ідеєю, зберігаючи на своєму смітті і все таке, але пам’ятайте, що тільки з гіршим, ніж збирання сміття, - це над вивезенням сміття.
  • Шукайте, звідки бере ваше сміття. Є деякі загальні причини , як конкатенації рядків замість використання StringBuilder(будьте обережні, StringBuilderце не чарівна паличка, і все ще можуть привести до розподілу! . Це означає , що прості операції , як додавання номера в кінець рядка може створювати дивовижні кількості сміття) або використання foreachциклів над колекціями, які використовують IEnumerableінтерфейс, також може створювати сміття, не знаючи (наприклад, foreach (EffectPass pass in effect.CurrentTechnique.Passes)це звичайна)
  • Використовуйте такі інструменти, як CLR-пам'ять CLR, щоб визначити, де виділяється пам'ять. Існує безліч навчальних посібників про те, як користуватися цим інструментом.
  • Коли ви знаєте, де розподіляється під час гри, подивіться, чи можна використовувати хитрощі, як об’єднання об’єктів, щоб зменшити кількість розподілу.
  • Якщо все інше не вдається, змушуйте колекції працювати швидше! GC на компактній основі слід за кожним посиланням у вашому коді, щоб з’ясувати, які об’єкти вже не використовуються. Refactor ваш код використовує менше посилань!
  • Не забудьте використовувати IDisposableна класах, які містять некеровані ресурси. Ви можете використовувати їх для очищення пам'яті, GC не може звільнитися.

Інша річ, про яку слід подумати - це продукти з плаваючою комою. Хоча .Net JITer робить досить багато оптимізацій, пов'язаних з процесором, він не може використовувати SSE або будь-який інший набір інструкцій SIMD для прискорення математики з плаваючою комою. Це може спричинити досить велику різницю швидкості між C ++ та C # для ігор. Якщо ви використовуєте моно, у них є спеціальні бібліотеки математики SIMD, якими ви можете скористатися.


Погодьтеся повністю. Реалізація збирачів сміття на "менших" платформах, здається, є повним сміттям.
Krisc

Хороший пост, проте, що стосується вашої заяви про "розподіл об'єктів купи" наперед ", я рекомендую прочитати " Правду про типи цінності "
Джастін

Чудовий момент, коли ви оптимізуєте код, його дійсно варто зрозуміти платформу, для якої намагаєтесь оптимізувати. Це насправді коментар про типи значень / типи посилань, будь-який довгоживучий об'єкт, швидше за все, не буде на стеку. Це справді про те, щоб переконатися, що ви отримаєте якомога більше своїх асигнувань на час завантаження, ви не потрапили в цей магічний бар'єр на 1 Мб під час гри. Усі реалізації .net, які спрямовуються на xna target aslo, мають чітку гарантію, об’єкти, виділені близько в часі, будуть близькими у просторі, що може бути приємно для perf.
Cubed2D

Крім того, схоже, я забув згадати, що поточний компактний фреймворк на xbox має алергію на вбудовані виклики методу. Зберігайте цей для ваших найгірших варіантів перф-сценаріїв, хоча використання ref версій математичних методів виглядає досить некрасиво, як це є!
Cubed2D

10

Типовий підводний показник продуктивності не враховує сміттєзбірника при розробці / розробці гри. Виробництво занадто багато сміття може призвести до "гикавки" в грі, які трапляються, коли GC працює протягом значного тривалого часу.

Для C # використання об'єктів цінності та оператор "using" можуть зменшити тиск з боку GC.


3
Крім того, ви можете сказати, що збирач сміття працює явно, якщо ви тільки що закінчили розподілити / безкоштовно важкий цикл або якщо виявите, що у вас є запасні цикли.
BarrettJ

16
usingТвердження не має нічого спільного зі збором сміття! Це для IDisposableоб'єктів - для вивільнення некерованих ресурсів (тобто тих, якими сміттєзбірник не займається ).
Ендрю Рассел

9

Я б сказав, що найбільшими проблемами, з якими я стикався при написанні ігор в C #, була відсутність гідних бібліотек. Більшість, що я знайшов, це або прямі порти, але неповні, або обгортки над бібліотекою C ++, які несуть сувору штрафну ефективність за марширування. (Я говорю спеціально про MOgre та Axiom для бібліотеки OGRE та BulletSharp для бібліотеки фізики Bullet)

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


Це хороший момент щодо керування C # та Java замість інтерпретації ... відредагував моє запитання, щоб зробити його більш точним :)
Michael Klement

2
Маршаллінг в цілому є вузьким місцем продуктивності, але він також допомагає бути обізнаним про видимі типи - типи, які можна відобразити безпосередньо в керованій пам'яті без істотного впливу на продуктивність. msdn.microsoft.com/en-us/library/75dwhxf7.aspx
Шон Едвардс


4

C # та Java не інтерпретуються. Вони компілюються в проміжний байт-код, який після JIT стає так само швидким, як і власний код (або достатньо близький, щоб бути незначним)

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

Крім цього, керовані мови справді набагато більше здатні обробляти таку ефективність, яку вимагають ігри, ніж їм належать заслуги. Добре написаний керований код набагато швидший, ніж погано написаний нативний код.


Так, спасибі за зауваження, вже виправлена ​​інтерпретована / керована річ;) Крім того, гарна точка з сітками, що плавають навколо сцени. Не думав про це, коли думав про проблеми з GC ...
Майкл Клемент

1
IDisposableдозволяє детерміновано очищати критичні та некеровані часом ресурси, але не впливає безпосередньо на доопрацювання та збирання сміття.
Сем Харвелл

4

Ні Java, ні C # не інтерпретуються. Вони обидва складаються в рідний машинний код.

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


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

4
Варто зауважити, що у .NET 4 збирач сміття підтримує збір тла для всіх трьох поколінь об’єктів. Це повинно ефективно мінімізувати ефективність збору сміття в іграх. Відповідне посилання: geekswithblogs.net/sdorman/archive/2008/11/07/…
Майк

Сміттєзбиральники розвиваються, і, як зазначив Майк Стробель, деякі вже знаходяться у виробництві, що майже усуває цю нерівність.
Сем Харвелл

2
Ні C #, ні Java не компілюються в рідний машинний код. C # компілює в MSIL і Java в байт-код. Збір сміття не дасть жодних "довгих" пауз, але може дати "гикавку".
Cloudanger

2

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

Індустрія ігор для розробників все ще дуже сильно пронизана C ++, оскільки більшість інструментів та трубопроводів, які використовуються для виштовхування великих або просто відшліфованих маленьких ігор, були написані на C ++, і наскільки я знаю ВСІ офіційні комплекти розробників ви можете отримати для XBox, PS3 та Wii випускається лише сумісність для C ++ (набором інструментів XBox в даний час може бути більше керовано, хтось більше знає?)

Якщо ви хочете зараз розробити ігри для консолей, ви майже отримаєте XNA та C # на XBox, а потім лише в бічній частині бібліотеки ігор під назвою XBox Live Indie Games. Деякі, хто виграє конкурси тощо, вибираються, щоб перенести свою гру на реальну аркаду XBox Live. За винятком цього плану створення гри для ПК.

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