Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # chi sono
- [contatti]
- ciao sono andrea, lavoro qui a 2hire come sviluppatore embedded e smontacose.
- Visto che chi non sa fare insegna, oggi voglio parlarvi di entity component system e perché penso sia veramente bello
- e perché non l'ho mai usato
- # survey
- vedo un po' di facce conosciute.
- quanti di voi sono programmatori puri?
- quanti sono programmatori per necessità di videogioco?
- quanti conoscono il pattern Entity Component system?
- quanti usano un engine per i propri lavori?
- # obiettivo
- perché chiedo questo?
- ecs è alla base di tantissimi prodotti in ambito videogiochi, e credo che conoscere un po' i meccanismi che fanno funzionare queste macchine, ci renda persone migliori e possa risolvere la fame nel mondo.
- Per chi prima ha detto di essere un programmatore puro, che non usa engine per i suoi giochi, e che non conosce ecs, spero di riuscirvi a mostrare qualcosa di nuovo.
- # antefatto [warning: fictonalization]
- 2 gamejam fà mi sono fatto convincere da Andrea a partecipare, a suon di parolacce
- insieme a sarah, bruno, tsuneo e massimo ci eravamo dati appuntamento al pub per condividere un po' di idee e decidere quale tecnologia avremmo usato
- io per l'occasione io avevo deciso finalmente di imparare love2d e ecs, ed ero molto deciso a condividerli con gli altri
- Fu una bella sessione di brainstorming, si buttarono giù molte idee e avevamo anche una bozza di un possibile gameplay (lo so, non si fa)
- # un problema [warning: informatica]
- Problema: vogliamo modellare un sistema dove molteplici agenti interagiscono fra di loro contemporaneamente, e con un certo grado di autonomia
- per esempio: in un videogioco abbiamo il personaggio di un giocatore, e dei nemici che si muovono a random
- # proposta 1
- ecco come avrei affrontato io il problema, un po' di tempo fa
- - è la mia prospettiva da programmatore che non vuole usare engine
- modelliamo una classe player, nel suo metodo update leggiamo gli input per muoverlo. modelliamo una classe npc, e nel suo metodo lo facciamo muovere a random
- # aggiunta
- se il giocatore tocca un nemico, perde
- # proposta 1.1
- nel loop del gioco facciamo if(player touches enemy) die()
- # aggiunta
- i nemici non si muovono a random, ma vanno verso il giocatore
- # proposta 1.2
- la classe npc riceve il giocatore, ad ogni update si muove verso la sua posizione
- ^ pessimo design
- # aggiunta
- quando il giocatore attiva la sua arma, i nemici dietro di lui esplodono
- # proposta 1.3
- nel loop del gioco mettiamo un if(x is pressed){for( e in enemies){if(e is behind player) die(e)}}
- # cosa abbiamo finora
- come potete immaginare questo è un design che diventa sempre più ingarbugliato, con logica sparsa un po' ovunque, oggetti che non si sa a chi appartengono, bug che compaiono in maniera imbarazzante.
- Quale è il problema? aggiungere un comportamento diventa sempre più difficile, i dati sono inutilmente ridondanti.
- questo design va bene quando abbiamo un solo giocatore, 2/3 nemici, ed un tutorial per qualche engine js/html5, ma possiamo allargare il nostro mondo solo spendendo molte bestemmie
- # il problema
- il problema di fondo del design di prima è che un comportamento (muoversi verso un obiettivo, esplodere) è mezzo mischiato con i dati su cui opera (la propria posizione, l'obiettivo, un evento) e questi piccoli pezzi di codice sono replicati un po' di volte.
- # ecs
- (non ho controllato wikipedia, garantito sto dicendo delle cazzate)
- ecs dice:
- il mondo è popolato da esseri, che si chiamano entità. essi hanno una identità e poco più.
- nel mondo ci stanno anche leggi, chiamate sistemi, che governano come le entità si evolvono da un istante di tempo all'altro.
- ad esempio: un sistema dice che se ho un obiettivo, devo "spostarmi verso di esso",
- un'altra dice che "spostarmi" significa modificare la mia "posizione" con un vettore,
- una terza dice che se c'è una esplosione vicino a me, allora vengo distrutto
- # ecs -cont
- i Sistemi interagiscono con le entità? No! ogni sistema interagisce con il suo tipo di dato, che è chiamato Componente.
- Dove stanno questi Componenti? ogni Entità è un contenitore di tutti i Componenti che ne devono determinare il comportamento
- In pratica cerchiamo di disaccoppiare completamente i dati dal codice, ed eliminiamo le dipendenze fra i vari pezzi di codice
- # esempio
- Modelliamo il nostro gioco con Entità{posizione, grafica, vita, input, nome="player"}, e tanti nemici modellati come Entità{posizione, obiettivo, grafica, nome="npc..."}
- dove posizione, grafica, vita, input, obiettivo sono i nostri Componenti
- poi creiamo un Sistema<posizione, input> che modifica la posizione a seconda dell'input, per permettere all'utente di controllare Qualcosa
- un Sistema<posizione, obiettivo> che avvicina la posizione all'obiettivo, per far muovere Qualcosa
- questi sono sistemi semplici, delle funzioni, che fanno evolvere le entità singolarmente
- # esempio 2
- e per modellare le interazioni fra entità?
- una soluzione (una delle tante) è avere un sistema per verificare se una interazione sta avvenendo, e se si creare al volo una entità che descrive questa interazione. Sui componenti di questa nuova Entità "evento" possiamo triggerare tutti i sistemi che ci pare.
- per esempio: potremmo avere un Sistema<posizione, collidibile> che verifica quali entità collidono e genera una Entità{collisione, entità_a, entità_b} per ogni nuova collisione, un Sistema<collisione> che cambia il colore delle entità che collidono, un Sistema<collisione> che azzera la vita delle entità, un Sistema<vita> che uccide l'entità con vita zero, e un Sistema<collisione> che distrugge l'entità "evento", in modo da consumare gli eventi ad ogni turno
- # sembra complicato?
- si, è un po' complicato. sopratutto perché l'istinto naturale del "prima programma e poi chiedi scusa" qui viene sovvertito: prima di programmare c'è del lavoro da fare per individuare entità, componenti e sistemi, e cercare di evitare l'errore di nascondere dati dentro i sistemi, e comportamenti dentro le entità
- # ma il mondo stesso è complicato
- in realtà però il problema di architettura, il problema di spendere del tempo a sistemare il codice, è un problema che ad un certo punto qualsiasi progetto deve affrontare.
- Chi ha già avuto un progetto personale, ad uno stato medio/avanzato sà quanto è doloroso il debito tecnico di copiare e incollare il codice in giro
- # cosa non sto dicendo
- ecs, come lo ho illustrato qui, è un meccanismo a basso livello per organizzare lo sviluppo, ma non è ancora chiaro come farlo funzionare nella pratica.
- un approccio (semplicistico e poco ottimale) è:
- nel setup, creo le Entità con i loro Componenti, e li salvo in una lista master.
- nel loop, per ogni Sistema itero la lista, ed eseguo il sistema sulla entità se questa soddisfa il suo filtro (per esempio il Sistema<posizione, texture> si attiva solo per le entità con questi due componenti, e disegna a schermo una texture alla posizione indicata)
- ovviamente c'è un discorso dell'ordine con cui attivo i sistemi, e un possibile ordinamento delle entità, che sto accuratamente evitando
- # un approccio più sensato
- usate un motore di entity component system che vi renda la vita semplice
- # svantaggi
- # vantaggi
- # perché è figo
- plugnplay
- mix and mash
- salvataggios
Add Comment
Please, Sign In to add comment