È ragionevole scrivere un motore di gioco in C? [chiuso]


53

Anche se C ++ sembra essere il re, da quello che mi è stato detto che C è ancora ampiamente usato nei giochi, specialmente nelle console. Tuttavia, scrivere un intero motore di gioco in C sarebbe irragionevole oggi? Quali sono, se del caso, alcuni vantaggi che C ha rispetto al C ++? Perché qualcuno dovrebbe voler usare C su C ++?


1
I giochi per console utilizzano c ++ FYI!
Alan Wolfe,

In realtà penso che C sarebbe più facile scrivere giochi fino a una certa scala, diciamo decine di migliaia di LOC o giù di lì, principalmente perché ti consente di concentrarti su bit e byte senza tipi di dati complessi e crea super veloce rispetto al C ++. Ma dopo una certa scala (diciamo raggiungendo centinaia di migliaia di LOC), vorrei iniziare a cercare C ++ dove inizierei a desiderare tipi di dati complessi, maggiore sicurezza dei tipi, possibilmente eccezioni, modelli e andare ancora più grande in scala (diciamo milioni), per cose diverse da C ++ da combinare con il codice C e C ++.

C ha anche l'ulteriore vantaggio di essere ampiamente portatile anche per ABI, quindi diventa abbastanza facile prendere il tuo codice C esistente e quindi iniziare a usarlo in altre lingue, ad esempio da un FFI. Il C ++ è un po 'più imbarazzante con la modifica del nome, l'incapacità di oltrepassare i limiti del modulo, le ripetizioni di vtable non sono le stesse tra i compilatori, le implementazioni di librerie standard differiscono tra i fornitori, ecc. Generalmente trovo che le librerie C che scrivo durino più a lungo senza bisogno di modifiche e andando fuori moda, anche se ci vuole più tempo per scrivere qualsiasi cosa di scala con esso.

Risposte:


49

Tuttavia, scrivere un intero motore di gioco in C sarebbe irragionevole oggi?

È ragionevole, ma la domanda è: cosa ti compra? Probabilmente non hai bisogno dell'estrema portabilità offerta da C, ed è un peccato rinunciare a tutte le funzionalità offerte da C ++ a meno che tu non sia davvero filosoficamente contrario.

Quali sono, se del caso, alcuni vantaggi che C ha rispetto al C ++?

Tempo di compilazione migliore?

Perché qualcuno dovrebbe voler usare C su C ++?

Penso che sia principalmente una scelta estetica. A molte persone piace C perché è semplice e minimale e si sente pulito. Il C ++ ha molte funzioni interessanti (vale la pena usare solo gli spazi dei nomi), ma è anche grande e disordinato.


3
Fino a Id Tech 4
ottico,

9
@Josh: più facile da eseguire il debug !? I programmi C sono notoriamente difficili da eseguire il debug, in gran parte a causa di puntatori e gestione della memoria. I programmi C ++ (quando si usano veri e propri idiomi di programmazione C ++, che tendono a evitare puntatori e gestione della memoria ogni volta che è possibile) sono diversi ordini di grandezza più facili da eseguire il debug.
BlueRaja - Danny Pflughoeft,

14
C può essere compreso dai semplici mortali. Il C ++ sembra avere molte funzionalità e i programmatori esperti di casi limite imparano anche dopo un decennio di usarlo ogni giorno per vivere.
Jari Komppa,

13
Il C ++ è un grande linguaggio, ma la sua temibile reputazione è diffusa soprattutto da persone che hanno appena letto storie dell'orrore e non hanno avuto il tempo di impararlo. C'è molto da imparare, ma in cambio ottieni molto valore. C ++ ti consente di esprimere molte cose che C semplicemente non può.
munifico

2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)e ora stai eseguendo il debug della memoria. Con C ++ non sai mai cosa verrà allocato quando, perché ci sono molti modi per allocare memoria (nuovi, malloc, costruttori di classi, ecc.)
YoYoYonnY

59

Ho lavorato a lungo con un motore di gioco pure-C che ha spedito diversi prodotti, quindi è assolutamente possibile. Ecco la mia esperienza personale con il lavoro su entrambi i motori C vs C ++:

  1. L'uso di strutture pure-C consente di sfruttare le conoscenze sull'allineamento delle strutture e quindi è possibile utilizzare queste informazioni per costruire i livelli di persistenza e serializzazione degli oggetti. Il motore con cui ho lavorato aveva alcuni semplici parser di intestazione che avrebbero creato automaticamente questi metadati sulle strutture e reso banali alcuni tipi di operazioni sui dati. L'analisi di file di intestazione C ++ arbitrari è essenzialmente impossibile e non appena si aggiungono l'ereditarietà e le funzioni virtuali si perde la capacità di sapere esattamente dove sono le cose in memoria
  2. Il tempo di compilazione è significativamente più breve perché è possibile mantenere i file di intestazione molto compatti e trarre vantaggio dalle dichiarazioni in avanti delle strutture.
  3. Il debug può essere migliorato perché senza l'uso di modelli ed ereditarietà è molto facile capire esattamente cosa sia un determinato oggetto e cosa stia facendo.

Tutti questi benefici potrebbero anche essere raggiunti con la stessa facilità usando un codice c ++ contenuto che si astiene dall'usare modelli ed ereditarietà su oggetti serializzati, ma è stata la decisione del CTO che sarebbe stato più semplice applicare la semplicità se gli elementi più confusi di C ++ non fossero a disposizione.

Personalmente penso che questo sia stato un po 'estremo, poiché mi mancava davvero la capacità di dichiarare in modo sano le variabili per i cicli e i molti usi completamente legittimi per l'eredità. Ma alla fine non ci è costato molta produttività


5
Non c'è davvero nulla che ti impedisca di implementare l'ereditarietà in C. E se usi C99 puoi dichiarare le variabili per i loop.
jsimmons,

15
Andare in disaccordo con il punto 3. È altrettanto facile scrivere codice disordinato e difficile da debug in C come in C ++. Un migliore debug non è qualcosa di inerente al linguaggio C.
Dan Olson,

7
Anche il codice pulito può essere più difficile da capire in C ++ - con sovraccarico, modelli, funzioni virtuali ed eccezioni, è molto più difficile vedere a colpo d'occhio esattamente quale sarà il flusso di controllo effettivo.
Kylotan,

6
@ Dan: Semplicemente avendo più roba, il C ++ è più difficile da eseguire il debug. Ovviamente puoi

Meno roba è in realtà il motivo per cui mi piace C. Ad esempio, in CI può semplicemente copiare bit e byte in giro con a memcpyper qualsiasi cosa perché il sistema di tipi non consente cose come copia ctors e dtors. Posso scrivere il codice sapendo che non dovrò eseguire il rollback degli effetti collaterali in quasi nessuna riga di codice dato che non posso uscire implicitamente da una funzione se non ne ritorno esplicitamente; non ci sono eccezioni gettate. Tutto ciò rende la scrittura di strutture di dati molto più semplice - in C ++ la semplice scrittura di una norma conforme vectorrichiede molto tempo, soprattutto se si desidera

18

Sto riscrivendo un motore di gioco 2D scritto in C ++ e Lua in C e Lua. Finora l'esperienza è stata abbastanza buona. Ovviamente fare operazioni vettoriali e matriciali non è così bello in C. Ma a parte questo, ho trovato l'esperienza abbastanza rinfrescante dopo aver trascorso oltre 10 anni come sviluppatore C ++.

C presenta numerosi vantaggi rispetto a C ++:

  1. Il compilatore si assicurerà che nessun codice venga eseguito al momento dell'inizializzazione statica. Ciò rende completamente sicuro l'allocazione statica di dati globali come stringhe utilizzate come chiavi, ad es
  2. Trasparenza. Nell'assegnazione C o nell'allocazione o nella definizione di una variabile non verranno eseguiti carichi di codice. C ++ genererà automaticamente i costruttori di copie per te, in modo da avere meno controllo su ciò che viene eseguito durante l'esecuzione dell'assegnazione.
  3. Un sacco di debug può essere più facile a causa della mancata modifica dei nomi delle funzioni
  4. Di solito va bene usare memcpy in C, ma facilmente causerà problemi in C ++, perché i costruttori di copie non verranno eseguiti. Dato che memcpy è molto più veloce di std :: copy che conta.

A parte questo ci sono una serie di vantaggi nell'entrare nel modo di pensare C. In C ++ mi trovo spesso a rendere le cose un po 'troppo generiche e astratte. In CI di solito ritagliano cose come i metodi get-set e spesso preallocano array di dimensioni fisse anziché utilizzare array dinamici. Spesso finisco con un codice di debug più breve e più facile in C. Le strutture dei dati sono generalmente più piatte e più facili da visualizzare in un debugger.

Ad essere sinceri, non farei mai un'app esclusivamente in C. Il motivo per cui funziona è che la combino con un linguaggio di livello superiore come Lua che può integrare molto bene C, se C non fosse così forte.

Software id scrive la maggior parte dei loro motori in CI credo, puoi guardare Return to castle Wolfenstein che è stato scritto in C.

Ho scritto della mia esperienza sulla scalabilità di C vs C ++ e degli aspetti negativi del vettore STL rispetto agli array semplici.


11
Cordiali saluti, in ogni caso che ho controllato (che è, credo, darwin gcc e vc2008), std :: copy compilerà semplicemente una chiamata a memcpy se entrambi i tipi sono POD.
BRaffle,

3
Inoltre, RE: STL vettore vs array semplici, perché non usare le belle parti del vettore e usare i normali puntatori C invece degli iteratori se non ti piacciono? Puoi semplicemente fare & myvector [N]. È come il migliore dei due mondi, supponendo che il tuo codice C esegua l'allocazione della memoria allo stesso modo. Oppure, per i loop, controlla BOOST_FOREACH. Lo rende ancora più semplice di C.
BRaffle,

1
Grazie per il suggerimento su std :: copy memcpy. Non lo sapevo. Quando Alexandrescu lo ha trattato alcuni anni fa, non era così. Informazioni sugli iteratori C ++. Riguarda principalmente la filosofia, cerco di programmare il modo in cui il C ++ doveva essere un programma sia per il bene delle persone con cui lavoro sia per trarre vantaggio dalle funzionalità del C ++. È stato principalmente fatto notare che alcuni miglioramenti del C ++ come i contenitori STL non sono sempre meglio che farlo nel vecchio modo C.
Erik Engheim,

7

Come ha sottolineato qualcun altro, C ++ porta il vantaggio di grandi spalle su cui puoi stare in piedi (BOOST, STL ecc.). Alla fine, è una scelta personale, ma sceglierei C ++ a causa delle risorse disponibili. Se ci sono funzionalità in C ++ che non desideri utilizzare, non utilizzarle.


1
Si noti che il 99% dei motori di gioco commerciali e interni si allontana da Boost e STL per vari motivi (garanzia di prestazioni, debugabilità, sicurezza dei thread, controllo).
Kaj,

42
E il 99% delle statistiche è composto.
BRaffle,

Sento che dovrebbe essere in qualche modo una regola citare tutte le statistiche.
Matt Jensen,

3

Non penso che nessuno usi C in questi giorni, di solito è mescolato con un linguaggio di livello superiore.

La programmazione in C ha alcuni vantaggi rispetto, per esempio, alla programmazione in C ++. Il C ++ può fare molte cose invisibili all'utente, il che può danneggiare le prestazioni se non stai attento. Il C ++ può anche essere terribile quando si tratta dell'utilizzo della cache, il che può compromettere le prestazioni.

Quindi potrebbe portare alcuni vantaggi a scrivere le parti critiche in termini di prestazioni di un gioco in modo simile al C, piuttosto che in un modo C ++ tradizionale. Non ho mai sentito parlare di nessuno, negli ultimi anni, in realtà scrivendo un intero gioco in C comunque.

Su alcune piattaforme, come l'iPhone, l'uso del C ++ può aumentare le dimensioni del tuo eseguibile con un certo numero di kilobyte (ho dimenticato quanto, scusa), motivo per cui alcuni sviluppatori di iPhone scelgono di scrivere il loro codice in un mix di C e Objective -C.


3

Ti darò un paio di ragioni in più per cui oggi sarebbe irragionevole scrivere un motore di gioco in C anziché C ++: STL e BOOST.

Non riesco a immaginare come varrebbe la pena scrivere ancora un'altra listimplementazione quando potresti fare affidamento su codice che funziona immediatamente (e che non devi scrivere!)


1
Qualche grande studio utilizza effettivamente boost? Anche l'utilizzo di STL è ancora in discussione, a causa della portabilità. Almeno per i motori console.
slicedlime

2
Personalmente, sto usando Boost.FunctionTypes per l'interazione c ++ / lua (vedi gamedev.net/reference/programming/features/CPPLuaExport/… ) e la libreria di numeri casuali Boost per la generazione uniforme di numeri casuali (per sistemi di particelle). Inoltre, Boost.Foreach è pulito. A proposito, chi se ne frega se i grandi studi non usano BOOST? Hanno la forza lavoro per scrivere da zero le loro librerie STL, no.
Loris,

1
Sì, ma capisci anche che ci sono librerie simili anche per C.
jsimmons,

2
Molte persone usano il boost nei giochi, credo. Ma è lungi dall'essere un requisito (o addirittura desiderabile) per molti di noi.
Dan Olson,

6
Le persone, ciò che credi è irrilevante: o lo sai o non lo sai .
o0 '.

3

Scrivere un motore di gioco in C è ragionevole. È veloce e può essere portato su più sistemi. Ad esempio, è possibile utilizzare per Android (con l'utilizzo di NDK). Potresti usarlo per l'iPhone (l'obiettivo c è solo un'estensione di c). Potresti anche usarlo per e del sistema operativo principale come Linux, Mac o Windows. Se ti senti a tuo agio con c, ti suggerisco di provarlo!


2

Certo che è ragionevole. Personalmente non lo farei, e la maggior parte dei fan di C che conosco in realtà scrive semplicemente codice simile a C in file .cpp. Ma le lingue sono abbastanza simili a dove non importa davvero.

Per quanto riguarda il motivo per cui qualcuno dovrebbe scegliere di farlo, penso che dipenda principalmente dalla filosofia anti-C ++. Personalmente non penso ancora che questo sia un buon motivo per scegliere C piuttosto che "C-style C ++". la pazzia di typedef struct è una ragione sufficiente per evitare C, e ce ne sono molte altre.

Sfortunatamente C e C ++ sono entrambi linguaggi piuttosto terribili quando arriviamo ad esso. Questo è uno dei motivi per cui le persone hanno cercato di scrivere molto del loro codice negli script negli ultimi anni.

Se stai cercando esempi di persone che lavorano in C, puoi ignorare l'id mentre ricordo di aver letto che hanno abbandonato C molto tempo fa. Cryptic Studios (Star Trek Online) fa tutto lo sviluppo del motore in C, però. Per quanto ne so, sì, è per la filosofia più che per qualsiasi vantaggio tangibile.


0

Sì e no. Sì, l'ho fatto qualche anno fa, ma avevo bisogno che il mio gioco funzionasse in 3D su un server remoto a 64 bit unix (non linux) con i giocatori su terminali stupidi. Non è stato banale. C può essere carino se vuoi integrare LUA ma alla fine ho fatto funzionare lua in C ++, quindi direi di sì, ma non farlo.


0

Una possibile buona risposta può essere "usa entrambi"?

Come ho sentito dire che i progetti di panda3d potevano essere ottimizzati, eliminando il collo di bottiglia usando un cython o ricodificando quelle parti.

Il più delle volte, le parti che devono essere ottimizzate sono la parte con molte iterazioni e annidamenti o con un sacco di calcolo numerico, quindi la mia ipotesi (selvaggia) è che un giusto compromesso sarebbe usare entrambi i linguaggi, usando C per le parti che includono molta programmazione a basso livello, quindi non puoi fare alcun uso improprio del linguaggio C ++ per la parte che richiede velocità e C ++ per il resto del gioco.

Idealmente fai la parte veloce del motore tenendo presente l'alto livello, e quindi usi un linguaggio di scripting o C ++ che userà molto meno nest / loop.

Ovviamente non potresti mai realizzare un motore del genere adatto a tutti i giochi che gli sviluppatori dovrebbero fare, tranne se dedichi il tuo motore a un tipo speciale di gioco ...

Ma non dare per scontato il mio consiglio dato che non sono uno sviluppatore di giochi esperto né uno sviluppatore esperto ... Penso che C ti costringa a scrivere codice veloce, mentre scrivo codice C ++ buono e veloce per un progetto grande come un gioco è una cosa diversa ...


0

C ha lavorato per John Carmack , potresti ottenere molti vantaggi usando C, ma fino a quando non ci arriverai per trarne vantaggio potrebbe volerci un po 'di tempo.

Qui puoi trovare un elenco di motori di gioco, alcuni dei quali sono scritti in C, forse puoi ottenere alcuni spunti su come fare un motore di gioco C attraverso il loro codice sorgente.


0

Il codice C è normalmente un codice C ++ valido.

I problemi principali con C ++ lo stanno usando in modo errato ( Linus Torvalds lo odia per questo motivo , ha avuto anche altri problemi con la portabilità della libreria e quindi compra sta lavorando a livello di sistema operativo e deve essere in grado di eseguire le cose su ogni casuale chip là fuori).

Ad esempio, non c'è quasi alcun vantaggio nell'usare un array cstyle [] su un c ++ std :: vector <> (o un contenitore simile).

I vettori sono dattiloscritti e possono essere controllati i limiti (è possibile accedere agli elementi utilizzando get () o [], anche se non si utilizza il metodo di verifica dell'array è comunque possibile eseguire una query sulle dimensioni anziché spostarle con il puntatore).

Ma i vettori possono essere più lenti se, ad esempio, non si dichiarano le dimensioni predefinite nel costruttore. Anche l'aggiunta di elementi a un vettore può causare rallentamenti se è necessario un ridimensionamento. C ++ 11 aggiunge anche molti vantaggi come l'inizializzazione uniforme (ora puoi dichiarare e inizializzare i vettori usando la stessa sintassi) e ci sono costruttori di spostamento che possono permetterti di evitare la copia. Puoi persino creare i tuoi inizializzatori personalizzati (se per qualche motivo volessi fare qualcosa di diverso dall'uso di malloc).

Oppure, se hai bisogno di ridimensionare le cose, allora i vettori sono ancora più facili da fare, non devi scherzare con malloc, copiare manualmente le cose e così via.

C ++ ti dà codice orientato agli oggetti. Una volta compilato sarà altrettanto efficace poiché è davvero solo un'astrazione per gli umani che lavorano con il codice. Sebbene cose come i costruttori possano rallentare la creazione di oggetti. Ma avrai bisogno del costruttore per impostare i valori predefiniti o altrimenti puoi inizializzare gli oggetti senza usare il costruttore (tralasciando il ()).

Ma l'orientamento agli oggetti rende la programmazione dei giochi molto più semplice. I giochi spesso hanno a che fare con oggetti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.