Mirror [35] è un API high level per il networking open source implementata per Unity3D grazie alla quale è stato possibile sviluppare la parte collaborativa del progetto di questa tesi. Si colloca sul livello di trasporto per la comunicazione real-time, e gestisce molte delle tasks che sono richieste in un videogioco multi-player. Mirror è inoltre un sistema server authoritative ovvero permette a uno dei partecipanti di svolgere il ruolo sia di client che di server allo stesso tempo, in modo tale che non ci sia la necessità di avere un server dedicato. In seguito verranno illustrati i concetti chiave e i componenti fondamentali per il funzionamento di questa libreria.
Mirror offre dei vantaggi nella comodità d’uso poiché permette di sviluppare video-giochi multiplayer con una contenuta quantità di lavoro da parte degli sviluppatori, essendo che esso funziona in congiunzione coi servizi internet ed essendo che permette un tipo di workflow iterativo.
3.4.1 Server e Clients
Sono le due classi base per il funzionamento di un’applicazione sviluppata con Mirror. Il server è un’istanza dell’applicativo alla quale tutti i giocatori si connettono quando vogliono giocare insieme, e tiene conto di diversi aspetti di tale applicativo, mantenendo la coerenza dell’ambiente virtuale condiviso (ad esempio il punteggio), mentre i client sono ogni singola istanza del gioco che si connette al server. Questi possono connettersi in locale, ma anche online (di seguito la procedura). Il server può essere sia dedicato, quando c’è un’istanza del gioco che è dedicata soltanto alle funzionalità proprie del server, sia Host server, ovvero uno dei client agisce sia da Server che da client. Ora per comprendere come queste due classi comunichino bisogna introdurre i concetti cardine di Mirror
3.4.2 Authority
Come detto precedentemente, Mirror è un sistema server authoritative e ciò significa che dipende dall’authority, ovvero come e dove un oggetto di gioco sia gestito, e questa solitamente è di appartenenza del server; ciò fa sì che sull’istanza di gioco del server l’ambiente condiviso venga modificato e poi propagato ai rispettivi client mantenendo la coerenza tra le diverse istanze. Mirror però offre anche la possibilità di affidare la local authority ad alcuni gameobject.
3.4.3 Network Identity
Componente che controlla l’identità unica di un oggetto nel gioco sul network, e che è utile affinché il gioco mantenga la coerenza sullo stato di quell’oggetto su tutti i client connessi.
Figura 3.2: Il component Network Identiti nell’Inspector di Unity
3.4.4 Network Behaviour
Si tratta di script che funzionano per tutti gli oggetti con una network identity.
Questi script permettono di utilizzare funzioni ad alto livello che permettono di comunicare col server per aggiornarlo sulle azioni dei singoli giocatori sulle istanze locali, oltre a fornire numerose informazioni sulle proprietà dell’oggetto (netID, isServer, isClient, isLocalPlayer, ecc..).
Le funzioni che permettono di comunicare col server sono chiamate Commands e sono l’unico modo per i client di attivare del codice sul Server, che è l’unica istanza a possedere l’authority sugli oggetti. Quando un gameobject di un client esegue una command, questa automaticamente sarà letta dal server come proveniente da quel determinato client e dunque sarà eseguita sul gameobject corrispondete al mandante della command ma sull’istanza del server. Questo fa sì che sia impossibile chiamare una command da un client per un giocatore differente.
Il server risponde a queste funzioni con due diverse tipologie di funzioni di alto livello:
• Client RPC Calls: possono essere mandate da ogni oggetto presente sull’istanza server con una NetworkIdentity, e il contenuto di tale funzione si riflette sul gameobject corrispondente di ogni istanza client collegata al server.
• Target RPC Calls: funzioni ad alto livello chiamate dal server e invocate sull’oggetto del client corrispondente alla NetworkConnection specificata nei parametri della funzione. Se nel primo parametro è presente la NetworkCon-nection allora il client corrispondente a quella connessione riceverà il messaggio
Figura 3.3: Client RPC
senza preoccuparsi del contesto, invece se il primo parametro è di un altro tipo, allora il client padrone del gameobject con lo script contenente la TargetRpc riceverà il messaggio.
3.4.5 Network Manager
È il componente che permette il funzionamento dell’intera infrastruttura Mirror, e si occupa della gestione di gran parte degli aspetti di un gioco multiplayer. Esso necessita di un riferimento ad un protocollo di trasporto (nella figura viene inserito quello di default per Mirror, ovvero il Thelepathy Transport). Gli sviluppatori di Mirror hanno voluto lasciare la possibilità di scegliere quale protocollo fosse più utile per il proprio videogioco. Vengono supportati trasporti di tipo UDP, TCP, WebGL e Steam e questi possono essere combinati poiché Mirror propone un componente che permette al server di utilizzare due diversi protocolli insieme.
Il NetworkManager si occupa anche della gestione degli spawn dei networked objects tramite l’istanziazione di prefab specificati nell’inspector del componente.
Il Player prefab è il prefab che rappresenta il giocatore, come ad esempio un avatar personalizzato, mentre è possibile dichiarare una lista di altri oggetti che potranno essere spawnati dinamicamente dal server, oppure iscrivere altri prefab direttamente da codice. Inoltre la natura open source di Mirror permette di creare il proprio Network Manager con funzionalità additive ereditando dalla classe NetworkManager.
3.4.6 NoIP
Precedentemente è stata accennata la possibilità di connettersi a Mirror sia tramite una rete locale ("localhost"), che però comporta che tutti i dispositivi siano collegati
Figura 3.4: I settaggi del NewtworkManager nell’Inspector di Unity
alla stessa sottorete per poter comunicare, sia online. Questa seconda metodologia comporta però che il server sia accessibile dalla rete e questo comporta la necessità di un indirizzo IP statico, oppure di un servizio che assegni un hostname all’indirizzo IP dinamico che si desidera raggiungere, ovvero quello a cui è collegato il server.
Per far ciò è stato scelto di sfruttare i servizi messi a disposizione da No-IP, che permette appunto di creare degli hostname custom da assegnare alla propria rete di casa affinché sia accessibile anche dall’esterno, facendo riferimento ad una stringa anziché ad un indirizzo IP. Questo servizio offre la possibilità di ottenere fino a tre hostname gratuiti, che però per rimanere attivi devono essere aggiornati una volta al mese (questo per evitare di avere numerosi hostname che non vengono utilizzati).
Ovviamente sono presenti anche pacchetti a pagamento che non richiedono alcun aggiornamento periodico e permettono di gestire più di tre hostname.