Perché posizionare la configurazione entità al di fuori degli script?


11

Ho visto molti giochi che definiscono i componenti di entità nei file di script, ma quando configurano ciascuna entità e specificano quali componenti ha, usano un altro formato di file (come XML). Perché lo fanno?

Chiedo principalmente di vedere quale fosse la logica degli altri per questo. Ho anche configurare il mio soggetti al di fuori di script (anche se ho scelto JSON non XML). Le mie ragioni per farlo sono di semplificare l'implementazione dei salvataggi e anche perché penso che questo tipo di configurazione sia meglio organizzato in qualcosa come XML o JSON.


@ Risposta di Christopher Larsen: Troppo lungo per pubblicare un commento come

Temo che potresti esserti discostato un po 'dall'argomento della domanda. I problemi che stai descrivendo sono più correlati alle entità basate sulla gerarchia; nota nella mia domanda che ho menzionato stavo parlando di entità basate su componenti.

Ecco un esempio di ciò che volevo chiedere. Di seguito sono due modi alternativi per configurare un'entità: tramite lo script e tramite un file JSON esterno. La mia domanda era: perché così tante persone preferiscono configurare l'entità al di fuori degli script?

Una classe di entità base:

class Entity:
    def __init__(self, name):
        pass
    def addComponent(self, comp):
        pass

L'approccio alla sceneggiatura:

orc = Entity('Orc')
orc.addComponent(PositionComponent(3.4, 7.9))

L'approccio JSON:

{
    "name" : "Orc",
    "components":
    {
        "PositionComponent": {
            "x" : 3.4,
            "y" : 7.9
        }
    }
}

Ho già dichiarato le mie ragioni per utilizzare questo approccio, che sono tecniche e organizzative. Volevo sapere perché così tanti altri (da quello che ho visto) usano questo.

Risposte:


13

Il principale vantaggio che mi viene in mente è che consente alla configurazione di essere modificata / gestita da un non programmatore senza richiedere che tocchino gli script di gioco.


Ciò può essere ottenuto semplicemente avendo due file (equivalenti di un .h e quindi un .cpp). Mi chiedo chi sarebbe una persona che vorrebbe creare un oggetto (oltre a dire questo non fare nulla sembra un vaso e quel fare nulla sembra un farfalle) che non vorrebbe aggiungere una logica ad esso (come se una persona coperta di polline dai fiori nel vaso, attira la farfalla). La lettura umana è ottima e uno dei miei pensieri sul perché è così, ma di nuovo mi sposto che JSON, le tabelle Lua e XML hanno tutti livelli simili di leggibilità umana da parte di non programmatori.
James,

2
Glest è un gioco modificato con xml. Molti non programmatori creano mod per questo. È sicuramente più accessibile avere xml / json rispetto allo script.
Sarà il

6

Un motivo per cui di solito utilizzo un file di configurazione anziché uno script per questo è:

L'unico modo per verificare la correttezza di uno script, ad esempio specificando tutti i valori e tale è eseguirlo.

Scrivere codice per consentire agli script di configurare i valori significa scrivere codice per creare oggetti scheletro in cui gli script possano riempire i valori e quindi convalidare che lo script abbia fatto così e così. È più codice e codice buggier rispetto al caricamento da un file di configurazione piatto, spesso utilizzando una libreria che supporta un qualche tipo di meccanismo di convalida.


5
Quando lo sviluppo del software tradizionale era migliore, questo era noto come il principio del minimo potere : oggi dobbiamo apprezzare i motivi per scegliere non la soluzione più potente ma la meno potente. La ragione di ciò è che meno potente è la lingua, più si può fare con i dati memorizzati in quella lingua.

1
@Joe Questo in realtà descrive abbastanza bene uno dei motivi per cui uso anche questo approccio. All'inizio ho provato a configurare le mie entità negli script, ma ho trovato difficile implementare i salvataggi (non riuscivo a tenere traccia delle relazioni tra i componenti). L'uso di un file di configurazione esterno mi aiuta molto.
Paul Manta,

Vedo questo come il contrario, se stai già utilizzando un'interfaccia di scripting, ora devi anche fornire un metodo di convalida dei dati per il file di configurazione invece di utilizzare l'interfaccia di scripting già definita per farlo per te.
James,

2

La configurazione dell'entità può essere semplicemente una serializzazione di un'entità specifica. Ciò ti consente di gestire l'output degli strumenti di modifica e modifica del gioco più o meno allo stesso modo di un salvataggio. In particolare, per i giochi in cui non è possibile prevedere in quale stato si troverà una determinata entità durante il salvataggio del gioco, ad esempio a causa della loro IA o perché sono parzialmente generati proceduralmente, è utile essere in grado di scaricare l'intero dati che definiscono ciò che un'entità "è" (al contrario di ciò che "fa") come flusso di byte da salvare.


1

Il modello che descrivi è un'implementazione di un sistema basato sui dati.

I sistemi basati sui dati sono comunemente utilizzati nello sviluppo di giochi in quanto consentono l'incapsulamento della definizione di contenuto esterno alla fonte. Questa rappresentazione esterna può quindi essere facilmente modificata (e persino aggiornata in tempo reale da un'applicazione che sta osservando la modifica) per cambiare il comportamento di un'entità.

Una volta definiti i dati esternamente, hai tutte le possibilità di come i designer interagiscono con essi, dalla modifica diretta dei file di testo (ugh!) A sofisticate interfacce utente che guidano le scelte del designer in una logica, coerente e persino verificata per la correttezza (da la prospettiva dell'equilibrio del gioco).

Se i dati fossero incorporati direttamente nel codice, qualsiasi modifica richiederebbe una ricostruzione dell'applicazione che per progetti di grandi dimensioni richiede moderatamente tempo, nonché il tempo necessario per la distribuzione dei file binari (ad esempio, i nuovi binari devono essere distribuiti e installati sul server).

Facciamo un esempio di un'entità sterotipica "l'orco" ...

Un modo di implementare per il nostro orco sarebbe quello di scrivere una descrizione completa nel codice di tutte le caratteristiche e la logica per l'orco.

  • maxhealth = 10
  • danno = 3 danni al secondo
  • Runaway = true
  • runawaywhen = health <10
  • aggressivo = true

Quando istanziamo gli orchi, tutti i loro valori vengono inizializzati esattamente allo stesso modo (o forse sono statici). Il problema che si pone è che alcuni designer verranno avanti e diranno "Abbiamo bisogno di un diverso tipo di orco per le aree per principianti, che ha meno salute, non scappa mai e non è aggressivo. Ciò consentirà ai nuovi giocatori di abituarsi a combattere senza maggiore difficoltà e confusione durante l'apprendimento del sistema di combattimento ".

Bene, ora hai bisogno di una classe diversa o (forse stavamo guardando al futuro) di regolare i valori che inseriamo nella "fabbrica" ​​che crea gli orchi quando li creiamo in un'area "principiante". Quindi apportiamo le modifiche, implementiamo nuovi binari. Solo per far tornare i playtester e dire che i nuovi valori di salute sono troppo bassi quando uccidiamo gli orchi in un colpo solo.

Se i nostri sistemi erano basati sui dati (e punti bonus per le applicazioni che supportano il ricaricamento quando vengono apportate modifiche), le modifiche necessarie per soddisfare il progettista e giocare con i tester sono semplici modifiche dei dati senza necessità di ricompilazione / distribuzione. Questo rende felici i progettisti perché non sono bloccati in attesa di modifiche al codice e rende felici i programmatori perché modifichiamo costantemente il codice sorgente per modificare i valori.

Portare i sistemi basati sui dati agli estremi consente di implementare qualsiasi cosa, dai livelli di gioco, agli incantesimi e persino alle missioni, mediante semplici modifiche ai dati che non richiedono alcuna modifica del codice. Alla fine, si tratta di semplificare la creazione, la modifica e l'iterazione del contenuto del gioco.


2
Gli script sono anche dati per la maggior parte delle definizioni
saranno il

1
-1. La domanda non riguarda i dati basati su hard-coding, ma gli script dinamici e le dichiarazioni statiche.

@Christopher Ho aggiunto una lunga risposta nel mio PO. Per favore controlla.
Paul Manta,

0

Nel tuo esempio stai già utilizzando due linguaggi di scripting. Questo è il modo in cui direi che alla lunga funziona meglio, ma suggerirei di unificare il linguaggio di scripting che stai usando. Se l'esempio di script che hai fornito è stato fatto in Lua, invece di Json, direi che usa le tabelle di Lua per costruire il tuo oggetto. La sintassi sarebbe effettivamente simile e ti permetterebbe di supportare un'interfaccia per esporre i tuoi componenti.

Toccare il motivo per cui le persone scelgono di farlo di solito in XML e quindi di scrivere in logica, è che questo ha senso quando lo dici. Ecco la mia definizione dell'oggetto nei dati, qual è un buon formato di archiviazione dei dati? È quasi sempre XML (anche se vado anche con JSON;). E poi quando vogliono aggiungere in logica, bene che sia codificato o inserito in un file di script.

Non è sbagliato pensare ma ai miei occhi le persone non stanno andando al passo successivo. Guarda qualsiasi linguaggio completo, c / c ++ / c # ,. Puoi definire gli oggetti e la loro logica tutti in una lingua, perché non fare lo stesso nella tua interfaccia di scripting ... È quasi come dire che dovremmo definire le nostre classi in XML e i nostri metodi in c # quando ci pensi. Forse i vecchi linguaggi di script di gioco non erano abbastanza potenti ed è ancora aggrappato al modo in cui è stato fatto.

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.