Modo elegante per simulare grandi quantità di entità all'interno di un mondo di gioco


33

Supponiamo di avere un gioco in cui ci sono molte (molte molte) entità che svolgono alcune funzioni, non tutte sono costantemente necessarie o devono essere considerate in ogni frame. Il problema concreto a cui sto lavorando in cui è presente questo problema è una simulazione dettagliata di un corpo compresi i suoi organi.

Nel gioco ogni creatura ha il suo corpo che è separato in parti più piccole (busto, gambe, ecc.) Ea volte queste parti contengono organi, che svolgono una funzione specifica all'interno del corpo. Se un organo attualmente serve uno scopo o è attivo non è mai realmente chiaro. Dopotutto, un animale potrebbe avere lo stomaco vuoto che quindi non ha bisogno di digerire nulla. Sarebbe abbastanza ridicolo controllare o simulare ogni oggetto in ogni frame e molto costoso non appena avrai molte creature nel mondo. Quindi stavo pensando a un modo per distinguere in modo intelligente tra gli oggetti che devono essere aggiornati e quelli che non lo fanno.

Quello che ho trovato sembra una soluzione almeno ok. Crea una semplice coda / stack (essenziale che ogni elemento venga rimosso non appena viene letto; l'ordine è irrilevante) chiamato "stack di attenzione" dove risiedono gli oggetti che devono essere simulati. Gli oggetti che richiedono attenzione si metterebbero semplicemente nella pila o vi sarebbero posti da altri oggetti. Questi oggetti implementerebbero probabilmente una semplice interfaccia con una funzione simulate ().

Applicato al mio precedente esempio di digestione, ciò significherebbe:

Il giocatore sceglie qualcosa da mangiare (supponiamo che sia pane) dall'inventario e lo mette nella bocca del suo personaggio e la bocca viene messa nella pila dell'attenzione. Nel frame successivo la bocca viene presa dalla pila e viene chiamata la sua funzione simulate (). Dal momento che è una bocca, sarebbe ragionevole simulare la masticazione qui. Ciò potrebbe continuare per alcuni fotogrammi in cui la bocca continua a mettersi in pila fino a quando non decide che il cibo è pronto per essere ingerito. In questo caso la bocca mette il pane masticato nello stomaco (so che non ci va direttamente, ma l'esofago viene lasciato fuori per semplificazione), che viene poi messo sulla pila dell'attenzione. Nel frame successivo viene avviata la simulazione del processo di digestione. E così via per il resto degli organi necessari.

Un problema prevedibile con questo sono oggetti inattivi. Un animale addormentato ne è un buon esempio. Potrebbe essere fatto come precedentemente descritto tenendo l'animale che dorme in pila e controllando ogni volta se deve svegliarsi, ma sembra dispendioso poiché è l'unica cosa che viene fatta. Per rendere più efficienti gli oggetti inattivi, avevo in programma di aggiungere una sorta di programma che memorizza i lavori da eseguire in un momento specifico. Se un animale va a dormire metterebbe un lavoro in quel programma che dovrebbe essere programmato per un certo periodo di tempo dopo che l'animale è andato a dormire. Questo lavoro si occuperebbe quindi di mettere di nuovo l'animale che dorme sulla pila dell'attenzione. Ora, potresti dire che un animale addormentato che non si trova sulla catasta dell'attenzione potrebbe perdere l'attacco di qualcosa perché la sua IA non è simulata,

Ora, onestamente, non so se questo è anche vicino a una soluzione elegante a questo problema a causa della mancanza di esperienza. Sono vicino a qualcosa di utilizzabile? Come si fa di solito o qualcuno ha suggerimenti o soluzioni migliori?

Risposte:


10

Questo è esattamente il modo in cui abbiamo risolto questo problema a Stendhal . Nel nostro caso ci sono molte cose che accadono periodicamente, ma non tutte le svolte: incantesimi di cura, piante che crescono un po 'più in là, cadavere che degenera, oggetti sul terreno in scadenza.

Abbiamo un numero di turno che viene aumentato ad ogni turno. E manteniamo una mappa dei numeri di svolta futura che punta a una serie di oggetti che devono essere avvisati in quella svolta.


cosa succede se qualcos'altro interagisce con l'oggetto nel frattempo? Ad esempio l'animale che dorme potrebbe essere svegliato da una pietra che colpisce. Dovresti rimuovere il programma dell'animale in quel caso?
Emiliano,

Dipende dalla situazione: se l'azione compiuta è innocua (come svegliarsi mentre si è già svegli), lasciamo che accada. Ma se l'azione consuma delle risorse, cerchiamo nella coda in sospeso e la rimuoviamo.
Hendrik Brummermann,

14

Sembra un problema simile a quello degli input: hai più di 100 tasti sulla tastiera ma non vuoi controllare ogni singolo tasto su ogni fotogramma, quindi cosa fai?

Due risposte: polling o messaggi di sistema.

Polling = in qualsiasi momento in cui avrebbe davvero importanza nel gioco, interroga lo stato dei tasti della tastiera (o degli oggetti, nel tuo caso). Il resto del tempo, ignorali.

Messaggi = ogni tasto della tastiera (oggetto) inserisce qualcosa in una coda di messaggi quando viene premuto o rilasciato (quando ha bisogno di attenzione). Ad ogni iterazione del ciclo di gioco, guarda attraverso la coda e risolve tutti i messaggi prima di procedere.


10

Quindi farò un passo indietro rispetto all'implementazione e rivedrò la domanda dal punto di vista del design. Hai un piano solido per visualizzare tutti i dettagli che vuoi includere in questa simulazione?

Per esempio:

  • Il giocatore può dire la differenza tra un animale a stomaco vuoto e un animale con uno pieno?
  • Queste informazioni sono importanti per loro quando fanno delle scelte di interazione all'interno del gioco?
  • Un giocatore che osserva l'animale può prevedere costantemente il risultato dei tuoi eventi simulati o basterebbe un numero casuale?

Fondamentalmente la regola generale è quella di non rendere la simulazione più complicata dei suoi risultati. Alla fine della giornata se le uniche animazioni che hai per le pecore sono pascolare, dormire, scappare. Quindi non importa davvero quanti fattori vanno nella decisione su quale stato scegliere. Tutti i giocatori vedranno le pecore che dormono di notte, scappano dal pericolo e mangiano durante il giorno.

La simulazione comportamentale è molto divertente su cui lavorare, ma tieni sempre presente l'esperienza degli utenti finali.


Sì, il giocatore sarà in grado di dire la differenza e ci sono alcuni effetti che questo ha sul gameplay, ma al momento è più una "trovata" per divertimento. Un po 'come il sistema di ferite nella fortezza nana, che è anche molto dettagliato ma trascurabile. Ma come hai già detto, è molto divertente lavorare su e questo è il mio obiettivo principale in questo momento.
Marc Müller,

9

Ho avuto un problema simile in un gioco su cui ho lavorato qualche anno fa: la simulazione di oggetti era complessa e non poteva essere eseguita in dettaglio su tutti gli oggetti del mondo.

La soluzione era utilizzare il concetto LOD per la simulazione. Gli oggetti alla vista del giocatore eseguiranno la simulazione completa. Oggetti lontani dal giocatore eseguivano periodicamente una simulazione altamente semplificata. Quando gli oggetti apparivano alla vista del giocatore, passavano dal corso, l'aggiornamento periodico della simulazione a aggiornamenti dettagliati e regolari.


2

La soluzione con un programma è buona. Si noti che ogni entità dovrebbe avere un elenco di puntatori alle sue azioni future, che dà la possibilità di invalidare le azioni future, se necessario. Vale a dire. l'animale che dorme si sveglia all'istante quando viene attaccato, quindi devi invalidare la sua azione di sveglia in futuro.


1

C'è un modello di progettazione per questo. Penso che si chiami Oggetti Database?

Fondamentalmente, mantieni una pecora "modello" che può rappresentare tutte le pecore non speciali nel mondo di gioco, le disegni allo stesso modo, mantenendo i dati univoci all'interno dell'oggetto modello, diciamo come una tabella delle posizioni delle pecore e / o del tempo -Dal-taglio. Quindi, ogni volta che devi rendere unica una pecora, puoi creare un'istanza specifica per tracciare quella pecora unica.

Lo stesso vale per le animazioni. Se si tratta di un'animazione inattiva o di un evento comune a ogni istanza, che può risiedere nell'istanza del modello, in cui è possibile pianificare separatamente animazioni più specifiche.

Molto tempo fa, ho scritto un gioco per un contest di programmazione il cui loop principale si chiamava animate () sull'intera scena. Ha usato i puntatori a funzione per sostituire le animazioni inattive con altre, come richiesto, e ha usato la tecnica per supportare l'animazione ereditata (ad esempio girare un personaggio che si trova su un disco rotante).

È simile in natura all'utilizzo di un delegato per l'animazione.


3
Modello flyweight, vuoi dire?
topright

0

Una macchina a stati funzionerebbe? L'animale è ad esempio in stato di sonno, stato alimentare, stato di marcia, ecc. Ad ogni stato è associato un elenco di organi attivi. Quindi ogni fotogramma che visiti ad ogni animale, attiva lo stato, cerca l'elenco degli organi per quello stato ed esegue l'aggiornamento su ciascuno degli organi.


Penso che ciò complicherebbe le cose perché deve essere possibile che si verifichino più cose all'interno dell'animale. Ad esempio, solo perché lo stomaco sta digerendo qualcosa non significa che il cuore smette di battere o che l'animale smetta di camminare. Certo, potresti definire un insieme di stati, ognuno dei quali prende in considerazione determinate funzioni, ma la quantità di stati sarebbe follemente enorme.
Marc Müller,

Più cose possono accadere per stato, perché si memorizzano tutti gli organi attivi su uno stato ed eseguono ciascuno per ogni frame. Tuttavia, molto di ciò che accade nella simulazione sembra adattarsi alle transizioni di stato. Ad esempio, masticazione -> digestione. Ma credo che tu abbia ragione che un animale non può avere un solo stato. Ci sono transizioni di stato in atto, diciamo con gli arti che non sono in relazione con le transizioni di stato che avvengono nel sistema digestivo. Ma forse è solo più complicato di quello che hai. Ho pensato che potesse essere qualcosa da considerare.
Erik Engheim,
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.