Qual è un livello appropriato di granularità per l'architettura basata su componenti?


26

Sto lavorando a un gioco con un'architettura basata su componenti. An Entitypossiede una serie di Componentistanze, ognuna delle quali ha una serie di Slotistanze con cui archiviare, inviare e ricevere valori. Funzioni di fabbrica come Playerproduzione di entità con i componenti richiesti e connessioni slot.

Sto cercando di determinare il miglior livello di granularità per i componenti. Ad esempio, in questo momento Position, Velocitye Accelerationsono tutti componenti separati, collegati in serie. Velocitye Accelerationpotrebbe essere facilmente riscritta in un'uniforme Deltacomponente, o Position, Velocitye Accelerationpotrebbero essere combinati insieme componenti come Frictione Gravityin un monolitico Physicscomponente.

Un componente dovrebbe avere la minima responsabilità possibile (a scapito di molte interconnessioni) o i componenti correlati dovrebbero essere combinati in elementi monolitici (a scapito della flessibilità)? Mi sto sporgendo verso il primo, ma potrei usare una seconda opinione.



Utilizzerai il tuo motore fisico o ne integrerai uno esistente?
Den,

@Den: sto scrivendo un codice di fisica , ma non è affatto un motore . Semplice cinematica 2D.
Jon Purdy,

Risposte:


14

C'è una linea tra la granularità completa, che non porta allo spreco di codice o allo stato simile a un BLOB (motivo per cui le architetture dei componenti sono preferite) e all'usabilità.

Ovviamente le cose possono avere un Position, ma non sono necessariamente dinamiche (quindi perché hanno Velocitye Acceleration?). Tuttavia, qualcosa con Velocitya sarà un oggetto in movimento, quindi ha senso anche Accelerationraggrupparsi.

Avete intenzione di avere un caso in cui v e una sta per essere necessario, ma non si vuole una simulazione fisica per loro? Allo stesso modo, ci sarà un punto Gravityse non sono oggetti di fisica?

tl; dr Raggruppa ciò che ha senso.


1
Sembra corretto. Il mio sistema ha pochissima centralizzazione: se un Entityha Positionalcuni componenti che lo rendono Positionpartecipe della fisica, allora Entityè di fatto fisico. Penso che ciò che posso fare è solo aggiungere alcuni componenti per il raggruppamento logico e mantenere tutti i componenti fondamentali ad una sola responsabilità. Così l'aggiunta di, diciamo, una Movablead una Entityavrebbe lo stesso effetto di aggiunta di una Position, Velocitye Acceleration.
Jon Purdy,

6

Per evitare di microgestire ogni singola variabile che suggerirei iniziando pesantemente, scegliere le divisioni attorno alla responsabilità e al rifattore quando la situazione si presenta logicamente. Puoi iniziare i primi disegni su carta. Ad un certo punto queste divisioni di responsabilità grossolane diventeranno i mattoni delle tue entità.

Quindi per un esempio affrettato hai Game. Il gioco si divide in Environment + State. L'ambiente si divide in StaticWorld + MovingStuff. Lo stato si divide in AIControlled + PlayerControlled. L'idea grossolana di danno si divide in TakesDamage + GivesDamage.

E così via.

Proprio come il consiglio comune di "Costruisci giochi, non motori!" per i nuovi praticanti raccomando "Costruisci giochi, non sistemi di elaborazione elaborati!" perché solo con l'esperienza personale di un gioco in esecuzione saprai se è richiesto un elaborato sistema di componenti nelle opere future.


Non sono un nuovo sviluppatore. Se avessi componenti basati su concetti piuttosto che sul comportamento (cioè dall'alto verso il basso contro dal basso verso l'alto), la mia architettura non sarebbe più fragile e più elaborata? Posso implementare qualsiasi comportamento che desidero da piccoli componenti, ma non riesco sempre a ottenere il comportamento desiderato da quelli precombinati. Per non parlare del fatto che non posso prevedere tutto quello che vorrò ottenere anche nel contesto di un gioco.
Jon Purdy,

Lo svantaggio dal basso verso l'alto è che le comunicazioni tra i componenti diventano un problema e le persone tendono a iniziare in modo troppo micro sulla scala di ciò che stanno modellando. Stavo principalmente cercando di allontanarmi dal super-micro "xyz è un componente" "la rotazione è un componente" "rgb è un componente" livello per qualcuno inesperto.
Patrick Hughes,

Giusto. Volevo solo assicurarmi di averti capito correttamente. Con il sistema di slot che ho, è semplice ed efficiente comunicare i componenti, quindi non vedo alcun inconveniente sulla scala "super-micro". Non intendo trasformare questo in un motore autonomo, ma se lo faccio, posso sempre introdurre astrazioni come i gruppi di componenti che menziono nel mio commento sulla risposta di The Communist Duck.
Jon Purdy,

4

La mia ipotesi sarebbe quella di combinare componenti che avranno molta interazione. Nel tuo caso, manterrei la posizione in un singolo componente e la velocità e l'accelerazione sarebbero tenute insieme in un componente fisico.

Ma dipende molto dalle caratteristiche del tuo gioco (a meno che tu non stia costruendo un framework senza un gioco specifico in mente).


2
Il problema con la combinazione di componenti con molta interazione è che a volte l'altra parte non è necessaria.
Il comunista Duck il

4

Mi rendo conto che questa è una vecchia domanda, ma forse qualcuno troverà utile questa risposta.

Credo che Systemsti aiuterà meglio a capire come costruire componenti. Esistono sistemi nelle architetture in cui i componenti non contengono la propria logica, a parte semplici getter / setter e funzioni di supporto. I sistemi operano su entità che soddisfano i requisiti dei componenti. Questo è il motivo per cui è meglio separare i dati dei componenti tanto quanto ha senso che tali dati vengano elaborati senza gli altri dati.

Ad esempio, potresti avere una MovementSystemche aggiorna le sue Entità in Positionbase alla loro Velocity. Questo potrebbe essere per entità semplici nel gioco. Ma, per il giocatore e i nemici, potresti volere il movimento che ha in Accelerationcui viene elaborato AcceleratedMovementSystem. Ma per gli ostacoli potresti desiderare Friction. Il terreno potrebbe anche avere attrito, ma non avrà una componente di velocità. Ma che dire Gravity? Aggiungilo Player, Enemy e Obstacle e crealo GravitySystemper elaborarlo.

La linea di fondo è che più disaccoppiati vostro Componentssono, più estendibile l' Entitiessarà quando si utilizza Systems.

Modifica: ultima dichiarazione resa più chiara.

Modifica: Ok, ho lavorato sul mio sistema e sono arrivato a questa realizzazione. Un esempio di suddivisione di Posizione e Velocità è che la manipolazione della Velocità fa sì che la Posizione cambi con un Sistema di movimento. Di conseguenza, un "InputMovementSystem" non ha bisogno di una posizione per far muovere il giocatore dall'input dell'utente poiché il MovementSystem rileverà le modifiche in Velocity da applicare alla posizione. Certo, funzionerebbe comunque bene per metterli insieme, ma questo è un esempio del motivo per cui non è necessario.


Di recente ho letto un post sul blog che diceva qualcosa del genere:

"Se disponi di dati che possono essere raggruppati con 2 diversi componenti, è meglio creare un terzo componente con tali dati."

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.