Identificazione delle risorse in un motore di gioco?


12

Voglio identificare le mie risorse caricate, ma non so quale dovrei scegliere. Ci sono 2 opzioni:

  • Nome (stringa)

    • Questo è il più semplice e anche veloce con unordered_map (O (1)), ma molto più lento dell'uso dei numeri interi.
    • Facilmente comprensibile nel codice.
  • Interi

    • Più veloce.
    • Non sono comprensibili nel codice.

So che le stringhe non sono così sicure o veloci, ma è così male o conta solo come cattivo in un titolo AAA? Potrei creare enum, per usare numeri interi, ma se carico la scena, le risorse, ecc. Da un file in fase di runtime, non posso usare enum. C'è un modo per rendere leggibili questi numeri interi se vengono generati in fase di esecuzione?

So che questo problema ha alcune discussioni su Internet, ma non sono riuscito a scoprire quanto sia importante in quali casi.


10
Perché non un'implementazione di entrambi? La versione stringa si collega a un dizionario <string, int> che a sua volta chiama un dizionario <int, asset>. È possibile aggirare il livello basato su stringa nel codice, ma utilizzare il livello basato su stringa per l'interazione dell'utente.
Krythic,

2
Secondo il punto di @ Krythic. Se al tuo codice piacciono gli interi per la velocità, lascia che il tuo codice utilizzi gli interi. Se ai tuoi utenti piacciono le stringhe per leggibilità, lascia che gli utenti utilizzino le stringhe. I due possono coesistere abbastanza felicemente (e puoi compilare selettivamente la versione di stringa solo in build di sviluppo, se vuoi saltare l'overhead completamente in versione)
DMGregory

Risposte:


19

Puoi supportare entrambi.

Mentre è spesso più efficace in fase di esecuzione di attività di riferimento da parte di un numero intero o alcuni simili tasto fast-to-confrontare, è spesso più efficace in fase di progettazione a loro riferimento per nome, perché gli esseri umani sono molto meglio a lavorare con nomi come enemy_bullet_casing_soundquello 72910613.

Utilizzare una chiave intera per cercare direttamente le risorse e utilizzare questo numero intero nel codice ove possibile (dove è possibile inserire il valore effettivo dell'intero in una variabile e quindi lavorare più facilmente con esso). Fornire una mappatura dal nome a quella chiave intera (piuttosto che direttamente alla risorsa) e utilizzare tale mappatura ogni volta che si incontrano riferimenti denominati alle risorse per risolvere la chiave intera effettiva e trovare la risorsa.

L'uso della ricerca basata sul nome renderà molto più facile lavorare con i tuoi file di dati, e mappare il nome su una chiave più veloce preserverà tutti i vantaggi importanti di una chiave di tipo intero più veloce ovunque sia necessaria.


Il mio caso: voglio cambiare il materiale di un oggetto, quindi invio una richiesta con il nome del nuovo materiale. (stringa) Quindi nel sistema grafico è presente una ricerca in una mappa non ordinata <stringa, puntatore> e il puntatore del materiale dell'oggetto verrà sostituito dal nuovo puntatore. Quindi, nel mio caso, non devo convertirlo in un numero intero? (poiché lo converto in puntatore e nei frequenti algoritmi utilizzo puntatori, uso solo stringhe per le cose occasionali.)
Tudvari,

O dovrei usare ID interi anziché puntatori ovunque sia possibile? (Quindi non devo includere il file header del materiale es.) Ad esempio il componente renderer ora memorizza il puntatore del materiale usato, che può essere usato direttamente dal motore grafico, ma devo includere Material.h . Ma quando memorizzo solo numeri interi nel componente renderer, non devo includere Material.h, ma devo effettuare una ricerca basata su numeri interi nella matrice di puntatori. Penso che quest'ultimo sia migliore. È? Dovrei refactificare questo?
Tudvari,

1

Nel mio progetto uso stringhe con hash, che vengono trasformate, in fase di compilazione, in numeri univoci (desidero!). Quindi, quando ho bisogno di una risorsa, ad esempio una trama, chiamo semplicemente

MngTexture->get(hash("my_texture"))

E dal momento che sto creando un semplice framework di sistema di entità e ho bisogno di caricare i dati dei componenti dai file, ho creato un linguaggio semplice come json per archiviare i dati, ma è compilabile (trasformando parole e caratteri da cifre a numeri e da stringhe a valori con hash) . Quindi, ad esempio, se voglio collegare la trama con l'hash ID ("my_texture") a "ball.PNG" nel mio file di dati, avrò

|my_texture| = "ball.PNG"

Dove || è un operatore che dice al compilatore di eseguire l'hashing della parola all'interno.

Quindi, fondamentalmente, utilizzo stringhe che sono mappate su in al momento della compilazione (quindi non hanno alcun sovraccarico), sia nel codice effettivo che nei file che sono i flussi per il caricamento dei componenti. Per calcolare l'hash un tempo di compilazione, basta cercarlo su Google, è una semplice funzione di 5-10 righe di codice.

Ovviamente puoi caricare la stringa dai tuoi file e l'hash in fase di esecuzione, in questo caso non devi scrivere il dizionario da solo perché l'algoritmo lo farà per te (creando numeri interi dalle stringhe) e io pensare che l'hashing sia veloce almeno quanto la ricerca in una mappa, a causa della localizzazione della memoria (si sta semplicemente eseguendo il looping di una stringa che è lunga pochi byte).

Spero che questo possa aiutare.


0

L'identificazione dell'oggetto tramite stringhe non è ottimale, gli ints sono molto più efficienti. Per comodità, è possibile mantenere una tabella di stringhe (o dizionario) di stringhe in ints per aiutare in fase di progettazione e durante il debug.

Vorrei tuttavia sostenere che nel tuo codice di gioco principale fai riferimento agli oggetti solo tramite il loro ID intero (o un enum per leggibilità). In questo modo è più semplice suddividere la tabella delle stringhe come risorsa separata. Se il tuo codice di gioco principale non si basa su questa tabella di stringhe, puoi eliminarlo dal gioco rilasciato, risparmiando potenzialmente una notevole quantità di memoria, una considerazione importante se stai lavorando su un gioco per dispositivi mobili e vuoi mantenere dimensioni di download ridotte come possibile.

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.