Perché è dannoso codificare i contenuti?


41

So che la maggior parte dei giochi memorizza il testo dei dialoghi nei file, ma ho anche visto alcuni giochi basati su testo programmare effettivamente il contenuto (mappa, scelte, possibili comandi del giocatore, testo della trama) nel codice del gioco.

Mi vengono in mente alcuni motivi, ma qual è il motivo principale per cui anche i giochi di testo mantengono tutto in file al di fuori del programma?

I dettagli dell'implementazione differiscono poco tra il mantenimento del contenuto in qualcosa di simile al popolare formato XML, l'analisi, il rendering delle mappe / la visualizzazione di testo basato sulle variabili create dal file XML e la semplice rinuncia del tutto al file XML. Entrambi finiscono con stringhe che escono sullo schermo. La differenza non è solo notazione?

Alcuni giochi contengono persino la grafica (arte ASCII?) All'interno del codice. So che questo non è giusto e posso indovinare alcuni motivi per cui è male, ma non conosco nemmeno il motivo principale.

È molto popolare avere la maggior parte dei contenuti al di fuori del programma. Anche Dwarf Fortress non utilizza i caratteri ASCII effettivi, ma immagini di caratteri ASCII caricati in memoria.

Lo chiedo principalmente perché è un po 'un PITA creare, analizzare e lavorare con file XML. Sai ... rispetto alla pigra alternativa di rendere ogni dungeon (contenuto) unico la propria classe.


9
I giochi basati su testo codificano molto il contenuto, ma penso che sia solo a causa del tempo in cui sono stati sviluppati e delle cattive scelte di design. Lo stesso potrebbe valere per la fortezza nana. Personalmente ho preso tutti i miei giochi basati su testo e spostato il contenuto al di fuori della fonte e in un database. Mi ha reso la vita molto più semplice.
Glen Swan,

7
i18n sarebbe molto difficile da fare con il contenuto incorporato nella fonte.
visita il

5
Non sono sicuro che questo sia specifico per lo sviluppo del gioco. In futuro pensate di chiedere ai programmatori SE o StackOverflow.
MichaelHouse

13
just making every unique dungeon (content) its own class.Mi ha fatto venire i brividi. La separazione dei dati dalla logica è un principio così fondamentale per me che sono sorpreso che ci siano ancora sviluppatori che li violano.
Lilienthal,

4
Qualunque cosa tu decida, renditi conto che il contenuto hardcoding consente casi molto più speciali. Desideri che un determinato capo appaia solo tra mezzanotte e le 7:00 (tempo reale)? È molto più facile codificarlo che creare un modo generico per far apparire i mostri solo in determinati momenti.
user253751

Risposte:


85

Ci sono diverse ragioni per questo. Ne parlerò solo alcuni:

  1. Rende il tuo codice sorgente un casino. Se hai molte finestre di dialogo (alberi), gran parte della tua base di codice è solo testo che non ha nulla a che fare con il tuo codice di gioco reale.
  2. Dovresti ricompilare ogni volta che cambi tanto quanto un singolo personaggio.
  3. La finestra di dialogo stessa è difficile da navigare. Immagino che provare a implementare un intero albero di dialogo, figuriamoci diversi, completamente all'interno della tua fonte si tradurrà in un pasticcio nidificato di spaghetti e ifs nidificati switche così via. Il che risulta quindi in un codice soggetto a errori, difficile da leggere e più difficile da eseguire il debug.
  4. Se vuoi consentire alle persone di modificare o espandere il tuo gioco, è molto più facile se non hanno a che fare con il codice sorgente per cambiare qualcosa.
  5. Il punto sopra è ancora più importante se lavori in una squadra. Non vuoi che il tuo scrittore debba incasinare il codice solo per entrare in una finestra di dialogo.
  6. L'analisi di XML o altri formati di file standard è piuttosto semplice se si utilizzano librerie esistenti, quindi il costo per implementarlo in questo modo è molto basso, offrendo molti vantaggi ed evitando i problemi sopra menzionati e molto altro.
  7. Come sottolineato da @MiloPrice di seguito, è anche molto più facile localizzare il gioco se il testo è in file esterni. Puoi aggiungere una lingua aggiungendo un file, il tuo team può occuparsi della traduzione senza dover toccare la fonte (che è particolarmente importante se permetti alle persone di tradurre che non dovrebbero vedere tutto il tuo codice - pensa ai liberi professionisti, alle persone del comunità che non appartengono al tuo team, ecc.).

10
Non direi che renderebbe il tuo codice un casino. Altrimenti, contenuto o no, tutto può essere considerato un disastro alla rinfusa. Puoi strutturare i contenuti in una buona struttura proprio come il codice. Ma il resto dei punti è ancora forte.
Glen Swan,

28
La facilità di localizzazione / traduzione è un altro grande vantaggio.
Milo P,

2
@Christian: puoi avere un programma basato sui dati in cui i dati sono incorporati nel programma in un formato in cui sono direttamente utilizzabili sul posto (ad es. In C o C ++, grandi, si spera, constarray con durata di archiviazione statica). Ciò consente di risparmiare tutto il codice e il costo della memoria di runtime del caricamento / conversione di una rappresentazione di dati esterni in fase di runtime. Ovviamente si applicano tutti gli altri motivi per mantenere i dati esterni.
R ..

2
Personalmente preferisco un approccio ancora più forte per le stesse ragioni elencate qui: sposta anche la maggior parte del tuo codice in un linguaggio di scripting. Costruisci un core in C / C ++, incorpora un linguaggio come Python o Lua ed esporta un'API su di esso. Don't Starvesegue questo approccio ed è uno dei giochi più scritti che abbia mai visto. Numerosi altri giochi del passato e del presente lo fanno, così come le applicazioni (e raramente i programmi di utilità). Direi che nel complesso, al di fuori di piccoli progetti e piccole utility, la stratificazione pesante e la separazione sono sempre tuoi amici.
mechalynx,


30

Inserire i dati del contenuto del gioco nel codice significa che per vedere qualsiasi potenziale modifica o iterazione di tali dati del contenuto del gioco, è necessario ricompilare il gioco stesso. Questo è negativo per due motivi:

  • Molte lingue in cui sono scritti i giochi hanno tempi di compilazione lunghi. Il C ++ è particolare può essere molto negativo in questo senso, e il C ++ è un linguaggio molto comune per i grandi giochi commerciali. È meno un problema con linguaggi come C # e Java, ma non è ancora così veloce come essere in grado di memorizzare i dati di gioco in file esterni che possono essere ricaricati a caldo mentre il gioco è effettivamente in esecuzione per vedere le modifiche.

  • Molti giochi sono sviluppati da team che spesso consistono in sviluppatori non tecnici (designer e artisti) che producono contenuti. Non solo le persone non tecniche non vogliono dover ricompilare il gioco o gestire "ingombranti strumenti di programmazione" per iterare il loro contenuto, potrebbe essere desiderabile ridurre al minimo l'esposizione del codice sorgente solo ai programmatori (perché il minor numero di persone che avere accesso al codice sorgente, meno persone possono perdere - accidentalmente o no).

Penso che tu stia sopravvalutando la complessità del caricamento di dati da file di testo o XML. La maggior parte delle volte dovresti usare una libreria per farlo, il che rende il processo di analisi di XML / JSON / qualunque cosa molto più semplice. Sì, c'è un po 'di costo iniziale per scrivere un sistema di caricamento di livello basato sui dati, ma in genere ti farà risparmiare molto tempo a lungo termine rispetto a tonnellate di classi uniche per rappresentare ogni livello.

I giochi più piccoli o più semplici potrebbero non avere molto da guadagnare dall'investimento a lungo termine di un approccio basato sui dati, quindi a meno che gli sviluppatori non utilizzino framework / motori esistenti che lo supportano, potrebbe essere più efficiente per loro semplicemente codificare i dati in il codice di gioco.

Ci sono ovviamente una serie di ragioni per cui un determinato gioco può scegliere di mettere i propri dati in file esterni (o meno); non è possibile elencarli tutti. Ad un certo livello di solito si riducono tutti all'ulteriore velocità di iterazione o flessibilità che può fornire il non dover ricostruire il gioco.


Non penso che i tempi di compilazione siano davvero così importanti, ma come sviluppatore ci impegniamo sempre per "codice pulito" ... questa è una ragione abbastanza buona per separare le cose nel suo diritto ... il contenuto dovrebbe essere contenuto non codice!
Guerra,

4
I tempi di compilazione di @Wardy sono davvero importanti in C ++. Ho lavorato con soluzioni che hanno richiesto più di 15 minuti per essere costruite, sia per le dimensioni del progetto, sia per l'uso aggressivo di modelli o persino per la pigrizia degli sviluppatori (comprese le intestazioni non necessarie). E sono sicuro che questo è il caso di enormi giochi commerciali.
concept3d

1
@ concept3d: vorrei che il mio progetto fosse di 15 minuti. Una build pulita su un server di build dedicato richiede ~ 50 minuti.
Mooing Duck,

meno persone hanno accesso al codice sorgente, meno persone soffriranno di danni cerebrali causati dal C ++. : P
Sarge Borsch,

Penso che ad alcune persone manchi il punto di un hot-ricaricamento: a nessuno importa se ci vogliono 30 secondi per ricompilare il gioco, gli artisti non vogliono riavviare il gioco, vogliono una scorciatoia da tastiera, quindi possono provare diverse animazioni e trame al volo. In realtà questa è una delle cose che vogliono di più. Vedere l'aspetto delle cose al di fuori del gioco è una cosa, ma vederle nel gioco è ciò che conta.
Wolfdawn,

7

Come sempre, come sempre, dipende. Ma prima, vorrei sostenere che la codifica hard non è male da sola.

Ho alcuni contenuti codificati, in particolare il testo di una finestra di dialogo, in alcuni semplici giochi e il mondo non è finito. Noi programmatori adoriamo astrarre le cose, ma ricordiamo che ogni livello di astrazione che renderai renderà il tuo programma più complesso e più difficile da capire.

Se il tuo gioco è abbastanza semplice da permetterti di codificare alcuni contenuti, lo prenderei sicuramente in considerazione per semplicità.

Questo, tuttavia, non scala davvero troppo. Certamente il motivo più comune per mettere il contenuto in risorse esterne è semplificare il lavoro di squadra, in quanto una persona o una squadra possono concentrarsi sulla scrittura del gioco, mentre un'altra può concentrarsi sulla creazione e la lucidatura del contenuto.

Tuttavia, tracciare il confine tra programma e contenuto non è sempre davvero banale. Si potrebbe dire che le trame sono al 100% di contenuto; ma per quanto riguarda le trame generate proceduralmente? Il testo della finestra di dialogo potrebbe essere considerato contenuto al 100%; ma che dire quando cambia la finestra di dialogo a seconda delle tue azioni precedenti? Altri elementi che si potrebbero considerare parte del programma al 100%, come script o shader, potrebbero anche essere considerati parte del contenuto del gioco. Dovrebbero essere codificati? dovrebbero essere caricati come risorsa esterna?

Ricorda, tuttavia, che ogni tipo di contenuto supportato nel tuo gioco deve avere un codice di caricamento e interpretazione ad esso correlato, quindi in generale, in caso di dubbio, consiglierei un contenuto di codifica rigido e lo porterei a una risorsa esterna solo quando ho davvero bisogno di quella flessibilità (non quando pensi di potertene averne bisogno, ma quando effettivamente lo fai)

Infine, uno dei vantaggi dell'archiviazione dei dati nei file di risorse è che puoi caricarli solo quando ne hai bisogno (quindi velocizzando i tempi di caricamento del gioco) e scaricarli quando non ti servono più (consentendoti quindi di avere più contenuti di quello che può stare nella memoria). (Angolo di Nitpickers: le DLL delle risorse potrebbero essere probabilmente considerate risorse esterne)


7
"ma ricorda che ogni livello di astrazione che renderai renderà il tuo programma più complesso e più difficile da capire." Dovrei essere in disaccordo, l'astrazione può rendere un programma più semplice e certamente dovrebbe renderlo più facile da capire.
NPSF3000

1
@ NPSF3000 astrazioni saranno aggiungere complessità, ma in grado di rimuovere più di complessità si aggiunge.
user253751

2
@immibis, quindi la somma totale della complessità di un progetto dopo l'implementazione di un'astrazione dovrebbe essere inferiore rispetto a prima.
NPSF3000

3
@ NPSF3000: il mio punto è che non dovresti creare astrazioni solo perché puoi. A volte i dati di hardcoding sono più semplici, più comprensibili e più facili dappertutto. Il più delle volte, ho visto i giochi andare giù per il softcoding , che trovo deplorevole. Inoltre, tieni presente che l'aggiunta di astrazioni è sempre più semplice della loro rimozione, quindi sono fermamente a favore dell'aggiunta di astrazioni solo quando ne hai bisogno.
Panda Pajama,

@PandaPajama facendo qualcosa 'solo perché puoi' è probabile che causi un problema, indipendentemente da cosa sia quel qualcosa. Ciò non significa che qualcosa sia intrinsecamente complesso, il che era il mio punto di preoccupazione. Inoltre, cosa ti fa pensare che aggiungere astrazioni sia più facile che rimuoverle? Al di là della mia testa, la penserei diversamente: aggiungere tardi un'astrazione può significare un significativo refactoring, ma non riesco immediatamente a pensare a un caso in cui rimuovere un'astrazione non necessaria sarebbe complessa. Il passaggio da XML a stringhe codificate dovrebbe essere banale.
NPSF3000,

3

Un grande motivo per l'archiviazione in file di testo è la riusabilità. La creazione di un framework per giochi di testo che legge mappe, finestre di dialogo e altre risorse da un file di testo consente di riutilizzare il framework per altri giochi. Andando oltre i giochi di testo, ecco come grandi titoli di budget come Call of Duty rilasciano un nuovo gioco ogni anno.

Un altro motivo è la portabilità. Puoi utilizzare gli stessi file per Web, PC, Mac, Android, ecc. Tutto quello che devi fare è simulare il tuo framework per queste diverse piattaforme e la maggior parte dei dati di gioco non viene toccata.

Quando si va oltre i giochi basati su testo con script e dati archiviati nei file, i tempi di ricompilazione diminuiranno e si consentirà di creare un'interfaccia per manipolare i dati più facilmente.


1
Certo, avere la maggior parte delle cose riutilizzabili tende a costringerti a evitare di fare qualcosa di "speciale", al di fuori delle regole che hai già. Sicuramente non sto sostenendo i grandi giochi hardcoding, ma è estremamente utile quando si sta prototipando o scrivendo giochi sperimentali - ti dà molta più flessibilità. Viene fornito con un prezzo, ovviamente, quindi di solito è una buona idea rifattorizzare tutto una volta che il gameplay funziona davvero. Il gameplay è la parte difficile: assicurati di poterlo testare senza immergerti nell'inferno architettonico: D Di solito è più facile trovare la forma generale dopo averne i calcestruzzi.
Luaan,

3

Per rendere le modifiche più veloci, accelera lo sviluppo di grandi produzioni di tonnellate.

Non è necessario insegnare a tutti come imparare a modificare la fonte per apportare semplici modifiche. Trascinandolo dal codice reale, più persone hanno la possibilità di scherzare, è più facile scoprire con quali opzioni puoi giocare e l'intero processo di perfezionamento delle varie parti del tuo gioco richiede molto meno tempo. Anche le domande e risposte possono aiutarti.


3

Non riesco a credere che nessuno lo abbia ancora menzionato, ma una grande ragione è rendere la localizzazione MOLTO più semplice. Se hai bisogno di supportare inglese, francese, tedesco, spagnolo, portoghese, italiano, russo, cinese e qualunque altra lingua tu stia mirando, hardcoded richiede di avere code-behind separato per ogni lingua. Significa anche che se è necessario rimuovere determinati contenuti (leggi: censura), è necessario modificare il codice stesso per evitarlo, invece di dire "basta sostituire questo minigioco di sondaggio anale con questo banner passivo-aggressivo che spiega graficamente cosa sta succedendo ". È anche piuttosto ostile per i consumatori, poiché è probabile che dovranno riavviare il gioco per cambiare la lingua, poiché è necessario caricare altre librerie. Finalmente,

D'altra parte, se si utilizzano risorse esterne, supportare lingue diverse significa semplicemente caricare un file di risorse diverso. Questo può essere fatto facilmente mentre il gioco è in esecuzione. significa che puoi avere un unico codebase, semplificando enormemente lo sviluppo. Inoltre, puoi aggiungere facilmente il supporto post-rilascio per altre lingue. Infine, significa che puoi consentire all'utente di scegliere di non installare determinate lingue (una funzionalità che non si verifica molto spesso nei giochi, ma che è ancora possibile) per risparmiare spazio su disco e larghezza di banda.


3

Penso che una frase chiave sia la separazione delle preoccupazioni .

Se il tuo codice non include il testo, il codice diventa meno complesso. Il programmatore che scrive il codice non deve pensare al testo specifico e può concentrarsi sul codice.

Non deve pensare alla localizzazione. La persona che esegue la localizzazione non deve preoccuparsi del codice.


3

Penso che sia troppo facile essere il tipo "appassito del bianco" e consiglio caldamente di utilizzare un file di risorse di testo esterno.

Perché? Perché qui c'è una scelta che riguarda il bilanciamento dei costi / problemi / vantaggi di ogni soluzione.

Quando si utilizza un file esterno ... Beh, immagino che le altre risposte spieghino abbastanza bene i vantaggi. Ma per quanto riguarda i costi? Devi definire un formalismo valido, costruire un interprete, concordare un formato di file e, peggio ancora ... costruire un'altra applicazione -un editor-. Il che rappresenta un problema dello 0,00% se sei un membro di un team di 50 programmatori che sviluppa un grande progetto. Ma se sei solo: sei bloccato.

Ancora una volta, non sottovaluto gli enormi vantaggi di flessibilità di una risorsa esterna: la programmazione basata sui dati mi sembra la strada da percorrere per i videogiochi. Ma non dimentichiamo il costo.

D'altra parte, avere il testo all'interno del codice consente la prototipazione rapida, quindi dovrebbe essere preferito per la prima volta. Quindi il mio consiglio sarebbe, mentre il progetto matura, di analizzare il tipo di dati richiesti per modellare i dialoghi (stato d'animo / storia-stato / ...). Poi a un certo punto decidi di alcune classi / regole / formato di file e vai per la cosa reale, consentendo ad altre persone di modificare / disaccoppiare il codice dal contenuto e così via. OPPURE per un gioco con dialoghi semplici (Mario ...) consideri il costo troppo alto e mantieni codificate le poche stringhe / comportamenti.
La tua chiamata.

(Nota sulla localizzazione: è solo una tabella di hash, quindi è un problema indipendente e facilmente risolvibile.)


Alcune di queste cose sono ancora vere se si inserisce il testo nel codice. Hai ancora bisogno di un determinato formato, un modo per navigare nell'albero e così via. Tenendo presente ciò, qualsiasi costo aggiuntivo per l'implementazione di una fonte di contenuto esterna sembra relativamente basso, soprattutto perché esistono librerie ed editor maturi per l'analisi, la scrittura, la modifica e la creazione di questi file. A seconda della complessità delle tue finestre di dialogo, potresti persino scappare senza un editor specializzato e usare semplicemente un editor di testo standard.
Christian,

1
Certo: forse non ero abbastanza chiaro, volevo dire che solo dopo alcune iterazioni sai qual è la forma dei tuoi dialoghi (da una semplice linea retta a un albero complesso o una macchina a stati). Nei primi passi alcuni ifs (molto semplici) + qualche stringa hard coded sono ok imho. Quindi, quando puoi prevedere chiaramente le tue esigenze, fai una scelta, dopo aver valutato i costi / benefici di ogni soluzione.
GameAlchemist,

Una via di mezzo che sto usando nel mio attuale progetto di gioco one-man è di avere un contenuto hardcoded che viene generato da file analizzati prima del tempo di compilazione. In molti casi sarebbe la soluzione peggiore di entrambi i mondi, ma per quello di cui ho bisogno è in realtà piuttosto buona.
glenatron,

2

Immagino che anche le licenze possano essere un motivo per non includere contenuti nel codice.

Per esempio,

  • il tuo codice potrebbe essere FLOSS , ma non vuoi affatto concedere in licenza il tuo contenuto (forse vuoi pubblicare il tuo codice di gioco in modo che altri possano usarlo per creare giochi simili con contenuti diversi)
  • il tuo codice potrebbe essere FLOSS, ma desideri utilizzare una licenza Creative Commons per i tuoi contenuti (poiché le licenze software non funzionano perfettamente per i contenuti e viceversa)
  • il tuo codice potrebbe essere proprietario , ma stai riutilizzando contenuti gratuiti
  • il tuo codice potrebbe essere proprietario, ma desideri pubblicare i tuoi contenuti con una licenza gratuita / gratuita
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.