Quali insidie hai riscontrato durante la scrittura di giochi per PC con un linguaggio gestito come C # e come li hai risolti?
Quali insidie hai riscontrato durante la scrittura di giochi per PC con un linguaggio gestito come C # e come li hai risolti?
Risposte:
Non so molto su Java, quindi questo è dal punto di vista di uno sviluppatore .net.
Il più grande è di gran lunga la spazzatura. Il garbage collector .NET su Windows fa un lavoro fantastico e puoi scappare senza fare da baby-sitter per la maggior parte. Su Xbox / Windows Phone 7 è una questione diversa. Se si verificano bancarelle ogni pochi frame, la garbage collection potrebbe causare problemi. Al momento si attiva dopo ogni allocazione da 1 MB.
Ecco alcuni suggerimenti per gestire la spazzatura. Non dovresti preoccuparti della maggior parte di questi in realtà, ma potrebbero tornare utili un giorno.
GC.GetTotalMemory()
schermo. Questo ti dà un'approssimazione della quantità di byte allocati utilizzati dal tuo gioco. Se non si muove quasi, stai andando bene. Se sta salendo veloce, hai problemi.GC.Collect()
. Se sai che la maggior parte delle tue grandi allocazioni è fuori strada, è bello solo far sapere al sistema.GC.Collect()
tutti i frame. Potrebbe sembrare una buona idea, tenere d'occhio la tua spazzatura e tutto il resto, ma ricorda che l'unico con peggio di una raccolta di rifiuti è la raccolta di rifiuti.StringBuilder
(attenzione, StringBuilder
non è un proiettile magico e può comunque causare allocazioni!. Ciò significa che semplici operazioni come l'aggiunta di un numero alla fine di una stringa possono creare quantità sorprendenti di immondizia) o l'uso di foreach
loop su raccolte che utilizzano l' IEnumerable
interfaccia può anche creare immondizia senza che tu lo sappia (ad esempio, foreach (EffectPass pass in effect.CurrentTechnique.Passes)
è comune)IDisposable
su classi che contengono risorse non gestite. È possibile utilizzarli per ripulire la memoria che il GC non può liberare.L'altra cosa a cui pensare è la prestazione in virgola mobile. Sebbene .NET JITer esegua una discreta quantità di ottimizzazioni specifiche del processore, non può utilizzare SSE o altri set di istruzioni SIMD per accelerare la matematica in virgola mobile. Ciò può causare una notevole differenza di velocità tra C ++ e C # per i giochi. Se usi mono, hanno alcune speciali librerie matematiche SIMD che puoi sfruttare.
Una trappola per prestazioni tipiche non sta prendendo in considerazione il garbage collector nella progettazione / sviluppo del gioco. Produrre troppa spazzatura può portare a "singhiozzi" nel gioco, che si verificano quando il GC funziona per un tempo considerevole.
Per C #, l'utilizzo di oggetti valore e l'istruzione "using" possono alleviare la pressione dal GC.
using
dichiarazione non ha nulla a che fare con la raccolta dei rifiuti! È per gli IDisposable
oggetti, che servono per rilasciare risorse non gestite (ovvero: quelle che non sono gestite dal Garbage Collector ).
Direi che i maggiori problemi che ho riscontrato scrivendo giochi in C # è stata la mancanza di librerie decenti. La maggior parte che ho trovato sono porte dirette, ma incomplete, o wrapper su una libreria C ++ che comportano una pesante penalizzazione delle prestazioni per il marshalling. (Sto parlando specificamente di MOgre e Axiom per la libreria OGRE e BulletSharp per la libreria di fisica Bullet)
Le lingue gestite (distinte da quelle interpretate - né Java né C # sono in realtà più interpretate) possono essere altrettanto veloci delle lingue native se si ha una buona comprensione di ciò che le rende effettivamente lente (marshalling, garbage collection). Il vero problema, penso, è che gli sviluppatori di librerie non l'hanno ancora capito.
Come altri hanno già detto, le pause della raccolta GC sono il problema maggiore. L'uso di pool di oggetti è una soluzione tipica.
C # e Java non vengono interpretati. Sono compilati in un bytecode intermedio che, dopo JIT , diventa altrettanto veloce del codice nativo (o abbastanza vicino da essere insignificante)
La più grande trappola che ho riscontrato è nel liberare risorse che influenzano direttamente l'esperienza dell'utente. Questi linguaggi non supportano automaticamente la finalizzazione deterministica come fa C ++, che se non te lo aspetti può portare a cose come mesh che fluttuano sulla scena dopo aver pensato che fossero state distrutte. (C # realizza la finalizzazione deterministica tramite IDisposable , non sono sicuro di cosa faccia Java.)
A parte questo, le lingue gestite sono davvero molto più in grado di gestire il tipo di prestazioni richieste dai giochi di quanto non meritino credito. Il codice gestito ben scritto è molto più veloce del codice nativo mal scritto.
IDisposable
consente la pulizia deterministica di risorse time-critical e non gestite, ma non influisce direttamente sulla finalizzazione o sul garbage collector.
Né Java né C # vengono interpretati. Entrambi vengono compilati in codice macchina nativo.
Il problema più grande sia per loro che per i giochi è di dover programmare in modo tale che non si raccolgano mai durante la partita. Il numero di cerchi che devi saltare per raggiungere questo risultato supera di gran lunga i vantaggi di usarli in primo luogo. La maggior parte delle funzionalità che rendono divertente l'uso di quel linguaggio per la programmazione dell'applicazione o del server devono essere evitate per la programmazione del gioco, altrimenti durante il gioco si fanno lunghe pause durante il gioco e la raccolta dei rifiuti.
Una grande trappola che vedo nel creare giochi con linguaggi come questi (o usando strumenti come XNA, motore TorqueX, ecc.) È che sarà difficile trovare un team di brave persone con l'esperienza necessaria per creare un gioco equivalente a quello che sarebbe abbastanza facile trovare persone per C ++ e OpenGL / DirectX.
L'industria degli sviluppatori di giochi è ancora fortemente impregnata di C ++ poiché la maggior parte degli strumenti e delle pipeline che vengono utilizzati per estrarre piccoli giochi grandi o semplicemente ben rifiniti sono stati scritti in C ++, e per quanto ne so TUTTI i kit di sviluppo ufficiali che puoi ottenere per XBox, PS3 e Wii sono rilasciati solo con compatibilità per C ++ (il set di strumenti XBox può essere più gestito al giorno d'oggi, qualcuno ne sa di più?)
Se vuoi sviluppare giochi per console in questo momento ottieni praticamente XNA e C # su XBox e solo in una parte laterale della libreria di giochi chiamata XBox Live Indie Games. Alcuni che vincono concorsi, ecc. Vengono scelti per portare il loro gioco sul vero XBox Live Arcade. A parte quel piano sulla realizzazione di un gioco per PC.