Post Mortem Porting Quell Memento su PlayStation Vita

Daniel Schuller ed io abbiamo formato Bigyama nel 2012, dopo aver lavorato su numerosi titoli come Magic the Gathering: Duel of the Planeswalkers e Star Wars: Battlefront. La compagnia ha iniziato con un salto in tempo reale su PlayStation Home e un trasferimento in Scozia, prima di un ritorno a Nottingham e una ricentratura sui nostri talenti principali: programmare e realizzare grandi giochi! Il nostro primo passo è stato fornire le migliori tecniche per aiutare Fallen Tree Games a portare Quell Memento su PlayStation Vita.


Questo articolo discute di come a Bigyama abbiamo portato Quell Memento in Vita. Se vuoi saperne di più sul design di Quell, guarda l'articolo di Fallen Tree, The Making of Quell.


Iniziare

Memento è il terzo gioco della serie Quell; i precedenti giochi erano andati molto bene su mobile e avevo conosciuto Joe e Lewis in FTG per un po 'di tempo, avendo lavorato con loro a Free Radical Design prima della sua scomparsa. È stato fantastico avere la possibilità di lavorare ancora con loro e avere la possibilità di lavorare su una nuova piattaforma.

Qualche tempo fa avevo incontrato il team di Honeyslug, gli sviluppatori della fortunata Mini Kahoots della PSP che poi sviluppò il titolo di lancio di Vita Frobisher Says. Ci hanno messo in contatto con il team di sviluppo degli sviluppatori di SCEE (Sony Computer Entertainment Europe).

Siamo andati allo studio SCEE di Londra e abbiamo discusso le opzioni - PSP Mini, PlayStation Mobile o PlayStation Vita - ognuna delle quali offre agli sviluppatori l'accesso a Vita con vari gradi di funzionalità. Dopo alcune email avanti e indietro, abbiamo deciso che l'opzione migliore per Quell era quella di creare un gioco nativo Vita, dandoci pieno accesso alla potenza della Vita e a tutte le funzionalità di PSN, come classifiche e trofei.



Affrontare il porto

motori

Spesso il primo compito nella creazione di un gioco è decidere quale motore utilizzare. Esistono diversi motori disponibili su Vita, ma la maggior parte di essi sono completi in termini tecnici e sono semplicemente irrealizzabili da un punto di vista finanziario per un progetto di queste dimensioni.

C'è anche il PhyreEngine, spesso trascurato, sviluppato dalla stessa Sony e liberamente utilizzato dagli sviluppatori registrati di PlayStation: è stato usato per sviluppare giochi da Demon Souls a Colin McRae: Dirt and Journey. Di nuovo, come puoi immaginare, questo era molto più di quanto avessimo veramente bisogno, come provare a rompere un pazzo con un martello.

Convenientemente, Quell Memento ha utilizzato il motore di Fallen Tree Games, e sia il motore che il codice di gioco sono stati scritti utilizzando C. C e le sue varianti sono il linguaggio standard utilizzato per creare giochi e se stai sviluppando un gioco da rilasciare su molte piattaforme diverse davvero non dovrebbe andare con qualsiasi altra cosa.

Ciò ha reso evidente la nostra decisione: avremmo portato il motore di Fallen Tree Game alla Vita. Era gratuito, è stato creato appositamente per eseguire i giochi Quell ed era un buon codice base.

Può sembrare controintuitivo ignorare tutti i motori che già funzionano su Vita e scegliere un motore che non funziona, ma spostare un gioco su un nuovo motore può significare ricreare l'intero gioco per quel motore perché funziona in un modo molto diverso . Porting the engine affronta la radice del problema. Non devi preoccuparti di ricreare ogni singola caratteristica di gioco - devi solo ricreare la funzionalità su cui tutti siedono in cima.

Se sei fortunato, un porto potrebbe offrirti l'opportunità di sviluppare la tua tecnologia per una nuova piattaforma, pur essendo pagata per farlo. Bigyama ha il suo motore in-house e, se Quell Memento fosse stato costruito su un motore senza accesso al codice sorgente, come UDK o Unity, sarebbe valsa la pena considerarlo.

Aree chiave

La bellezza dello sviluppo di un porto è che hai un chiaro obiettivo da raggiungere.

La bellezza dello sviluppo di un porto è che hai un chiaro obiettivo da raggiungere.

All'inizio può sembrare scoraggiante, ma può essere suddiviso in alcune aree chiave: grafica, input dell'utente, audio, networking e salvataggio dei giochi.

Come ho già detto, il porting del motore significava che non c'era alcun codice di gioco significativo da scrivere o riscrivere; in questa situazione, far funzionare queste aree chiave dovrebbe significare che il gioco si prende cura di se stesso. Le prime fasi della creazione di un gioco sono un po 'per trovare il divertimento nel gameplay, ma con una porta è un po' troppo per essere abbastanza attivo e in esecuzione per capire dove è rotto.

Grafica

Quando fai una porta, inizia con la grafica.


È il miglior punto di partenza: se non riesci a visualizzare nulla sullo schermo, sarà molto difficile sapere se stai facendo progressi. Abbiamo iniziato la grafica prima ancora di mettere le mani su una Vita. L'API grafica di Vita è molto simile a OpenGL e Quell Memento utilizzava già OpenGL.

Quell utilizzava una pipeline a funzione fissa (il che significa che l'utente può solo configurare le fasi del processo di rendering attraverso un set fisso di funzioni), ma Vita utilizzava una pipeline programmabile (i programmi shader consentono di programmare le fasi del processo di rendering precedentemente programmate) come l'utente desidera).

Abbiamo avuto un breve periodo tra gli sviluppatori autorizzati e la ricezione dei kit di sviluppo, quindi nel nostro motore (che utilizzava Lua / C ++ / OpenGL) abbiamo emulato il comportamento dello stack matrix OpenGL usando shader e un piccolo codice personalizzato. Ciò significava che tutto il codice esistente di Quell, che era basato sulla tradizionale pipeline a funzioni fisse, poteva rimanere sostanzialmente intatto.

 // Parte del nostro wrapper per emulare lo stack di matrici OpenGL // Puoi trovare il file completo qui: https://github.com/balaam/glfacade Matrix4 glfCalcProjMatrix () Matrix4 mat; mat = mat.identity (); per (int i = 0; i < (int)g_glFacade.projectStack.size(); i++)  mat = mat * g_glFacade.projectStack[i];  return mat; 

Una volta che avemmo dei kit, abbiamo subito avuto qualcosa in funzione. C'era un po 'di lavoro da fare, come convertire il formato dei colori dei vertici in quello previsto dallo shader e reimpacchettare i dati dei vertici da diversi buffer separati, ciascuno contenente gli attributi dei vertici separati - posizione, UV e così via - in un singolo buffer interlacciato come mostrato nello schema seguente:


Con l'aggiunta di uno shader molto semplice, abbiamo presto installato il nostro splash screen sul kit ...


L'utilizzo del colore del vertice è un buon modo per garantire che il tuo gioco funzioni effettivamente e che la geometria venga eseguita correttamente prima di preoccuparti delle trame

Con l'aggiunta di un semplice shader per applicare texture, questo divenne presto questo:


Come ho detto, Quell stava usando la pipeline a funzione fissa e la Vita era programmabile - il che significa che tutto il rendering doveva essere convertito per usare gli shader piuttosto che l'approccio a funzioni fisse di impostare una moltitudine di vari stati di rendering per ottenere un determinato effetto.

Ci sono un paio di scuole di pensiero su come gestire i tuoi shader. Uno è quello di creare uno shader separato per ogni materiale o effetto; l'altro è l'approccio 'uber-shader', un enorme shader che utilizza le definizioni del pre-processore per produrre le varianti necessarie al momento della compilazione. Ognuno ha i suoi pro e contro:

Shader individuali - Pro:

  • Più facile da ottimizzare
  • Più facile da leggere e capire

Singoli shader - Contro:

  • Difficile da gestire in quanto il numero di shader richiesti può crescere incredibilmente rapidamente
  • Richiede spesso un intervento programmatore ogni volta che un artista desidera utilizzare una nuova combinazione di effetti

Uber-shader - Pro:

  • Supporto meno programmatore richiesto dagli artisti (dopo che il lavoro iniziale è terminato)
  • Un numero di file molto più gestibile

Uber-shader - Contro:

  • Più difficile da eseguire il debug e ottimizzare
  • Aumento dei tempi di compilazione

In realtà, è probabile che la maggior parte dei progetti utilizzi una combinazione di entrambi gli approcci. Per il nostro port Quell abbiamo scelto di andare interamente con l'approccio individuale dello shader, in quanto le nostre esigenze erano così semplici e fisse.

Il gioco si basava su relativamente poche combinazioni di stati di rendering OpenGL. Per dare un'idea di quanto fossero semplici i nostri requisiti di shader, ho aggiunto il più complesso qui:

 float4 main (float4 vColor: COLOR0, float2 vTexCoord: TEXCOORD0, float2 vTexCoord1: TEXCOORD1, float2 vTexCoord2: TEXCOORD2, uniforme sampler2D testTex: TEXUNIT0, uniforme sampler2D testTex1: TEXUNIT1, uniforme sampler2D testTex2: TEXUNIT2) float4 texResult = tex2D (testTex, vTexCoord ); float4 texResult2 = tex2D (testTex1, vTexCoord1); float4 texResult3 = tex2D (testTex2, vTexCoord2); float4 currentCol = texResult; currentCol [0] = texResult3 [0] * vColore [0]; currentCol [1] = texResult3 [1] * vColor [1]; currentCol [2] = texResult3 [2] * vColor [2]; currentCol [3] = ((texResult2 [3]) * (texResult [3])) * vColor [3]; restituire currentCol; 

Il codice di Quell Vita aveva un totale di 13 shader: otto programmi shader (un vertice e sette shader di frammenti), combinati con modalità di fusione specifiche. È stato abbastanza facile sostituire il codice nel motore Quell che ha impostato tutte le variabili OpenGL con le chiamate per impostare uno shader invece:

 rlSetBlend (RL_BLEND_RGBA); rlSetMultiTexture (0, rlGetTexture (quellGame_getAtlasImage (QUELLATLAS_SURROUND, true))); rlSetMultiTexBlend (0, RL_TEXBLEND_MODULATE_PASS_INV_ALPHA_TO_NEXT); rlSetMultiTexture (1, rlGetTexture (paneDesatTexture)); rlSetMultiTexBlend (1, RL_TEXBLEND_PREVIOUS_ALPHA_WITH_TEX_ALPHA);

divenne:

 rlSetShader (RL_SHADER_BLEND_RGBA_4);
Il rl (render layer) le funzioni sono un insieme di funzioni che racchiudono la funzionalità OpenGL; il 4 nel RL_SHADER_BLEND_RGBA_4 semplicemente indicato che questa era la nostra quarta variazione di questo shader RGBA - con così pochi shader non avevamo bisogno di una convenzione di denominazione particolarmente descrittiva.

Questi rl le funzioni esistevano già nel motore Quell, ma se il gioco da portare in porta non usa questo tipo di astrazione, è qualcosa che vorrete aggiungere presto. Permette di sottrarre il codice di rendering in modo che le modifiche specifiche della piattaforma possano essere apportate senza influire sul codice di gioco.

L'idealista in me avrebbe davvero voluto implementare un sistema basato su uber-shader. Tuttavia, questo sarebbe stato eccessivo e richiesto il lavoro da parte dei ragazzi dell'FTG per supportare, qualcosa che abbiamo lavorato sodo per minimizzare. Il porting non è diverso da qualsiasi altro compito di programmazione, in quanto dovrai sempre soppesare il "lavoro svolto" contro la tua visione idealizzata di come dovrebbero essere fatto.

In definitiva, ci sono stati pochissimi mal di testa nel far funzionare la grafica del gioco, anche se ci sono stati alcuni frustranti sprechi di tempo nel rintracciare ciò che ho ipotizzato fosse una sovrascrittura della memoria nel codice di rendering. È passato un po 'di tempo prima che me ne rendessi conto, a differenza di chiamate come glDrawArrays in OpenGL, dove l'array viene copiato quando si effettua la chiamata, le chiamate di richiamo di Vita non lo fanno, cioè non è possibile riutilizzare il buffer di vertici che si passa alle chiamate di disegno di Vita fino a quando non viene eseguito il disegno. Come puoi vedere dallo screenshot qui sotto, fare così può fare abbastanza casino.


I risultati di riutilizzare il buffer dei vertici prematuramente significava che questo ... ... occasionalmente sembrava un po 'più simile a questo, spesso solo per un singolo fotogramma.

La soluzione per questo era semplicemente utilizzare la funzionalità esistente nell'API per attendere fino a quando non veniva eseguita con il buffer, ma era un promemoria tempestivo dei pericoli di fare ipotesi sul modo in cui le cose funzionano su una nuova piattaforma (e anche su quale bug può essere, su qualsiasi piattaforma).

Input dell'utente

Siamo stati fortunati in quanto i precedenti giochi erano già stati rilasciati su Sony Xperia Play, il che significa che non era necessario molto lavoro per far funzionare i pulsanti: molti dei controlli fisici esistenti su Vita esistono sull'Xperia e sul funzionalità correlate era già in atto.


Lo smartphone Xperia Play presenta un layout simile a gamepad per PS Vita. Immagine da Sony Mobile.

Ciò significava che si trattava solo di mappare le chiavi hardware ai tasti software e passare il pulsante "premuto" e "rilasciato" agli stati del codice di gestione degli input esistente.


PS Vita è dotato di un touch pad posteriore. Foto di popculturegeek.

Dato che il gioco era nato su dispositivi mobili, lo stesso era vero per il pannello frontale. Il touch panel posteriore ha richiesto un po 'di rifinitura, il problema ovvio è che non puoi semplicemente alimentare entrambi nello stesso flusso di input, perché se un giocatore sta toccando entrambi i pannelli e rilascia il fronte, il gioco potrebbe volerlo registrare come equivalente di rilasciare la parte posteriore o non può.

C'era anche un po 'di lavoro nel prendere input dal pannello posteriore (che non ha le stesse dimensioni dello schermo) per sentirsi come se stessero mappando correttamente allo schermo frontale. Ciò è stato ottenuto trascurando un bordo di zona morta attorno al bordo del pannello posteriore e ridimensionando gli ingressi all'interno di questa area per mappare sullo schermo.

 // gli input posteriori non sembrano corrispondere completamente al range dello schermo frontale, quindi allungare il codice // questi sono valori facilmente accessibili #define REAR_DEADZONE_MIN_X 10 #define REAR_DEADZONE_MIN_Y 75 #define REAR_DEADZONE_MAX_X 950 #define REAR_DEADZONE_MAX_Y 430 #define REAR_STRETCH_X 960 # define REAR_STRETCH_Y 544 static vec2 vitaMapRearInputToScreen (int inputX, int inputY) vec2 stretchedInput; stretchedInput.x = (inputX-REAR_DEADZONE_MIN_X) * REAR_STRETCH_X / (REAR_DEADZONE_MAX_X-REAR_DEADZONE_MIN_X); stretchedInput.x = clampf (stretchedInput.x, 0, REAR_STRETCH_X); stretchedInput.y = (inputY-REAR_DEADZONE_MIN_Y) * REAR_STRETCH_Y / (REAR_DEADZONE_MAX_Y-REAR_DEADZONE_MIN_Y); stretchedInput.y = clampf (stretchedInput.y, 0, REAR_STRETCH_Y); return stretchedInput; 

Tutto sommato, penso che siamo arrivati ​​abbastanza leggeri qui, in parte a causa di come il gioco si basa interamente su un semplice gesto di scorrimento. Portare attraverso interfacce radicalmente diverse può essere un vero mal di testa e, fatto male, ha il potenziale per paralizzare un gioco altrimenti fantastico. Se avessimo portato un gioco d'azione in terza persona sul Wii, questa sezione sarebbe stata considerevolmente più lunga.

Audio

Non mentirò; Ho un vero rapporto amore / odio con l'audio. Nel mio tempo libero in Free Radical Design ho passato molto tempo a lavorare con i ragazzi audio del team del motore e i sound designer per ottenere l'audio nel gioco e mi sono divertito immensamente. Audio solleva davvero un gioco e lo porta alla vita.

Purtroppo, il lato più basso delle cose, con il suo cocktail di formati di file, frequenze di campionamento, compressione, voci, bus, streaming di file e così via, non mi ha mai entusiasmato nello stesso modo. Quindi ci siamo avvicinati a questo compito con una certa trepidazione.

Per fortuna, l'SDK Vita viene riempito con campioni (regolarmente aggiornati) che coprono in modo completo tutti i modi di utilizzare l'API audio. Il minimo che vorrete, anche nei più semplici giochi 2D, è la possibilità di riprodurre suoni unici (gli effetti sonori del gioco) e la capacità di riprodurre audio in streaming (musica e altri file di grandi dimensioni che sono troppo grandi per tieni caricato in memoria per tutto il tempo). In molti giochi 2D potresti anche scegliere di attaccare solo con il mono e risparmiare un po 'di memoria in più, forse anche permettendoti di evitare lo streaming completamente.

Con alcuni ottimi riferimenti per lavorare negli esempi, abbiamo avuto tutto l'audio attivo e funzionante in un paio di giorni. L'unico altro grande lavoro sull'audio è stato un passaggio ritardato nel formato audio da VAG a un formato proprietario con un livello molto più alto di compressione, che ha ridotto l'utilizzo della memoria audio a circa il 30% di quello che era stato precedentemente.

Alla fine, il processo di implementazione dell'audio è stata un'esperienza molto meno dolorosa di quanto avessi temuto.

Rete

Quell Memento è un gioco per giocatore singolo senza giochi di rete e funzionalità online limitate, quindi teoricamente avrebbe dovuto essere una delle aree più semplici. La realtà mette bene in risalto una delle sfide del porting su una piattaforma PlayStation: i temuti TRC (Technical Requirement Checklist - una lista di sviluppatori da fare e non da fare per soddisfare QA).

Vorrei sottolineare che Sony non è unica qui; Microsoft e Nintendo hanno i loro equivalenti. A differenza dei dispositivi mobili, in cui la funzionalità online viene spesso fornita da una soluzione cross-platform di terze parti, o PC, in cui l'unica persona che giudica l'implementazione sarà l'utente finale, sulle console questa area tende a essere sottoposta a un controllo approfondito. Questo in parte ha a che fare con il garantire che la funzionalità fornita da un servizio come PSN si comporti in modo coerente tra i titoli e che i blocchi parentali, le classi di età e così via vengano rispettati.

Di conseguenza, se stai eseguendo il porting su una console, anche per un gioco con funzionalità online relativamente semplici, potrebbe essere necessario più tempo del previsto. Per un porto, il rispetto dei TRC può essere una delle parti più intrusive del lavoro che devi svolgere. Requisiti specifici su come gestire eventi quali perdita di connessione o negazione dell'accesso alle funzionalità a causa del blocco dei genitori, nonché i tempi e le modalità in cui è necessario inoltrare queste informazioni all'utente, potrebbero richiedere un certo grado di alternanza tra componenti di gioco e di rete che semplicemente non esistevano nel gioco originale.

Abbiamo utilizzato una libreria fornita da Sony che avvolge tutta l'installazione di basso livello e la rimozione di PSN e attività online in un'interfaccia abbastanza semplice, fornendo callback per tutte le attività asincrone. Le chiamate dal gioco alla funzionalità online potrebbero essere ridotte a pochi gruppi distinti: login, archivio e classifiche, ognuna con pochi parametri per specificare i dettagli.

Tutto ciò significava che una richiesta online poteva essere attivata solo con poche righe di codice, e alla fine abbiamo probabilmente non più di cinque o sei diverse funzioni chiamate dal gioco per supportare le funzionalità online.

I callback del wrapper Sony forniscono dettagli abbastanza dettagliati su tutto ciò che va storto, ma per la maggior parte questi potrebbero semplicemente essere classificati come un successo o un fallimento e il richiamato appropriato al gioco attivato. Ciò significava che potevamo anche ridurre le richiamate dal motore al gioco in altrettante chiamate.

Gli stati di errore sono stati gestiti il ​​più possibile nel codice del motore. Ciò significava che i ragazzi di Fallen Tree potevano continuare a sviluppare Quell senza doversi preoccupare degli stati di errore specifici di Vita.

Ad esempio, se una funzione del motore ha una chiamata prerequisita che potrebbe potenzialmente fallire, piuttosto che richiedere al gioco di chiamare qualsiasi prerequisito e poi la sua richiesta, chiameremmo il prerequisito in silenzio, mettendo in cache la richiesta effettiva. Se il prerequisito fallisse, faremo il dump della richiesta e notificheremo il gioco attraverso il normale callback, richiamando la finestra di dialogo dal lato motore. In caso di successo la richiesta sarebbe eseguita come previsto.


Questo in generale ha funzionato bene; come con qualsiasi sistema che viene aggiunto in seguito e sta facendo del suo meglio per essere non intrusivo c'erano uno o due pezzi di codice meno eleganti, ma ha fatto il lavoro.

Salva giochi

Vale la pena ricordare i giochi salvati perché, come per le funzionalità di rete di cui sopra, sono soggetti ad un alto grado di controllo in termini di TRC. I giochi di salvataggio sono soggetti a due errori chiave: l'esaurimento della memoria di file o l'esaurimento della quota di salvataggio.

(Ho escluso il salvataggio della corruzione perché non c'è davvero molto da fare per un salvataggio corrotto: il sistema ti avviserà e potrai informare l'utente, ma tutto ciò che puoi fare è rimuoverlo e andare avanti ... e forse hai un piccolo grido tranquillo per tutte quelle ore perse.)

L'esaurimento dell'archiviazione del file system è piuttosto auto-esplicativo: semplicemente non c'è abbastanza spazio per salvare ciò che si desidera. La quota di salvataggio viene impostata durante lo sviluppo del gioco; è essenzialmente un limite auto-dichiarato sulla quantità di memoria che la tua applicazione avrà mai bisogno per salvare i dati di gioco. Questa quota non è tutta assegnata all'installazione del gioco, tuttavia - non è garantito che esista.

Nel maneggiare ognuno di questi hai davvero due opzioni.

Se il gioco esaurisce la memoria del file system, puoi:

  1. Avvisare l'utente ma consentire all'applicazione di continuare, oppure
  2. Prevenire il progresso dell'applicazione.

Per quanto riguarda l'esaurimento della quota di salvataggio, puoi:

  1. Predisponi per sovrascrivere o cancellare i dati di salvataggio, o
  2. Assicurati che non accada mai!

La natura di Quell ci ha permesso di affrontare questo problema in modo piuttosto conciso andando con le opzioni 2 e 1, rispettivamente. Quell non è un gioco in cui potresti voler tornare al salvataggio di cinque minuti fa, quindi è necessario un solo salvataggio e questo viene creato automaticamente, salvato e scaricato. Il contenuto e quindi la dimensione del salvataggio è in qualche modo prevedibile.

Alla prima riproduzione il nostro sistema di salvataggio tenterà di allocare la quantità massima di memoria che sarà necessaria per il tuo file di salvataggio. Se non è possibile farlo, ovvero se è già disponibile spazio di archiviazione file insufficiente, verrà visualizzato il messaggio standard mostrato di seguito:


Il giocatore non può continuare fino a quando non ha risolto personalmente il problema (minimizzando o chiudendo l'app e cancellando alcuni dati). Una volta colpito OK, tenterà nuovamente di allocare la memoria. Una volta che questo salvataggio iniziale è stato creato con successo, si può presumere che non si verificherà mai una carenza nel file system e una quota di salvataggio.


altre considerazioni

TRC e invio

Ho già brevemente menzionato TRC (la lista di controllo dei requisiti tecnici) e in quanto disclaimer direi che sono felice che i TRC esistano; come un giocatore, le cose come PSN sono diventate parte integrante dell'esperienza che apprezzo sapendo che posso aspettarmi un certo grado di coerenza nel comportamento dei giochi.

Detto questo, come sviluppatori, sono un dolore. Siamo stati fortunati che il gioco fosse relativamente semplice e in quanto tali molti TRC potevano essere semplicemente ignorati in quanto non erano applicabili. Tuttavia, anche se stai lavorando per portare un gioco relativamente semplice a una qualsiasi console, ti consiglio vivamente di familiarizzare con le regole di quella piattaforma presto e fare riferimento a loro spesso. Ciò che potrebbe essere stato accettabile su una piattaforma potrebbe non volare su un'altra, e non vuoi aspettare finché non ricevi una grande lista di motivi per cui hai fallito il QA per rendersi conto che stai facendo tutto sbagliato.

Per una piccola squadra senza un reparto QA dedicato, questo può sembrare un compito davvero scoraggiante, ma un po 'di senso e pianificazione possono fare la differenza.

In primo luogo, molti dei requisiti sono solo uno specifico modo per chiedervi di non fare cose stupide che probabilmente non vorreste fare comunque - per fortuna, i ragazzi della FTG avevano già evitato di fare qualcosa di stupido, quindi questo è stato un buon inizio.

In secondo luogo, abbiamo mantenuto un foglio di calcolo di tutti i requisiti e se attualmente sono passati, falliti, non possono ancora essere testati o semplicemente non sono applicabili. Dato che le funzionalità chiave sono entrate nel gioco, potremmo fare una lista di questo elenco per aggiornare lo stato di ciascun requisito e allo stesso tempo aggiornare i nostri ricordi su quali restrizioni applicare.

Nel momento in cui abbiamo raggiunto la nostra fase di certificazione della qualità, abbiamo avuto un'idea chiara di dove ci trovavamo rispetto ai TRC e non ci siamo trovati di fronte a brutte sorprese.

Porting a Target in movimento

Assicurati di aver chiaramente concordato i tempi e gli obiettivi. Questo è più un problema di business che tecnico ma cruciale se stai portando un gioco per qualcun altro, anche se è solo un progetto di hobby tra amici. (Vuoi rimanere amici, vero ?!)

Quando abbiamo iniziato a lavorare su Quell Memento non era ancora finito e, mentre c'era un sentimento generale su quando sarebbe stata la data di fine, nulla era scolpito nella pietra. In definitiva, l'intero progetto ha richiesto più tempo del previsto.


Con il senno di poi, sarebbe stato preferibile aspettare che il gioco fosse completamente finito - o almeno molto più completo - prima di iniziare il nostro porto. Poiché il porting del motore è stato raramente influenzato dal nuovo gameplay e dai contenuti, ma ci sono state occasioni in cui le funzionalità richiedevano modifiche al motore. Ci sono state anche delle volte in cui i progressi sul porting del motore sono stati bloccati mentre aspettavamo di aggiungere nuove funzionalità.

Abbiamo un ottimo rapporto con i ragazzi di FTG e siamo stati abbastanza fortunati in queste situazioni per avere la flessibilità di passare ai nostri progetti per questi periodi (compreso l'esame di alcune delle caratteristiche più uniche della Vita come la realtà aumentata), ma come chiunque chi ha mai provato un po 'di multitasking dovrebbe saperlo, questo non è il modo più efficace per lavorare.


Cose che abbiamo imparato

È difficile indicare le singole lezioni straordinarie che abbiamo imparato; abbiamo acquisito più di un accumulo incrementale di conoscenze relative a nuovi strumenti, API e processi.

In futuro, forse saremmo più audaci nel forzare (o per lo meno suggerire) le modifiche nel codice del gioco in cui ci sembrava ragionevole - potremmo aver reso alcune attività più difficili di quelle che dovevano essere questa volta. Ma la definizione di "ragionevole" varia sempre da un progetto all'altro.

Inoltre, probabilmente aspetteremo che un gioco sia più completo prima di iniziare a lavorare su un porto in futuro, avendo più persone che lavorano su di esso per un tempo inferiore. Anche in questo caso, la fattibilità di questo potrebbe variare enormemente tra i progetti a seconda del programma di rilascio. Avendolo fatto una volta, però, ora possiamo valutare meglio quanto a lungo potremmo aver bisogno.

Ancora più importante, abbiamo accumulato mesi di preziosa esperienza su una nuova piattaforma, incluso il processo di invio, anche avendo la possibilità di indagare su alcune delle sue caratteristiche uniche. Per una squadra che si basa in gran parte sul lavoro a noleggio e sul lavoro a contratto come fonte di reddito, il valore di questo non può essere sottovalutato.


Conclusione

Il mio consiglio per qualcuno di voi che considera un porto per Vita sarebbe di dargli una spaccatura. Penso che ci sia una certa mistica che circonda lo sviluppo della console; siamo stati fortunati ad avere esperienza in questo campo, ma anche senza questo non dovresti essere scoraggiato.

Sony è molto accogliente nei confronti di indie e piccoli sviluppatori (qualcosa che penso diventi evidente alla più ampia comunità di sviluppatori di giochi) e, se possiedi un ragionevole grado di conoscenza dello sviluppo del gioco tecnico, con il grande supporto del team di supporto degli sviluppatori di Sony non dovresti incontrare sfide insormontabili.

Quell Memento per Vita è ora disponibile in SCEA e SCEE.