• Non ci sono risultati.

Progettazione ed implementazione di un motore di gioco 3D reattivo e dotato di un sistema di eventi componibili funzionalmente

N/A
N/A
Protected

Academic year: 2021

Condividi "Progettazione ed implementazione di un motore di gioco 3D reattivo e dotato di un sistema di eventi componibili funzionalmente"

Copied!
430
0
0

Testo completo

(1)

UNIVERSITÀ DI PISA

DIPARTIMENTO DI INFORMATICA

Corso di Laurea Magistrale in Informatica (LM-18)

Progettazione ed implementazione di

un motore di gioco 3D reattivo,

dotato di un sistema di

eventi componibili

funzionalmente

RELATORI Prof. Marcello CARROZZINO

Prof. Franco TECCHIA

CANDIDATI

Giovanni PALMITESTA Francesco SCARLATO

(2)

Indice

1. INTRODUZIONE

...5

2. MOTORI DI GIOCO ODIERNI

...13

2.1 UNREAL ENGINE ...39

2.1.1 CENNI STORICI ...39

2.1.2 STRUTTURA E TERMINOLOGIA ...43

2.1.3 PROGRAMMARE CON UNREAL ...46

2.1.4 SISTEMA DI EVENTI ...49 2.1.5 GRAFICA E RENDERING ...60 2.1.6 IMPRESSIONI DI UTILIZZO (UNREAL ENGINE) ...64 2.2 UNITY ...65 2.2.1 CENNI STORICI ...65 2.2.2 STRUTTURA E TERMINOLOGIA ...67

2.2.3 PROGRAMMARE CON UNITY ...70

2.2.4 SISTEMA DI EVENTI ...75

2.2.5 IMPRESSIONI DI UTILIZZO ...77

2.3 UNREAL E UNITY (FEATURE GRAFICHE) ...79

2.3.1 DEFERRED SHADING ...79

2.3.1.1 VANTAGGI DEFERRED SHADING ...81

2.3.1.2 SVANTAGGI DEFERRED SHADING ...82

2.3.2 GLOBAL ILLUMINATION ...82

2.4 UNREAL E UNITY (MERCATO) ...85

3. OPENGL: LA

GRAFICA 3D REALTIME

...86

3.1 PROCESSORI GRAFICI MODERNI (GPU) ...88

3.2 ELEMENTI ESSENZIALI ...90

3.2.1 OPENGL OBJECT ...90

3.2.2 OPENGL CONTEXT ...92

3.2.3 VERTEX ARRAY OBJECT ...92

3.2.4 VERTEX BUFFER OBJECT ...93

(3)

3.2.6 TEXTURE ...95

3.3 IL MONDO 3D ...99

3.4 PIPELINE DI RENDERING OPENGL ...101

4. L'ENGINE SAM: PROGETTAZIONE ED

IMPLEMENTAZIONE

...102 . 4.1 LE SCELTE DI BASE

...102 4.1.1 IL LINGUAGGIO ...102 4.1.2 L'APPLICATION PROGRAMMING INTERFACE (API) ...105 4.2 IL PERCORSO ...108 4.2.1 LIVELLO 0 – IL TUTORIAL (ELEMENTI FONDAMENTALI) ...108 4.2.2 LIVELLO 1 – IL POWER UP (ASTRAZIONE DEI MECCANISMI DI RENDERING) ...109

4.2.2.1 DRAWING CONTAINER ...109

4.2.2.2 GLPROGRAM ...120

4.2.2.2.1 PARSING DI UNIFORM ...121

4.2.2.2.2 OPENGL TERMS ...124

4.2.2.2.3 PARSING DEI BLOCCHI ...126

4.2.2.2.4 RIFLETTERE UN NAMESPACE IN RAM ...135

4.2.2.2.5 MESH ...139

4.2.2.2.6 VAO ...140

4.2.2.2.7 VBO, __VBO, GLBUFFER, RINGBUFFER ...142

4.2.3 LIVELLO 2 – IL BOOST (AUDIO IMMAGINI E FEATURE GRAFICHE AVANZATE) ...145 4.2.3.1 IMPORTAZIONE TEXTURES ...145 4.2.3.2 PIPELINE COMPLETA ...148 4.2.3.3 SOTTOSISTEMA AUDIO ...156 4.2.3.4 RENDER TO TEXTURE ...163 4.2.3.5 DEFERRED SHADING ...172

4.2.4 LIVELLO 3 – TANK MODE (ENTITA' E GESTIONE RISORSE) ...180

4.2.4.1 SERIALIZZAZIONE E GESTIONE DELLE RISORSE ...180

(4)

4.2.4.3 TRASFORMAZIONI APPLICATE AD UN'ENTITA' ...191

5. LA PROGRAMMAZIONE REATTIVA

...199 5.1 FUNCTIONAL REACTIVE PROGRAMMING ...203 5.1.1 SODIUM ...207 5.1.2 RX ...214 5.1.3 EVREACT ...222

6. L'ENGINE SAM: SISTEMA DI EVENTI

REATTIVO

...225

6.1 DESCRIZIONE

...225

6.2 IMPLEMENTAZIONE ...230

6.3 EVENTI TIPATI E COMPOSIZIONE DEL GRAFO ...240 6.4 CONSIDERAZIONI SUL SISTEMA DI EVENTI ...250 6.4.1 FIRST ORDER FRP ...250 6.4.2 EVENTI E CELLE COMPONIBILI FUNZIONALMENTE ...251 6.4.3 COMPONIBILITÀ NATIVA DEI COMPORTAMENTI E DELLE ANIMAZIONI ...252 6.4.4 MULTI-THREADING NATIVO ...253

7. PERFORMANCE E RISULTATI

...257

7.1 DAVIDE CONTRO GOLIA

...257

7.2. VIDEOGAMES ...259

8. CONCLUSIONI

...266

9. GLOSSARIO

...271

(5)

APPENDICE A - PIPELINE OPENGL

...318

A.1 VERTEX SPECIFICATION AND FETCHING ...322

A.1.1 PRIMITIVE ...324

A.2 VERTEX SHADING ...328

A.3 TESSELLATION ...333

A.3.1 TESSELLATION CONTROL SHADING ...334

A.3.2 TESSELLATION ENGINE ...341

A.3.3 TESSELLETION EVALUATION SHADING ...341

A.4 GEOMETRY SHADING ...346

A.5 RASTERIZATION ...351

A.6 FRAGMENT SHADING ...351

A.7 FRAMEBUFFER OPERATIONS ...357

A.7.1 PIXEL OWNERSHIP TEST ...358

A.7.2 SCISSOR TEST ...358

A.7.3 STENCIL TEST ...359

A.7.4 DEPTH TEST ...363

A.7.5 BLENDING ...364

A.7.6 DITHERING ...366

A.7.7 ENDING ...367

APPENDICE B - IL TUTORIAL

...368

B.1 APRIRE UNA FINESTRA ...368

B.2 DISEGNARE UN TRIANGOLO ...371

B.3 TRASFORMARE GLI OGGETTI NEL MONDO 3D ...376

B.4 APPLICARE UNA TEXTURE AD UN OGGETTO ...386

B.5 MUOVERE LA TELECAMERA CON MOUSE E TASTIERA ...396 B.6 IMPORTARE MODELLI 3D ...400 B.7 MODELLO DI ILLUMINAZIONE DI PHONG ...406 B.7.1 COMPONENTE DIFFUSIVA ...407 B.7.2 COMPONENTE AMBIENTALE ...409 B.7.3 COMPONENTE SPECULARE ...409

B.8 INDICIZZAZIONE DEI VBO ...412

B.9 TESTO 2D ...415

(6)

1. INTRODUZIONE

I videogiochi sono una delle forme d'arte più affascinanti mai concepite dall'uomo: è questa profonda convinzione che ci ha condotto a studiare Informatica e a diventare programmatori. E' questa idea, radicata saldamente nelle nostre menti, che ci ha spinto a desiderare di creare SAM (State Against the Machine), il nostro personale motore di gioco.

Il documento alla cui consultazione il lettore si accinge, infatti, verte sulla progettazione ed implementazione di un game engine 3D. Come molti nostri colleghi ed amici ci hanno spesso domandato, dopo avergli riferito il tema del nostro studio, immaginiamo che anche il lettore possa sentire il bisogno di chiederci: “Perché?”.

Già perché addentrarsi in un campo così vasto ed impervio? Perché non servirsi semplicemente di un software commerciale già esistente e collaudato? Le risposte a queste domande sono molteplici e riassumibili in questi punti:

 Valore didattico: il nostro lavoro mira non solo all'ideazione di un software funzionante, ma anche all'accrescimento delle nostre conoscenze e competenze nella programmazione e nell'utilizzo delle

API grafiche. Inoltre, tra gli scopi della tesi, c'è anche quello di

fungere da vademecum per chi, come noi, abbia l'interesse di avvicinarsi alla creazione di un proprio game engine. Ecco perché il

capitolo 3, il capitolo 4, l'Appendice A e l'Appendice B si

soffermano così nel dettaglio rispettivamente sulle caratteristiche di

OpenGL [1] e sul processo di implementazione delle feature del

(7)

 Facilità di adattamento: è indubbio che porsi nello schema di ragionamento di un altro individuo, e/o nello specifico, di una moltitudine di esperti che lavorano da anni su un progetto, non sia né semplice, né tanto meno immediato. Abbiamo perciò posto su due piatti della bilancia la possibilità di sviluppare applicazioni e plugin per un framework già esistente, oppure l'idea di creare la nostra implementazione di un nuovo game engine. Abbiamo capito che il tempo che avremmo impiegato per conoscere a livello professionale un'altra piattaforma sarebbe stato paragonabile a quello speso per ricominciare da zero, considerando come il nostro intento non fosse affatto quello di arrivare immediatamente a sviluppare titoli tripla A. Nel secondo caso, però, la logica implementativa sarebbe stata completamente nelle nostre mani, consentendo al framework di ragionare come noi, e non costringendoci, al contrario, a ragionare come il framework.

 Sfida personale: di questo argomento non se ne parla quasi mai, ma, a nostro modesto parere, è netta nel mondo di oggi la tendenza a dare per scontata l'esistenza di molte cose. Diamo per scontata la connessione a banda larga, le reti wirless, la grafica HDR 4K e tanti altri piccoli dettagli talmente radicati nella nostra realtà iper tecnologica da neanche più notarli. Noi abbiamo scelto di non dare per ovvia l'esistenza di altri motori di gioco e di porci ad un livello più basso, quello di codice, API e librerie e di ripartire da lì per creare qualcosa di non necessariamente nuovo e commercialmente di successo, ma quantomeno nostro e diverso.

La nostra tesi propone una duplice chiave di lettura. Presenta innanzitutto una componente prettamente compilativa, caratterizzata dai

(8)

seguenti aspetti :

 Excursus sulla storia dei motori di gioco, dai loro albori fino ad oggi e panoramica generale su Unity 2018 e su Unreal Engine 4, gli attuali leader nel settore dei game engine (Capitolo 2).

 Introduzione dettagliata ad OpenGL come API (Application programming interface) per interfacciarsi al sottosistema grafico di un dispositivo (Capitolo 3).

 Descrizione delle scelte effettuate nella progettazione del nostro motore di gioco ed illustrazione del processo implementativo. Tutto ciò è stato fatto delineando un percorso che passa in rassegna le feature progressivamente da noi introdotte nel sistema (Capitolo 4).

La tesi presenta, inoltre, una componente di ricerca, legata prevalentemente ai seguenti aspetti:

 Studio della programmazione reattiva e della componibilità

funzionale nell'ambito di un sistema di eventi (Capitolo 5).

 Specifica ed implementazione di un sistema di eventi reattivo all'interno del nostro motore di gioco (Capitolo 6).

 Produzione di alcune applicazioni di test per dare saggio delle attuali capacità del nostro engine e provare l'efficacia delle feature implementate (Capitolo 7).

Soffermandoci sulla componente di ricerca, spieghiamo le differenze tra il nostro modello ed i framework di cui tratteremo nel secondo capitolo.

Abbiamo voluto organizzare l'evoluzione del sistema senza un ciclo di vita rigido come, ad esempio, quello di Unity. In esso, infatti, le funzioni

(9)

maggior parte delle azioni, con il sistema degli eventi innestato all'interno del ciclo di vita stesso. Abbiamo cercato di uniformare il modello, proponendo un sistema in cui gli eventi siano il mezzo centrale a disposizione delle entità per scatenare aggiornamenti ed azioni. In questo modello, anziché un classico game loop, all'interno del quale vengono chiamati, per ogni componente di un'entità, i metodi delegati all'aggiornamento dello stato del sistema, abbiamo, invece, un sistema reattivo. All'interno di esso le componenti ascoltano messaggi (gli eventi) e reagiscono agli stessi con opportune funzioni; ogni funzione registrata da una componente opera sullo stato della componente stessa. Ciò si manifesta, ad esempio, nel fatto di avere a disposizione, invece che un generico metodo Update(), un evento di tick sollevato ogni n millisecondi. Le componenti registrate rispondono a

tale tick eseguendo azioni ed operando modifiche al proprio stato. Esse

possono, inoltre, sollevare nuovi eventi ed inviare, quindi, ulteriori messaggi verso il sistema.

Questo è un modello che mostra delle profonde similarità con quello basato su attori; Carl Hewitt in [54] definisce un attore in questa maniera: “An Actor is a computational entity that, in response to a message it receives, can concurrently:

send a finite number of messages to other Actors.create a finite number of new Actors.

designate the behavior to be used for the next message it receives.” Nel modello ad attori non c'è un ordine intrinseco nell'esecuzione delle azioni descritte sopra. Esse possono, quindi, essere eseguite in maniera concorrente ed asincrona; inoltre, due messaggi inviati in maniera contemporanea possono essere elaborati in qualsiasi ordine. Una propagazione degli effetti sincrona è ciò che, in prima analisi, distingue il

(10)

framework reattivo scritto per animare l'engine SAM da un modello ad attori. Le entità, oltretutto, non sono dotate di indirizzi, esse ascoltano eventi pubblicati all'interno del sistema e questi eventi non sono messaggi indirizzati ad una specifica entità. Game engine funzionali come il Nu

Engine [55] [56] definiscono il concetto di indirizzo (address) assegnandone

uno sia ad eventi sia ad entità. Ecco che inviare un messaggio ad un evento corrisponde a sollevare tale evento. Lo stesso messaggio, invece, potrebbe essere indirizzato ad un entità causando una sua reazione. L'introduzione di indirizzi è considerabile una possibile evoluzione del nostro framework reattivo; in ogni caso rimarchiamo la differenza con il modello ad attori che è, per natura, asincrono e che trova largo impiego nella scrittura di grossi sistemi distribuiti, nei quali è necessario garantire funzionalità di Location

Transparency, Automatic Scale Out, Persistence, Failure Recovery, Resilience, Strong Isolation e BackPressure [57] [58].

Il disegno delle entità resta un disegno a componenti, analogo a quello della maggior parte dei game engine attuali. La differenza è che, nel realizzarlo, abbiamo seguito un modello data-driven, definendo in opportune strutture dati la parte di rappresentazione (i dati) ed in altre strutture quella di logica, ovvero la parte atta alla definizione ed alla generazione degli eventi e delle azioni in risposta agli stessi. In questo modo diventa più semplice, fra entità che hanno la stessa rappresentazione, riutilizzare parti di codice per esprimere comportamenti diversi, un problema nel quale il paradigma ad oggetti mostra i suoi limiti.

Gli oggetti centrali del nostro framework reattivo sono tre: le entità, i

comportamenti (behaviour) e gli eventi.

Le entità ospitano la parte dei dati e sono dotate di strumenti per orchestrare i behaviour che agiscono su ciascuna di esse. Per esempio, in un dato momento, un'entità proiettile può avere attivo un behaviour che le faccia

(11)

seguire in maniera teleguidata un bersaglio. Se il bersaglio nel frattempo viene rimosso dalla scena, l'entità proiettile può ascoltare tale evento, attivando in risposta un nuovo behaviour (ricerca bersaglio) e disattivando il primo.

L'attivazione di un behaviour consiste nella definizione di nuovi

eventi all'interno del sistema e nella registrazione di callback. Gli eventi

sono stati implementati con i costrutti tipici della programmazione funzionale, come filter, map, reduce, ossia con una semantica che si riconduce a quella del calcolo su stream ed a quella della programmazione

funzionale reattiva (FRP). Gli eventi sono, a tutti gli effetti, stream che

emettono valori nel tempo e che, potenzialmente, supportano le stesse operazioni degli stream classici.

Scopo primario della tesi, è, in ultima analisi, la progettazione e l'implementazione di un motore di gioco 3D reattivo, dotato di un sistema di eventi componibili funzionalmente. Abbiamo scelto di chiamare il nostro motore di gioco SAM, acronimo per State Against The Machine. Si tratta di un gioco di parole che allude alla macchina a stati di OpenGL (oltre a richiamare il nome del famoso gruppo grunge anni '90, ndr).

Ma veniamo al vero perché del nome scelto per il nostro framework grafico. A seguito di una ponderata riflessione riguardo alla gestione dei comportamenti delle entità e dell'evoluzione dello stato del sistema in generale, si è deciso di non utilizzare il paradigma FRP puro. I motivi sono vari, senza dubbio, infatti, la scrittura di logica FRP complessa richiede una profonda familiarità con i linguaggi puramente funzionali, ha una curva di apprendimento alta ed impone una certa rigidità nella scrittura dei programmi. Ci siamo posti l'obiettivo, invece, di scrivere un framework il cui utilizzo non comporti un cambio radicale di prospettive e di modo di ragionare da parte del programmatore abituato alla programmazione

(12)

imperativa e ad oggetti.

Durante la scrittura di precedenti applicazioni, ci siamo trovati di fronte a situazioni scomode, nel momento in cui volevano dare alla stessa entità comportamenti diversi. Immaginiamo questa successione di azioni: ruota, muoviti in avanti, animazione di attacco, attacca. In una simile situazione è stato necessario scrivere del codice che si comportasse come un automa a stati finiti ed il controllo dello stesso poteva risultare tedioso, poco espressivo, prono ad errori e non componibile.

Nel nostro framework reattivo le entità sono componenti del sistema, il cui compito è orchestrare l'attivazione e la disattivazione di behaviour. Possiamo vedere un behaviour come una lista di callback registrate sugli eventi del sistema, che ricordiamo essere componibili funzionalmente. Un behaviour, inoltre, è dotato di un evento di terminazione. In un certo istante un'entità si trova in un dato stato di comportamenti, che corrisponde a tutti i behavior attualmente attivi.

Così come una macchina a stati, a seguito di un input, effettua una ben precisa transizione in un nuovo stato, così le entità, a seguito di eventi, transiscono in un nuovo stato di comportamenti, attivando e disattivando determinati behavior. Da qui il nome di State Against the Machine.

Analizziamo ora la struttura della tesi. Essa si compone di dieci capitoli e di due appendici. Nel secondo capitolo abbiamo effettuato un excursus sulla storia dei game engine, seguito dall'analisi di Unity 2018 ed Unreal Engine 4, nel terzo capitolo abbiamo introdotto l'API grafica OpenGL, nel quarto capitolo abbiamo trattato della progettazione ed implementazione delle feature grafiche di SAM, il nostro motore di gioco, nel quinto capitolo abbiamo introdotto i concetti di programmazione reattiva e di programmazione funzionale reattiva, mostrando esempi di framework e librerie già esistenti che utilizzano tali principi, nel sesto capitolo abbiamo

(13)

mostrato la progettazione ed implementazione del nostro sistema di eventi reattivo, nel settimo capitolo ci siamo soffermati sulle performance dell'engine e su alcune demo giocabili da noi prodotte, nell'ottavo capitolo abbiamo presentato le conclusioni del nostro lavoro.

Il nono ed il decimo capitolo rappresentano, infine, rispettivamente, un ricco glossario ed un insieme di riferimenti bibliografici.

Al termine del documento sono riportate l'appendice A, nella quale abbiamo dettagliatamente descritto tutti i passi della pipeline di rendering OpenGL e l'appendice B, nella quale abbiamo descritto l'implementazione di alcune fondamentali e basilari componenti di un motore di gioco.

(14)

2. MOTORI DI GIOCO ODIERNI

Questo capitolo presenta un’analisi dello stato dell’arte in materia di

Game Engine, al fine di valutare le funzionalità comunemente richieste a tali

componenti software e di conoscere la loro storia e la loro evoluzione nel corso degli anni.

Con il termine game engine si intende un framework software strutturato per la creazione e lo sviluppo di videogiochi. Gli sviluppatori li utilizzano allo scopo di realizzare videogames per console, dispositivi mobili (mobile devices) e personal computer.

Le componenti di base solitamente fornite da un game engine sono: un

motore di rendering per grafica 3D e/o 2D, un motore fisico (o un sistema

di collision detection), un motore audio, un motore di animazione, delle librerie per la gestione dell'intelligenza artificiale, uno scene graph ed il supporto video per la creazione di cinematics in computer grafica.

Negli anni ottanta del XX secolo, prima dell'invenzione dei game engine, i giochi venivano tipicamente scritti uno per uno, come entità

singole, tra di loro disconnesse sul piano programmativo. Ad esempio un

videogame per Atari 2600 doveva essere programmato ad hoc in modo da ottimizzare l'utilizzo dell'hardware del display. Il riuso di codice tra un videogame e l'altro era veramente minimo e la scrittura di un framework risultava essere completamente irrealistica; la grande quantità di dati che sarebbe stato necessario salvare, infatti, non era per nulla alla portata delle

piccole memorie dell'epoca. Inoltre, il rapido sviluppo delle tecnologie

legate ai cabinati da sala giochi (arcade games), rendeva difficile adottare un design di programmazione fisso, costringendo le software house ad

(15)

adattarsi ad ogni nuova macchina introdotta sul mercato.

Nonostante ciò, nei citati anni ottanta videro la luce i cosiddetti

construction kits o game creation systems, considerabili antesignani dei

game engine. Si trattava, fondamentalmente, di editor di livelli, distribuiti assieme al software di gioco principale, che consentivano agli utenti di espandere la propria esperienza di gaming costruendo nuove mappe per i propri titoli preferiti. Ne menzioneremo alcuni:

 Pinball Costruction Set: distribuito da EA (Electronic Arts) nel 1983 come videogame per Apple II, Atari 800, Commodore 64, MS-DOS, ed IBM PC fu il primo ad introdurre il concetto di editor in un videogioco. Dava, infatti, all'utente la possibilità di creare e salvare

nuovi flipper tramite una comoda interfaccia drag & drop. Nonostante la fisica di gioco non fosse modificabile, era possibile creare artwork personalizzati per il proprio flipper e salvare tutto su

floppy disk;

Figura 2.1: Interfaccia di Pinball Construction Set su IBM PC (sinistra) e su MS-DOS (destra).  Thunder Force Construction: prodotto da TechnoSoft nel 1984 per

Sharp X1 e NEC PC, seguito del primo episodio di Thunder Force,

sparatutto a scorrimento di origine nipponica, questo titolo, oltre a

(16)

Figura 2.2: Schermate di gioco Thunder Force Set su NEC PC.

 Adventure Construction Set: pubblicato da EA nel 1984 per Commodore 64, Apple II ed MS-DOS, poteva essere utilizzato per creare giochi di avventura tramite mattoncini. Consentiva all'utente di

costruire mappe, posizionare creature ed oggetti tramite un piccolo

menu;

Figura 2.3: Interfaccia dell'editor di Adventure Construction Set su Amiga (sinistra) e su AppleII (destra).

 Garry Kitchen's GameMaker: si tratta di un IDE (Integrated Development Environment) pubblicato da Activision nel 1985 per Commodore 64, Apple II ed IBM PC. Viene ricordato come il primo prodotto di game design di alto livello ad essere stato rilasciato. Consentiva di creare sfondi, oggetti mobili, effetti sonori, nonché di

(17)

BASIC, ma con funzioni audio e video già integrate. L'editing della

scena avveniva tramite una interfaccia a menu. Tale IDE dava il meglio di sé sul Commodore 64, che all'epoca, disponeva della maggior potenza di calcolo e ricchezza di suoni e colori tra tutti i computer e le console commerciali disponibili;

Figura 2.4: Interfaccia dell'editor di sprite (sinistra) e dell'editor di sfondi (destra) di Garry Kitchen's Game

Maker su Commodore 64.

 Wargame Construction Set: pubblicato da Strategic Simulations Inc nel 1986 per Amiga, Atari 8-bit family, Atari ST, Commodore 64 ed MS-DOS consentiva al giocatore di creare, modificare e giocare a

scenari di guerra da lui costruiti. Era possibile disegnare la mappa e collocare elementi ambientali, quali alberi, cespugli o edifici. Ogni

unità aveva, inoltre, i propri attributi modificabili. Queste caratteristiche garantivano al giocatore una quantità pressoché illimitata di scenari giocabili. Il gioco metteva a disposizione otto

(18)

Figura 2.5: Interfaccia dell'editor di mappe (sinistra) e schermata di gioco (destra) di Wargame Construction

Set su MS-DOS.

 Shoot-'Em-Up Construction Kit: prodotto dalla Sensible Software

nel 1987 per Commodore 64, Amiga ed Atari ST, consentiva all'utente di creare semplici giochi sparatutto (shoot'em up), disegnando

sprites e sfondi e modificando i pattern di attacco dei personaggi. La

creazione dei livelli era sempre basata su un'interfaccia a menu e metteva a disposizione editor di sfondi, di sprite, di animazioni, di colori e di semplici effetti sonori;

Figura 2.6: Interfaccia dell'editor di Shoot'Em'Up Construction kit su Amiga.

 Arcade Game Construction Kit: rilasciato dalla Brøderbund nel 1988 per Commodore 64, consentiva di creare piccoli giochi arcade e salvarli su floppy disk. La creazione dei livelli avveniva tramite menu, immettendo i controlli via joystick (joypad);

(19)

Figura 2.7: Interfaccia dell'editor di Arcade Game Construction kit su Commodore 64.

Il concetto di game engine nacque, tuttavia, solo successivamente, all'inizio degli anni novanta, quando alcune compagnie di videogame iniziarono a sviluppare i loro primi, embrionali, motori di gioco, da utilizzare in combinazione con il nuovo software di propria produzione. Tali motori erano proprietà esclusiva della software house e non si pensava affatto alla possibilità di venderli o di concederne la licenza per l'utilizzo. Non esistevano ancora, quindi, game engine di terze parti, da utilizzare per realizzare il proprio software su licenza (license).

Lo sviluppo dei game engine fu legato principalmente alla comparsa dei primi giochi 3D. Citiamo i motori che nacquero in quell'epoca:

 Ultima Underworld Engine: si tratta del motore con il quale la

Origin Systems sviluppò Ultima Underworld nel 1990. Quest'ultimo può essere considerato uno dei primissimi videogame in 3D della storia. Esso sfrutta, infatti, alcuni efficaci espedienti per dare l'impressione della tridimensionalità, quali dislivelli e superfici

inclinate. Gli NPC, inoltre, pur essendo semplici sprite 2D, sono renderizzati in 3D, come, d'altronde, tutto il resto degli elementi di

(20)

Figura 2.8: Immagini di gameplay di Ultima Underworld su MS-DOS.

 Doom Engine: prodotto dalla id Software ed anche noto come id

Tech1, il Doom Engine fu ultimato nel 1993 ed utilizzato per creare Chex Quest 1, Chex Quest 2, Doom, Doom II, HacX, Heretic, Hexen e Strife. Non si trattava di un vero motore 3D, bensì di un

motore 2D capace di dare l'illusione della tridimensionalità utilizzando le differenze di altezza tra gli elementi architettonici degli ambienti. Tutte le entità di gioco non collegate alla mappa non erano altro che sprite 2D. Ad esempio, a causa della natura essenzialmente bidimensionale del motore, non era possibile posizionare una stanza al di sopra di un'altra all'interno di un livello. Tuttavia questa scelta rendeva il motore ed i giochi con esso realizzati, estremamente

leggeri, capaci, quindi, di funzionare anche su hardware poco potente.

Figura 2.9: Immagini di gameplay di Doom su MS-DOS.

(21)

software su cui Doom e Quake si basavano e costruire su di esso i propri videogiochi originali, preoccupandosi principalmente del design di grafica,

personaggi, armi e livelli.

Figura 2.10: Immagini di gameplay di Quake su Windows '95.

Ecco che iniziava a profilarsi la fondamentale distinzione tra game concept

(collisioni, gestione input) e game asset (personaggi, ambienti, livelli,

textures). Continuando il nostro viaggio nella storia dei game engine ricordiamo:

 BUILD Engine: creato da Ken Silverman nei primi anni '90, ebbe il suo momento di gloria tra il 1995 ed il 1996, quando William

Shatner's TekWar, Witchhaven e Duke Nukem 3D vennero

commercializzati. Fortemente ispirato al Doom Engine, BUILD fu uno dei primi motori ad essere concesso in licenza a terzi per lo sviluppo delle proprie opere videoludiche. E' famoso per aver introdotto alcune

novità rispetto all'idTech 1, quali, ad esempio, la suddivisione del

mondo in settori, la possibilità di modificare l'altezza delle stanze, la possibilità di orientare la telecamera verso l'alto e verso il basso, nonché l'illusione della presenza di edifici con più piani nelle mappe. Quest'ultima feature funziona mediante un ingegnoso meccanismo di

teletrasporto del giocatore, il quale viene semplicemente traslato in

(22)

Figura 2.11: Immagini di gameplay di Duke Nukem 3D su Windows '95.

 XnGine: prodotto dalla Bethesda e pubblicato nel 1995, si tratta del primo motore interamente 3D della storia dei videogame. E' stato usato per programmare Battlespire, The Elder Scrolls II: Daggerfall,

Redguard, NIRA, Terminator: Future Shock, Terminator: SkyNET ed X-Car. L'XnGine ebbe molti problemi di compatibilità e

stabilità su Windows 95, in quanto sviluppato per DOS. I principali problemi erano dati, in particolare, dagli oggetti poligonali in 3D (mesh), un'assoluta novità, visto che fino a quel momento, in tutti gli altri engine, erano sempre state utilizzate sprite 2D per gli item di gioco;

Figura 2.12: Immagini di gameplay di The Elder Scrolls II: Daggerfall su MS-DOS.

 Jedi Engine: rilasciato nel 1995 dalla LucasArts ed utilizzato per

(23)

accovacciarsi e di guardare in alto ed in basso. Le dimensioni degli

oggetti di gioco, altresì, scalavano a seconda della distanza dal punto di vista del giocatore, accrescendo l'effetto complessivo di tridimensionalità e prospettiva;

Figura 2.13: Immagini di gameplay di Star Wars: Dark Forces su MS-DOS.

 Quake Engine: pubblicato nel 1996, fu il primo motore interamente

3D sviluppato dalla id Software e venne utilizzato per programmare CIA Operative: Solo Missions, Hexen II, Laser Arena, Quake, Silver Wing ed Urban Mercenary. Fu il primo motore ad introdurre

lo z-buffering, tecnica che contribuiva, assieme al view-frustum culling ed allo scene graph, a renderizzare nella scena soltanto ciò che era visibile al giocatore, risparmiando enormemente sulla quantità di poligoni renderizzati. Furono, oltretutto, aggiunte sorgenti luminose

3D;

(24)

 RenderWare: creato già nell 1993 dalla Criterion Software, questo game engine iniziò ad essere utilizzato commercialmente dopo il 1996 e raggiunse l'apice del suo successo imprenditoriale nei primi anni 2000. Questo è da imputarsi alla scelta di Sony e di moltissimi sviluppatori di sfruttare RenderWare per la programmazione grafica su

PlayStation 2. Più di 200 giochi furono realizzati con RenderWare, tra i quali ricordiamo Alone In The Dark (Hydravision Entertainment, 2008), Burnout (Criterion Games, 2001), Call Of Duty: Finest

Honor (Activision, 2004), Grand Theft Auto: San Andreas

(Rockstar Games, 2004), Harry Potter And The Prisoner Of

Azkaban (EA, 2004), Killer7 (Capcom, 2005), Manhunt (Rockstar North, 2003), Pro Evolution Soccer 6 (Konami, 2006), Rayman 2:

Revolution (Ubisoft, 2000), Sonic Heroes (Sega, 2003), Tony

Hawk's Pro Skater 4 (Neversoft, 2002). Si tratta sicuramente del

motore di gioco più prolifico dell'epoca pre-GPU, l'avvento delle quali aprì le porte ad un nuovo modo di concepire la grafica 3D.

Figura 2.15: Immagini di gameplay di Manhunt e PES 6 su PlayStation 2.

Fu proprio in quest'epoca di grande fermento che vendere la licenza di utilizzare il proprio game engine per usi commerciali divenne una pratica

(25)

Durante tutto il ventennio successivo i game engine divennero sempre più in voga e furono utilizzati sia da grandi software house, sia da piccoli sviluppatori indipendenti. Proseguiamo nel nostro percorso descrittivo:

 id Tech 2: anche noto come Quake II Engine, fu un upgrade della precedente versione id Tech 1, lanciato nel 1997. Rispetto al predecessore introdusse il supporto ad OpenGL e nuovi effetti di illuminazione basati su un sapiente utilizzo dei colori. L'engine divenne popolare grazie alla sua facile modificabilità (modding). Venne infatti pubblicato il suo codice sorgente, rendendo possibile agli sviluppatori realizzarne dei fork ad hoc.

Figura 2.16: Immagini di gameplay di Quake 2 su PlayStation.

Unreal Engine: realizzato dalla Epic Games nel 1998, nacque

essenzialmente come motore per sparatutto in prima persona (FPS), in combinazione con il videogame Unreal. Fu il principale rivale del motore di id Tech 2. Ne parleremo nel dettaglio più avanti nel capitolo.

(26)

Figura 2.17: Immagini di gameplay di Unreal su Windows '98.

Lilitech: nato nel 1998 da una collaborazione tra Monolith e

Microsoft, si chiamava inizialmente DirectEngine. Fu riacquistato

interamente della Monolith e ribattezzato definitivamente Lilitech. Fu utilizzato principalmente per giochi indipendenti a basso budget. Tra i titoli più famosi creati col Monolith ricordiamo Aliens vs Predator 2,

F.E.A.R., The Matrix Online, Tron 2.0.

Figura 2.18: Immagini di gameplay di The Matrix Online su Windows XP.

id Tech III: pubblicato nel 1999, segnò una rivoluzione nel campo

delle animazioni, che raggiunsero un nuovo livello di fluidità, grazie al passaggio dalle skeletal animation alle per-vertex animation. Call

Of Duty, Medal Of Honor: Allied Assault, Star Wars Jedi Knight II : Jedi Outcast, Quake III Arena, Return To Castle Wolfenstein,

(27)

sono solo alcuni dei titoli firmati id Tech III.

Figura 2.19: Immagini di gameplay di Medal Of Honor su PlayStation.

GeoMod (Geometry Modification): sviluppato da Volition nel 2001 ed utilizzato esclusivamente per gli sparatutto in prima persona Red

Faction e Red Faction II, fu il primo engine ad introdurre il concetto

di ambienti distruttibili (destructible environment) in un videogame;

Figura 2.20: Immagini di gameplay di Red Faction su PlayStation 2.

Torque Engine: creato nel 2001 come motore grafico interamente 3D,

uscì insieme all'FPS Tribes 2. Divenne molto famoso in quanto capace di alterare a runtime il livello di dettaglio delle scene, riducendo così il numero di poligoni da renderizzare;

(28)

Figura 2.21: Immagine di gameplay di Tribes su PlayStation 2.

Serious Engine: utilizzato per l'intera serie di sparatutto Serious Sam,

fu pubblicato da Creoteam nel 2001. Fork dell'id Tech III, la sua principale qualità consisteva nel riuscire a renderizzare ambienti

molto ampi con una notevole quantità di personaggi su schermo.

Questo consentì a Serious Sam di essere un gioco estremamente frenetico ed adrenalinico;

Figura 2.22: Immagini di gameplay di Serious Sam su Windows XP.

Max-FX: pubblicato dalla Rockstar nel 2001, assieme al primo Max Payne, introdusse l'effetto di rallentamento del tempo definito bullet time, che era stato reso famoso pochi anni prima al cinema dal film

(29)

Figura 2.23: Immagini di gameplay di Max Payne su PlayStation 2.

Unreal Engine 2: uscito nel 2002 insieme ad America's Army,

introdusse numerose novità rispetto alla precedente versione, come vedremo più avanti nel capitolo;

Figura 2.24: Immagine di gameplay di America's Army su Xbox.

Gamebryo: sviluppato da Numerical Design Limited, fu pubblicato

nel 2003 ed utilizzato, negli anni successivi, per più di 200 giochi, tra cui i capolavori RPG della Bethesda Fallout 3, Fallout New Vegas,

The Elder Scrolls III: Morrowind, The Elder Scrolls IV: Oblivion.

Noto per la sua grande flessibilità, supportava moltissime piattaforme e tecnologie, tra cui DirectX 9 e 10, era predisposto alla programmazione multi-core ed era integrabile con ambienti professionali di modellazione 3D quali Maya e 3Ds Max. Tra le sue feature ricordiamo anche un sistema di rilevazione delle collisioni

(30)

dinamiche (dynamic collisions detection), nonché un generatore di effetti particellari ed un gestore di audio 3D;

Figura 2.25: Immagini di gameplay di TES IV: Oblivion e Fallout 3 su PlayStation 3.

id Tech 4: si tratta di una complessiva riscrittura dell'id Tech 3, che

venne traslato dal C al C++ nel 2004, in combinazione con l'uscita di

Doom 3;

Source: sviluppato dalla Valve Corporation e rilasciato nel 2004, fu adoperato per famosi titoli quali Counter Strike: Source, Garry's

Mod, Half Life 2, Left 4 Dead e Portal. Era un motore molto

avanzato, dotato di innovative tecnologie di shading, illuminazione,

luci dinamiche (dynamic lights), fisica, nonché numerosi effetti visivi, come il motion blur o la water reflection. Era inoltre dotato di un sistema di animazione facciale molto avanzato e di

(31)

Figura 2.26: Immagini di gameplay di Half Life 2 su PlayStation 2 (sinistra) e di Left 4 Dead su Windows 7

(destra).

CryEngine: sviluppato originariamente dalla Crytek nel 2004 come motore dimostrativo per le GPU Nvidia, venne in seguito utilizzato per produrre titoli di grande successo quali Far Cry e Crysis. Far Cry divenne famoso per la sua totale assenza di tempi di caricamento durante l'esplorazione della vegetazione della vastissima isola, nonché per l'incredibile resa dell'acqua. Crysis, per molti anni è stato considerato alla stregua di un pesante benchmark per le GPU di ultima generazione;

Figura 2.27: Immagini di gameplay di Crysis su Windows 7 (sinistra) e di Far Cry su Xbox 360 (destra).

Unity: presentato da Over The Edge Enterteinment nel 2005, Unity

è divenuto, negli anni, lo standard de facto della programmazione di

videogames indipendenti (indie). Parleremo più nel dettaglio di

(32)

RAGE: l'acronimo sta per Rockstar Advanced Game Engine, fu il

frutto di una collaborazione tra RAGE Technology e Rockstar e rimpiazzò RenderWare, utilizzato per tutti i capitoli PS2 della saga di

Grand Theft Auto. Combinava in un unico pacchetto un framework di rendering, un motore fisico, un motore audio, un motore di animazioni ed un linguaggio di scripting. Fu creato allo scopo di gestire veicoli ed individui che fossero il più realistici possibile, in combinazione con l'uscita di GTA 4 nel 2006;

Figura 2.28: Immagini di gameplay di GTA 4 su PlayStation 3.

Unreal Engine 3: uscito nel 2007 si tratta della versione di Unreal ad

oggi più utilizzata in assoluto, come vedremo in seguito;

Anvil Engine: noto fino al 2006 come Scimitar, nel 2007 fu

ribattezzato Anvil dalla Ubisoft. E' stato il motore di tutta la saga di

Assassin's Creed, nonché di Prince Of Persia e di Prince Of Persia: Le Sabbie Dimenticate. Il motore utilizza 3D Studio MAX per la

modellazione degli ambienti e Zbrush per persone ed oggetti. Negli anni Anvil è stato migliorato, introducendo il ciclo del giorno e della

notte, la messa a fuoco a distanze maggiori, una vegetazione più realistica e migliori effetti di riflessione della luce;

(33)

Figura 2.29: Immagini di gameplay di Assassin's Creed su PlayStation 3.

Frostbite: rilasciato da DICE nel 2008, fu utilizzato per anni

esclusivamente per la saga di Battlefield. Dal 2016, invece, ha esordito con successo in campo sportivo, divenendo il motore ufficiale di FIFA 17 e FIFA 18. La possibilità di distruggere quasi ogni

elemento dell'ambiente, vegetazione inclusa, è una delle

caratteristiche a cui i fan del motore sono maggiormente legati;

Figura 2.30: Immagini di gameplay di Battlefield 4 su PlayStation 4.

Dunia Engine: creato da Kirmaan Aboobaker su richiesta della Crytek si tratta di una rielaborazione del CryEngine, che vide la luce

nel 2008, assieme a Far Cry II. Il motore metteva a disposizione tecnologie quali l'HDRI e la radiosity. Dunia era anche in grado di simulare realisticamente il cambiamento del clima, ma soprattutto il

fuoco e la sua propagazione nella steppa, anch'essa variabile sulla

(34)

Figura 2.31: Immagini di gameplay di Far Cry 2 su Xbox 360.

Dopo questa esauriente panoramica storica sulla nascita e lo sviluppo dei game engine, il nostro sguardo si è inevitabilmente spostato sul presente. Dal 2008 in poi, molti altri motori di gioco sono stati lanciati e sviluppati, fino ad arrivare alla situazione attuale, in cui esistono numerose realtà concorrenti, ciascuna delle quali è, solitamente, specializzata in un determinato settore o sottogenere videludico. Quali sono i motori di gioco di maggiore spessore nel 2018? Vediamone alcuni:

 Godot Engine: engine open-source e royalty-free scritto in C/C++ iniziato a sviluppare da Juan Linietsky ed Ariel Manzur nel 2007, il cui sorgente fu poi pubblicamente rilasciato nel 2014. Interamente sviluppato, da quel momento in poi, dalla community, l'engine può essere eseguito su Windows, Linux, MacOS, BSD ed Haiku e può sviluppare applicazioni per Windows, Linux, MacOS. FreeBSD,

Android, iOS, BlackBerry 10 ed HTML5. Oltre a mettere a disposizione una comoda GUI (graphical user interface), il motore consente di scrivere codice C# o C++ per programmare i giochi, nonché di utilizzare GDScript, il linguaggio di scripting proprio di Godot, molto simile al Python. Godot Engine consente di sviluppare sia applicazioni 2D sia applicazioni 3D. Suoi utilizzatori sono aziende come Rock Milk, Guaranapps e Searchlight games. Tra i giochi più

(35)

noti con esso prodotti ricordiamo Reakt e Get Teddy.

Figura 2.32: Graphic user interface dell'editor del Godot Engine.

 Marmelade SDK: motore di gioco proprietario sviluppato in C/C++ da Marmelade Technologies Limited e presente in circolazione dal 2015. Con una licenza dal costo di 600$, supporta lo sviluppo di applicazioni per Android, BlackBerry 10, iOS, LG Smart TV, Tizen, Windows, Roku 2, Roku 3, Windows Phone 8, ma non Linux. L'idea di mercato dietro Marmelade è quella del write once run everywhere, ossia la possibilità di esportare il medesimo codice sviluppato per qualsivoglia piattaforma domestica o mobile. Molte aziende, come

ZeptoLab, EA, PopCap Games e Nintendo hanno utilizzato

Marmelade SDK e numerosi titoli di successo sono stati realizzati negli ultimi anni con questo motore: Call Of Duty: World At War:

Zombies, Need For Speed: Shift, Plants vs. Zombies, Metal Gear Solid Mobile. Nonostante l'evidente successo, il supporto a

Marmelade SDK è stato interrotto nel Maggio 2018 e l'ultima versione stabile disponibile è quella del Settembre 2016.

(36)

Figura 2.33: Graphic user interface dell'editor del Marmelade SDK.

 Cocos2d: motore di gioco open-source e royalty free specializzato nella realizzazione di applicazioni 2D. Inizialmente sviluppato, a partire da Febbraio 2008, da Ricardo Quesada nella città di Los

Cocos (Còrdoba), in Argentina, il suo sorgente venne reso disponibile

e numerosi fork furono realizzati sia dall'autore originale, sia dalla community. Esiste in almeno cinque varianti, ciascuna scritta in un differente linguaggio di programmazione. Si hanno, infatti: Cocos2d (Python), Cocos2d-ObjC (Objective-C) e Cocos2d-x (C++),

Cocos2d-html5 (JavaScript), Cocos2d-xna (C#). L'elemento

fondamentale del motore di gioco, invece che dalle mesh, è costituito dalle sprite, che vengono organizzate assieme per costruire le varie scene. Cocos2d fornisce al programmatore una GUI, il supporto per motori fisici come Box2D e Chipmunk, un sistema audio basato su

OpenAL, nonché il supporto allo scripting in JavaScript e Lua. Nelle

sue varie implementazioni Cocos2d è capace di produrre software per Windows, MacOs, Linux, Android, Tizen, Windows Phone 7 & 8,

Xbox 360, HTML5 browsers. Tra le aziende che hanno utilizzato negli anni Cocos2d ricordiamo Zynga, Glu, Big Fish Games e Disney

Mobile. Tra i giochi più noti sviluppati con l'engine citiamo: Big Fish Casino, Dragon City, Badland e Castle Clash.

(37)

Figura 2.34: Schermata di creazione di una sprite (sinistra) e schermata di debug di un piccolo gioco di slot

machine (destra), entrambi realizzati con Cocos2d-x.

 MonoGame: si tratta di un motore di gioco open-source e royalty-free ottenuto da una reimplementazione del framework XNA Game Studio

4, di proprietà della Microsoft. Sviluppato a partire dal 2009 da José Antonio Leal de Farias, divenne, nel 2014, l'unico modo di lavorare

con una versione ancora supportata di XNA, a causa della decisione di Microsoft di smettere definitivamente di supportare XNA Game Studio. Monogame si è espanso notevolmente negli anni, divenendo uno dei più utilizzati motori di gioco 2D nel mondo della videoludica indipendente. Consente anche di realizzare applicazioni 3D, sebbene non sia il suo target principale. Per lavorare con MonoGame si scrive codice in linguaggi della famiglia .NET, come il C# o l'F#. Tramite MonoGame si può produrre software per Windows, Linux, Android, iOS, Windows Phone, PlayStation 4, PlayStation Vita, Xbox One e

Nintendo Switch. Tra le aziende che hanno utilizzato negli anni MonoGame ricordiamo: Tribute Games, Kongregate, Supergiant

Game e 17-BIT. Alcuni dei titoli più famosi sviluppati con

(38)

Figura 2.35: Alcune schermate di gameplay di titoli sviluppati con MonoGame (sinistra). Demo di un gioco

platform realizzato utilizzando il framework MonoGame in C# su Visual Studio 10 (destra).

 ShiVa3D: motore di gioco con licenza freemium (il contenuto premium parte da 200$) comparso nel 2007 e specializzato nello sviluppo di videogioochi 3D. Una delle sue feature principali consiste nel gran numero di piattaforme supportate, quali Windows, MacOS, Linux, iOS, Android, Windows Phone, Blackberry 10, PlayStation 3, Xbox 360, Wii, Playstation 4, Xbox One, PlayStation Vita, Apple TV. E' dal 2014 che non viene rilasciata una nuova versione del motore. Tra le società che hanno sviluppato titoli con lo ShiVa3D engine ci sono: Ubisoft, Exkee e Grip Digital. Ricordiamo alcuni giochi sviluppati con questo motore: Prince Of Persia 2: The Shadow, The

Flame, Babel Rising 3D e Voodoo Dice.

(39)

 HeroEngine: motore di gioco proprietario con licenza annuale da 99,95$ all'anno sviluppato da Simultronics Corporation a partire dal 2009. Si tratta di uno strumento specializzato nella creazione di MMO

(Massively Multiplayer Online Games) 3D. Una delle sue feature più interessanti è la cosiddetta online creation. Quest'ultima consiste nella possibilità di vari sviluppatori di lavorare in contemporanea online sullo stesso ambiente 3D, vedendo i propri rispettivi progressi in tempo reale sullo schermo. L'HeroEngine integra numerose tecnologie di terze parti, tra cui FMOD per l'audio, PhysX la fisica,

SpeedTree per la generazione di vegetazione, Vivox per la chat vocale

e fornisce, inoltre, plugin per 3D Studio Max e per Maya. Tra le società che hanno utilizzato negli anni l'HeroEngine ricordiamo UTV

Ignition Entertainment, BioWare e ZeniMax Oline Studios. I più

famosi giochi sviluppati con il motore di gioco sono: The

Repopulation, Star Wars: The Old Republic ed in parte anche The Elder Scrolls Online.

Figura 2.37: Graphic user interface dell'editor dell'Hero Engine.

La scena attuale dei game engine è dominata principalmente da due framework: l'Unreal Engine 4 e Unity 2018. Nelle prossime sezioni verranno introdotti tali prodotti sia dal punto di vista storico, sia dal punto di vista delle funzionalità, al fine di analizzarli mediante un conciso confronto che possa aiutare a cogliere sia le peculiarità tecniche che hanno in comune, sia le divergenti idee di mercato che giacciono dietro di essi.

(40)

2.1 UNREAL ENGINE

L'Unreal Engine è un motore grafico sviluppato dalla società Americana Epic Games, con sede a Cary, nel North Carolina.

2.1.1 CENNI STORICI

La prima versione del motore fu sviluppata interamente da Tim

Sweeney, fondatore della Epic Games. Egli, ispirato dai pionieristici

capolavori di John Carmack, quali Doom e Quake, decise di realizzare il proprio sparatutto in prima persona (FPS), denominandolo Unreal.

Parallelamente con la creazione del gioco, iniziata nel 1995, anche la prima embrionale versione dell'engine prese forma, debuttando ufficialmente nel 1998.

Seppur ancora agli albori, il motore già era provvisto di meccanismi per l'hardware ed il software rendering, per la collision detection, per il

colored lighting e per il texture filtering. Era, inoltre, già presente un editor di livelli denominato UnrealEd, capace di supportare la constructive geometry.

Le piattaforme compatibili furono, fin da subito, Windows, Linux e

MacOS. Negli anni il target sarebbe stato poi esteso anche alle principali

console esistenti (PlayStation 2, PlayStation 3, PlayStation 4, Xbox,

Xbox360, XboxOne, GameCube, Wii, WiiU, Nintendo Switch), così come al mondo del mobile (Android, iOS).

La popolarità dell'engine crebbe rapidamente soprattutto grazie alla sua intrinseca modularità, nonché grazie all'introduzione di un comodo

(41)

come si dice in gergo, "moddare" il sistema. Scopo della modularità era quello di rendere il motore flessibile ed estensibile, capace di resistere, pertanto, ad innumerevoli generazioni di videogiochi. Citiamo, a tal proposito, le parole dello stesso Tim Sweeney:

"... the big goal with the Unreal technology all long was to build up a base of code that could be extended and improved through many generations of games. Meeting that goal required keeping the technology quite general purpose, writing clean code and designing the engine to be very extensible ..."

Unreal (EpicGames, 1998), Unreal Tournament (EpicGames, 1999), DeusEx (Eidos, 2000), sono tutti esempi di titoli famosissimi sviluppati con

Unreal Engine 1.

Figura 2.38: Immagini di gameplay di Unreal Tournament su Windows XP.

La seconda versione del motore fece la sua comparsa nel 2002, recando con sé un nuovo renderer, l'editor di cinematics Matineè ed un file exporter per 3D Studio Max e Maya, così come il motore fisico Karma. Apparve anche UnrealEd3, la nuova versione dell'editor di livelli.

Tra i videogiochi di maggior successo realizzati con UnrealEngine 2 ricordiamo: Tom Clancy's Splinter Cell (Ubisoft, 2002) e Bioshock (2K

(42)

Games, 2007).

Figura 2.39: Immagine di gameplay di Tom Clancy's Splinter Cell su PlayStation 2.

La terza versione dell'engine è sicuramente quella che finora ha riscosso il maggior successo in termini di popolarità ed utilizzo. Presentata nel 2004, la principale innovazione che introdusse fu la sostituzione della vecchia rendering pipeline fissa, con una nuova pipeline basata interamente sugli shader. Utilizzato per più di dieci anni è stato esteso e potenziato nel tempo con l'introduzione di numerosissime feature, tra le quali: ambienti distruttibili (destructible environments), dinamica dei corpi morbidi (soft body dynamics), simulazione di folle (large crowd simulation),

illuminazione globale in tempo reale (real time global illumination).

Mass Effect (Bioware, 2007) è stata programmato tramite Unreal Engine 3, così come Mirror's Edge (EA Digital Illusions CE, 2008), Batman Arkham City (Rocksteady Studios, 2011), DmC: Devil May Cry

(Ninja Theory, 2013) e numerosissimi altri giochi tripla A pubblicati nello scorso decennio.

(43)

Figura 2.40: Immagini di gameplay di DmC Davil May Cry su Xbox 360.

La versione dell'engine correntemente utilizzata è però la quarta (Unreal Engine 4), la quale è frutto di dieci anni di studio e si sviluppo ed è stata presentata ufficialmente nel 2014.

Tra le principali novità che ha portato con sé ricordiamo la hot compilation e l'innovativo modello dei blueprints. Di quest'ultimo

argomento discuteremo a breve.

Gears Of War 4 (The Coalition, 2016), Fortnite (Epic Games,

2017), Kingdom Hearts 3 (Square Enix, in uscita a Gennaio 2019) sono validissimi esempi di titoli creati sfruttando l'enorme potere dell'Unreal Engine 4.

(44)

Figura 2.41: Immagini di gameplay di Fortnite su Windows 10.

2.1.2 STRUTTURA E TERMINOLOGIA

L'Unreal Engine 4 è scritto in linguaggio C++ ed è costituito da una

gerarchia di classi.

L'unità base dell'Unreal Engine è il game object, istanza dalla classe

UObject. Questa classe rappresenta la base per qualsiasi entità che faccia

parte del mondo di gioco. Essa implementa, inoltre, i meccanismi di garbage collection, di serializzazione dei dati (data serialization) e di gestione dei

metadati.

Tra i più rilevanti game objects troviamo sicuramente gli actor, definiti come oggetti posizionabili e modificabili all'interno di un livello: le sedie, i tavoli, il sole, le pareti di una casa ed il personaggio giocante sono validi esempi di actor del sistema. Ciascun actor, oltretutto, può essere sottoposto alle canoniche trasformazioni tridimensionali di traslazione, rotazione e

scalatura. AActor è la classe di riferimento per tale speciale tipo di game

object.

Gli actor, inoltre, possono essere arricchiti tramite le cosiddette

components. Per component si intende una qualsiasi funzionalità o attributo

assegnabile ad un actor, il quale, tuttavia, non potrà mai esistere indipendentemente da esso; potremmo citare, ad esempio, l'audio del rumore

(45)

emesso da una sorgente sonora, oppure il comportamento fisico di un determinato actor.

Tra gli actor di maggior rilievo ricordiamo le pawn, istanze della classe Pawn. Una pawn è un particolare actor che rappresenta un avatar di gioco, sia esso un PC (Playable Character) oppure un NPC (Not Playable

Character).

I characters sono, altresì, particolari pawn, realizzate ad hoc per rappresentare personaggi direttamente gestiti dall'utente. Ecco perché la classe Character è munita, di base, di meccanismi di gestione delle collisioni e di movimento bipede.

Altri actors che vanno necessariamente citati sono i brush, istanze della classe Brush, semplicemente definibili come le geometrie fondamentali del mondo di gioco. Ci sono rette, piani, rettangoli, cubi, sfere, coni, ed in generale tutto il necessario per costruire qualsivoglia ambiente o architettura.

Quando un actor viene collocato nel mondo tridimensionale diviene parte di una scene, altrimenti detta level o map.

Una collezione di levels si definisce world e rappresenta l'intero mondo di gioco.

L'Unreal Engine 4 si compone di numerosi editor, tutti accessibili tramite la GUI dell'editor principale, preposti alle funzionalità più disparate:

 Level Editor: è la base operativa del lavoro, fornisce una finestra sul mondo tridimensionale, consente di inserire nuovi attori nel mondo, di applicare ad essi trasformazioni di traslazione, rotazione e scalatura, così come di gestire l'illuminazione della scena. Dispone di un sistema di creazione e di manipolazione di geometrie. Consente, inoltre, di testare il proprio mondo 3D con la funzione

(46)

 Material Editor: consente di creare nuovi materiali e di modificare quelli già esistenti;

 Blueprint Editor: fornisce lo schema completo dei blueprints del

livello attuale, dando la possibilità di modificarlo a piacimento,

creando così nuove correlazioni tra gli attori;

 Persona Editor: utilizzato per creare nuovi scheletri umani, mesh ed eleganti animazioni;

 Niagara Editor: ha sostituito il precedente Cascade Editor, si tratta di un generatore di effetti speciali particellari;

 UMG UI Editor: serve per creare i propri menu di gioco;

 Matinee Editor: permette di creare e gestire cinematic di ogni tipo;  SoundCue Editor: preposto a creazione e manipolazione di effetti

audio;

 Paper2D Sprite Editor: serve a creare nuove sprite per i giochi 2D;  Paper2D Flipbook editor: consente di creare animazioni per le

sprite 2D;

 PhAT (Phisics Asset Tool): permette di gestire la fisica di gioco;  Static Mesh Editor: consente di creare e modificare mesh statiche;  Media Player Editor: dà la possibilità di gestire la riproduzione di

brani nel gioco;

(47)

2.1.3 PROGRAMMARE CON UNREAL

L'esperienza di programmazione con Unreal Engine 4 si potrebbe definire bipartita. Da un lato si trova il mondo delle classi C++, che costituiscono il nucleo del motore, mentre, dall'altro, si colloca il mondo dei nuovissimi blueprints. Per chi pensasse che lavorare con Unreal significhi operare una scelta tra uno stile di programmazione di serie A (C++) ed uno stile di serie B (blueprints) bisogna immediatamente specificare come i due sistemi siano stati creati allo scopo di interagire e compenetrarsi e non affatto per costituire uno un'alternativa dell'altro.

Il C++ di Unreal è ben lontano dal plain C++, infatti la quasi totalità delle funzionalità dell'engine si innescano e vengono invocate mediante un

sistema di tag appositamente creato dal team Unreal.

UPROPERTY() ed UFUNCTION() sono i due più lampanti esempi

di questa tecnica. Basta, quindi, anteporre ad una proprietà il primo tag e ad una funzione il secondo per trasformarle, rispettivamente, in una proprietà ed in una funzione del motore di gioco. Lo stesso ragionamento vale per

UCLASS, che trasforma una classe qualsiasi in una classe Unreal.

______________________________________________________________

UCLASS()

class AMyActor : public AActor

{ GENERATED_BODY() public: UPROPERTY(EditAnywhere) int32 TotalDamage; ... };

(48)

______________________________________________________________

Listato 2.1: Dichiarazione di una classe personalizzata che eredita da AActor in Unreal.

I parametri dei tag servono a specificare la modificabilità e la

visiblità dell'oggetto taggato rispetto agli editor di Unreal.

______________________________________________________________

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Damage")

int32 TotalDamage;

______________________________________________________________ Listato 2.2: Dichiarazione di una variabile di istanza e di una proprietà che sia ovunque modificabile ed

editabile per mezzo dei blueprints in Unreal.

E' possibile, quindi, rendere un oggetto visibile tramite editor, oppure rendere un valore modificabile (sia staticamente sia a runtime), così come esporre attributi e funzioni al meccanismo dei blueprint, nonché annotarli con un determinato tag.

Nella logica degli sviluppatori dell'Engine, lavorare con il C++ deve essere prerogativa solo dei programmatori più esperti, lasciando invece, ai

game designers, il compito di lavorare con la comoda interfaccia blueprint,

che consente di creare dinamiche di gioco pur non essendo in possesso di particolari capacità tecniche.

I blueprint non sono altro che un flessibile e potente linguaggio di

visual scripting che fornisce una schematica rappresentazione visiva a grafo dei game actor, delle component ad essi legate e delle relazioni che

intercorrono tra gli actor stessi. Il blueprint di un livello racchiude, qundi, i meccanismi di causa effetto che regolano il comportamento degli actor del livello stesso.

(49)

Se volessimo vedere, ad esempio, un braciere esplodere quando il personaggio giocante schiaccia una certa mattonella sul pavimento, potremmo agire così:

 creiamo una trigger box e la collochiamo sulla mattonella scelta;  creiamo una sorgente sonora e le associamo il rumore di una

esplosione;

 cerchiamo e selezioniamo l'evento di collisione con il personaggio tra quelli disponibili per il trigger;

 leghiamo all'evento di collisione la riproduzione di un suono dalla sopracitata sorgente sonora;

 leghiamo all'evento di collisione la scomparsa del braciere.

Figura 2.43: Esempio di utilizzo dei blueprint. La scatola rossa rappresenta l'evento, quelle blu con la

lettera f sono le funzioni che vengono eseguite in risposta all'evento, mentre le altre blu sono gli oggetti bersaglio delle funzioni stesse.

Ecco che con pochi sforzi e senza scrivere una riga di codice, abbiamo implementato la nostra piccola idea. Nel prossimo capitolo vedremo più approfonditamente il funzionamento degli eventi di Unreal.

(50)

tra C++ e blueprint. Bisogna sfruttare il codice nativo per creare attori e, in generale, classi customizzate che soddisfino le nostre aspettative ed idee di gameplay.

In seguito è necessario servirsi della rapidità fornita dal comodissimo approccio visuale dei blueprint, che consentono di collegare tra loro i comportamenti di varie classi semplicemente linkandole in uno schema grafico.

2.1.4 SISTEMA DI EVENTI

Gli eventi di Unreal sono rappresentati tramite i nodi di un grafo detto

event graph. Essi vengono chiamati dal codice del gameplay per fare

iniziare l'esecuzione di una rete individuale (individual network, concatenazione di chiamate di funzione, variabili e nodi di controllo di flusso conseguenza di un determinato evento).

Per event graph si intende un grafo che utilizza eventi e chiamate di funzione per effettuare azioni in risposta alle situazioni che si verificano nel gameplay. L'event graph è una delle componenti fondamentali del blueprint di un livello. Possono esistere vari event graph, almeno uno per ogni livello di cui vogliamo descrivere le interazioni. Per utilizzare un event graph bisogna innanzitutto stabilire i suoi punti di ingresso (uno o più eventi), poi connetterli a chiamate di funzione (function call), nodi di controllo di flusso (flow-control nodes) e variabili di vario genere, definendo, così, il comportamento desiderato. Quando un evento viene sollevato, bisogna immaginare che una sorta di inpulso (pulse), parta da esso, sollecitando l'azione dei nodi successivi ad esso collegati. Quando un nodo riceve tale impulso si attiva e fa ciò per cui è stato programmato, utilizzando tutti gli input di cui necessita e producendo tutti gli output stabiliti.

(51)

All'interno di un singolo event graph è possibile inserire un numero arbitrario di eventi. Ciascuno di essi è caratterizzato da un output pin (da cui fuoriesce il pulse) e da uno o più output data pin (da cui fuoriescono i dati necessari al prossimo nodo dell'event graph). Sottolineiamo come si possa avere un solo evento di default del medesimo tipo per ciascun event graph. Mostriamo il funzionamento di alcuni eventi di default:

L'evento Level Reset viene sollevato quando il livello ricomincia. E'

utile quando si vuole far succedere qualcosa se il livello viene ricaricato per qualche motivo, ad esempio dopo la morte del personaggio. In questo caso, al verificarsi dell'evento, viene eseguita la funzione Set Actor Transform,

che applica al target Player la trasformazione Level Start, che resetta la

matrice di trasformazione del personaggio ai valori di default.

Figura 2.44: Esempio di collegamento di una funzione (callback) all'evento di Level Restart.

L'evento Actor Begin Overlap viene sollevato quando due attori si

intersecano. Nell'esempio sotto riportato, quando il Player interseca l'altro

(52)

Figura 2.45: Esempio di collegamento di una funzione (callback) all'evento di Actor Begin Overlap.

Notiamo come venga utilizzato un nodo di controllo di flusso per effettuare tale operzione, il nodo Branch. Quest'ultimo consente di impostare

una scelta nel flusso di esecuzione del grafo degli eventi ed ha bisogno di una condizione e di una funzione da eseguire sul ramo true e sul ramo false

(eventualmente anche solo su uno dei due).

Esistono numerose altri nodi di controllo di flusso, tra i quali citiamo: il nodo DoN, che manda in esecuzione la stessa catena di nodi per un

massimo di N volte. Una volta raggiunta la condizione di terminazione non agisce, a meno che un impulso raggiunga il suo input di Reset.

Nell'esempio sottostante vediamo come, premendo il tasto W, oppure S,

il valore della variabile throttle viene impostato ad 1 e l'actor Veichle Movement viene attivato. Dopo aver premuto venti volte W oppure S, però, il

nodo DoN smette di funzionare, a meno che non si schiacci F, che resetta il

funzionamento del nodo. Si potrebbe utilizzare un simile meccanismo, ad esempio, per simulare venti accensioni consecutive di un veicolo e poi la necessità di rimettere carburante per farlo ripartire.

Riferimenti

Documenti correlati

 Use of the graphics card for generic tasks (not related with 3D computer graphics).  Ex.:

(ci discostiamo meno dalla soluz analitica, esatta) dt = 1.0 sec / FpS della simulaz fisica. (recall: non necessariametne lo stesso FpS del rendering) quanto cresce l’errore al

Ogni frammento in pos [X,Y] viene processato indipendentemente dagli altri frammenti. indipendentemente da quale primitiva lo ha generato output della computazione: un pixel

applico il lighting una volta per vertice – di solito #vertici << #frammenti. Per-fragment * Lighting – (a.k.a. " Phong Shading“)

La soluzione proposta non è esente dai limiti di ogni game engine e authoring tool: in particolare, quando si crea un software di questo tipo si limita per forza la creatività di

«Palazzo Penne, uno dei rari esempi di archi- tettura di impianto rinascimentale ancora esistente nel centro antico di Napoli costituisce testimonianza tangibile delle vicende

Pezzi diversi, in generale, devono essere lavorati secondo un ordine differente (in caso contrario si parla di “Flow Shop”). Produzione a celle: qui le macchine “sono

Figura 1 - Struttura della Fed 74 Tabella 1 - Le agenzie che disciplinano le banche commerciali 87 Tabella 2 - Indici di indipendenza legale della banca centrale 233 Tabella 3