Quali sono i pro e i contro dell'incorporazione di Lua in un gioco C ++?


37

Ho un libro di programmazione di giochi in C ++ e contiene una sezione Lua. Ho iniziato a leggere la sezione Lua, e sembra interessante, ma non riesco a determinare i pro e i contro dell'utilizzo di Lua nel mio gioco C ++. L'unico vantaggio che mi viene attualmente in mente è che puoi effettuare alcuni aggiornamenti di codifica, tramite Lua, senza dover ricompilare. A parte questo, non riesco a pensare a niente. Quindi quali sono i pro e i contro dell'aggiunta di Lua a un gioco C ++?

Gli esempi sarebbero apprezzati.




Concordo sul fatto che sia simile a quelle domande, ma ciò che conta qui è il "contro".
Jonathan Dickinson,

@JonathanDickinson le risposte non puntano in quella direzione però ... dichiarano sostanzialmente lo stesso della domanda collegata.
Bummzack,

Risposte:


33

L'unico vantaggio che mi viene attualmente in mente è che puoi effettuare alcuni aggiornamenti di codifica, tramite Lua, senza dover ricompilare.

Non scartare l'utilità di questo così facilmente. Non capirai mai quanto sarai produttivo fino a quando non toglierai la fase di ricompilazione.

Il "flusso" è un concetto psicologico abbastanza ben compreso quando si tratta di lavorare. Il flusso è quella sensazione che provi quando ti concentri su un'attività, quando analizzi e risolvi i problemi quasi senza pensare, ecc. Sei al massimo della tua produttività quando "fluisci".

I tempi di compilazione rovinano tutto. È difficile rimanere nel flusso se hai anche una compilazione di 10 secondi tra il test di qualcosa.

Quando stai sviluppando un gameplay, quello che hai di solito è un "circuito chiuso". Hai un'idea, codifichi un test per vedere se funziona e poi lo provi. Se non funziona, lo modifichi e riprova. Il tempo di "code-to-test" è molto importante per mantenere il flusso. Ottenere il più piccolo possibile è fondamentale.

Ciò che Lua (o qualsiasi linguaggio di scripting incorporato) ti consente di fare è testare le modifiche, non solo senza "compilare", ma vivere nel gioco . A seconda di come costruisci il tuo gioco, puoi eseguire un comando che riavvierà il gioco con nuovi script senza dover interrompere e ricaricare i dati e così via. Non solo non è necessario ricompilare, non è necessario rieseguire.

La possibilità di farlo, dato il supporto adeguato del motore, può aumentare notevolmente la produttività.


Un altro grande vantaggio dello scripting è la capacità di non preoccuparsene. Se hai trascorso molto tempo a scrivere C ++, rimarrai stupito da quanto tempo passi in minutae. Dove viene eliminata la memoria. Dove questo viene liberato. Anche se stai usando shared_ptrovunque, solo l'atto di digitare tutti quei nomi di tipi di variabili ti rallenta.

In un linguaggio di scripting tipicamente dinamico, non devi preoccuparti. Lo scoping è semplice. Le funzioni sono oggetti di prima classe; non è necessario creare manualmente funzioni. È così facile fare alcune cose.

Ora questo ha degli aspetti negativi, se non sei un programmatore disciplinato. È molto facile usare i globi in Lua (anche se ci sono modi per impedirlo). Non preoccuparti significa che puoi essere molto sciatto quando scrivi il codice.

Ma ancora una volta, essere molto sciatto può avere dei vantaggi .


Un altro aspetto positivo di Lua è che rende un bel linguaggio di descrizione dei dati. Proprio come JSON è solo un file JavaScript che genera e restituisce un array / tabella, è possibile creare script Lua che restituiscono tabelle.

Questo è utile per i file di configurazione; Il formato tabella di Lua è molto meglio dei formati .ini. Il formato è ancora piuttosto pulito, compatto ed estensibile.

Oh, ed è ancora uno script di Lua, quindi può eseguire la logica effettiva. L'aspetto negativo di questo è ... beh, è ​​uno script Lua, quindi può eseguire la logica effettiva . Questo potrebbe essere disastroso nel gioco, dal momento che l'utente potrebbe potenzialmente iniziare a rovinare tutto.

Ma in realtà, questo è facilmente risolto. Lua è progettato per essere incorporato, il che significa che l'isolamento è in realtà abbastanza semplice. In effetti, un nuovo stato Lua non fornisce nulla per impostazione predefinita; devi effettivamente fare qualcosa per esporre anche la più semplice delle librerie Lua standard. L'accesso ai file, l'accesso allo stato di gioco, ecc. È tutto opt-in, non opt-out. E ogni stato di Lua è separato l'uno dall'altro. Lo stato Lua che usi per gli script AI non deve essere lo stato Lua che usi per i file di configurazione.

In realtà ho del codice che ti permette di registrare molte librerie standard Lua, ma passa attraverso e rimuove tutti i file IO. In definitiva, il peggio che un file di configurazione basato su script Lua potrebbe fare è causare il crash del gioco immediatamente dopo averlo eseguito, esaurendolo nella memoria. E dal momento che non stai condividendo questi file di configurazione manualmente, non sarebbe molto divertente per un hacker.


Direi che il più grande svantaggio di qualsiasi linguaggio di scripting è il debug. La maggior parte dei linguaggi di scripting non ha debugger e Lua non è diversa. Lua ha tutti gli strumenti necessari per creare strumenti di debug. Ma in realtà non ha un debugger integrato. Devi metterne uno insieme. E ciò richiederà un ragionevole grado di lavoro.

Oppure puoi farlo con "debug printf". Dipende davvero da quanto codice Lua scrivi.


1
lo scorrimento non è sempre una buona cosa; fare le cose automaticamente a volte significa non perdere tempo a camminare sulle alternative di progettazione.
Lurscher,

10
@lurscher: il design è ciò che fai prima di sederti al codice. Avresti dovuto elaborare tutte quelle alternative di progettazione prima di iniziare a scrivere, testare e eseguire il debug del codice.
Nicol Bolas,

23

Dove lavoro:

Professionisti:

  • miglioramenti del tempo di iterazione . Il nostro gioco è impostato per eseguire il polling di un file system host per le modifiche e "sgobbare" automaticamente nelle modifiche. (Hanno effetto solo alla prossima apertura del file, ma in pratica è un grande miglioramento: ricaricare il livello e le tue nuove modifiche lua entrano immediatamente.)
  • integrazione console . Qualsiasi funzionalità di debug può essere agganciata a una tradizionale console in stile Quake con un REPL. Per build interne possiamo persino collegare un lua REPL a un semplice socket che parla telnet e abbiamo il controllo della rete sul nostro gioco.
  • api ridotta e curva di apprendimento inferiore . Artisti e designer non tecnici possono partecipare ad alcune attività che sarebbero tipicamente strozzate al programmatore.
  • analisi di codice statico specializzato . È facile analizzare l'output luac -le sbirciare il bytecode per fare qualche analisi; è anche abbastanza facile analizzare la maggior parte dei file sorgente lua, specialmente se si dispone di una convenzione di codifica. Possiamo far rispettare le convenzioni locali. Puoi anche cercare metalua per avere ancora più potere qui.
  • gestione degli errori . Se la nostra API è priva di crash, anche se lua fa qualcosa di stupido, possiamo prenderlo e recuperarlo usando lua_pcall.
  • facile estensione API . Scrivere una nuova funzione per l'API C ++ Lua <-> non è troppo difficile. Ci sono anche pacchetti che aiuteranno ad automatizzare questo.
  • fonte semplice . Apportare modifiche, ad esempio per evitare la matematica in virgola mobile nell'interprete lua (importante su alcune piattaforme integrate) o per ottimizzare per sistemi particolari, non è troppo difficile!
  • metatables . Sono fantastici. Tanto potenziale per fare cose interessanti in fase di esecuzione. Abbiamo "tabelle virtuali" che in realtà non hanno contenuti ed eseguono una ricerca in una complessa struttura di dati sul lato C ++ dei nostri giochi.
  • coroutine . Essere in grado di interrompere e riprendere ad esempio gli script comportamentali AI è sorprendente. Ci vuole un po 'più di buon senso da parte dello Lua Scripter - stiamo ancora lavorando su come renderlo più "sicuro" con il nostro motore.

Contro:

  • GC imprevedibile . Ottimizzare ciò che il nostro stepdovrebbe essere cambia drasticamente a partita. Alcuni funzionano meglio con GC completo per ogni frame (piccolo set di lavoro). Alcuni funzionano meglio con passaggi molto più piccoli più raramente. Nota che c'è molto lavoro per migliorare il GC nelle versioni lua più recenti e in alcune patch (che non dovresti avere paura di usare!)
  • spese generali più elevate . Manteniamo molte delle nostre grandi strutture dati dal lato C per evitare sovraccarico di memoria per ogni voce di tabella. C ++, C e assembly generalmente producono codice più veloce. Quindi è limitato al 90% del motore di gioco che non è critico per le prestazioni e occasionalmente migriamo le cose da lua a C (o viceversa).
  • frammentazione . Forse il problema più grande su piccoli sistemi di memoria. Usiamo solitamente piccoli pool di oggetti e un heap di oggetti grandi completamente separato per lua. Abbiamo inserito passaggi GC completi in punti strategici nel gioco. Scarichiamo script o buttiamo via il lua_Statetutto in alcuni casi. E a volte abbiamo ancora problemi. Ottimizzare le dimensioni dei piccoli pool di oggetti (sono fissi, per semplicità e costi generali inferiori) e le dimensioni dell'heap di oggetti di grandi dimensioni specifico per lua possono essere una seccatura. Ma su sistemi più grandi di circa 4 MB, non ci siamo ancora preoccupati degli heap e dei pool specializzati.
  • mancanza di sicurezza del tipo . Se non si dispone di un buon set di strumenti per l'analisi del codice statico, si dovrà ricorrere a un sacco di controllo degli errori di runtime (forse usando __indexe __newindex). È meglio se riesci a rilevare gli errori in fase di compilazione. Ci sono varie cose che puoi fare per alleviare questo.

Lua è altamente raccomandata, sii disposto a lavorarci un po '! Potresti anche voler dare un'occhiata a Squirrel , anche se credo che abbia una base utenti più piccola.


Vorrei poterlo votare più volte. Molto completo, molto approfondito, chiaramente strutturato. +1
Koarl

5

In realtà ci sono 3 grandi vantaggi:

Questi fattori ti consentono come sviluppatore di giochi di abilitare funzionalità che accelereranno lo sviluppo e aumenteranno la qualità del tuo gioco.

Per esempio:

  • Sarai in grado di modificare le logiche di gioco semplicemente aggiornando il gioco da un file o da un socket di rete.
  • Puoi consentire agli utenti di creare i propri script (per robot o mod)
  • I progettisti e gli artisti del gioco saranno in grado di aggiornare e testare parti del gioco senza dover utilizzare il set di strumenti di compilazione.
  • Non dovrai ricompilare ogni volta che cambi qualche script.
  • Non dovrai riscrivere l'intero gioco se cambi piattaforme / motori / lingue.

1
"Non dovrai riscrivere l'intero gioco se cambi piattaforme / motori / lingue." A meno che non passi da Lua a un'altra lingua. E se stai scrivendo il tuo "intero gioco" in Lua, se cambi motore, allora quel cambiamento deve essere esposto a Lua (o hai bisogno di qualche astrazione tra Lua e il motore per nascondere i dettagli). Quindi non vedo come Lua aiuti in questi casi.
Nicol Bolas,

3

Dalla mia esperienza, un po 'ridotta.

Professionisti

  • L'integrazione iniziale è davvero semplice. Esistono strumenti per aiutare a generare associazioni, ma il meccanismo di associazione è così semplice che puoi scriverne la tua versione, con le tue caratteristiche personalizzate, in pochissimo tempo
  • Ottieni iterazioni molto più veloci sulla logica di gioco (supponendo che implementi la ricarica in runtime)
  • Avrai un ambiente liberatorio in cui sperimentare: proverai più cose perché il sovraccarico per farlo diminuisce in modo significativo
  • Sintassi familiare: nonostante tutte le sue differenze, ti sentiresti difficile come programmatore C per non sentirti a tuo agio in poche ore
  • Migliore separazione della logica di gioco dal "motore": il tuo motore diventa un fornitore di servizi che deve esporre un'API decente al client Lua. La barriera linguistica ti fa riflettere di più, invece di limitarti a entrare e armeggiare una variabile membro

Contro

  • La gestione della memoria Lua non è l'ideale per i giochi. Ce la fai, non ti piace
  • Il debug di Lua è orribile. Dovrai lavorare per migliorare l'esperienza
  • Conservare i dati in Lua significa che dovrai eseguire il debug in Lua: ispezionarli da C sarà inizialmente complicato
  • Lua ha una buona quantità di spari nella sintassi del piede, come per impostazione predefinita tutte le variabili sono globali
  • Lua è un linguaggio di programmazione, proprio come qualsiasi altro. Non aspettarti che i non programmatori si trasformino magicamente in programmatori solo perché hai rimosso il compilatore
  • Essere bravi a integrare e supportare Lua è un grosso lavoro. Non aspettarti che faccia le fusa fin dall'inizio. È lecito ritenere che dovrai effettivamente ammortizzare questo costo in alcuni giochi

Verdetto finale, personale: se stai costruendo un gioco di dimensioni decenti e non hai già un linguaggio di scripting, prendi Lua. Ne varrà la pena.


1

La mod di Garry è un esempio di gioco che utilizza Lua e C ++. Usano Lua per tutte le mod, il che le rende molto più facili da realizzare per le persone. C ++ è usato per tutti gli interni. L'unica cosa che mi viene in mente sarebbe il fatto che Lua non è veloce come C ++.

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.