lunes, 18 de febrero de 2013

Postmortem: Naughty Dog's - Jak and Daxter: the Precursor Legacy

  
 
El Postmortem, es un documento que realizan algunos desarrolladores de videojuegos tras finalizar un proyecto. Habitualmente este documento es privado y se queda en los archivos de las compañias, pero en ocasiones algunos valientes desarrolladores se atreven a sacarlos a la luz.

Si se realiza con absoluta sinceridad, este documento puede convertirse en una ingente fuente de conocimiento para futuros desarrollos, ya que en él se detallan que cosas fueron bien y cuales fueron mal durante su proceso de creación, pasadas por el prisma que aporta el paso del tiempo y el hecho de haber logrado finalizar el proyeto.

Para aprender mas sobre los clásicos, una buena forma de hacerlo es a traves de los post mortems, y que mejor forma de hacerlo que comenzando con un clásico de la PS2. En este documento, podremos apreciar que dificultades y aciertos se produjeron durante su desarrollo, de la mano de Stephen White director de programación de Naugthy Dog.




PostMortem de 'Jak & Daxter: The precursor of legacy' por Stephen White
 
A finales de 1998, Naughty Dog había finalizado con gran éxito su tercer juego de la serie Crash Bandicoot, y el cuarto juego de la serie llamado Crash Team Racing estaba por aquella época en pleno proceso de desarrollo preparándose para salir en las vacaciones de finales del año 1999.

Por otro lado, en aquellos tiempos la compañía Sony guardaba recelosamente los detalles de su nueva consola, la esperada Playstation 2 ya próxima a salir al mercado. Pero los rumores y nuestras propias especulaciones nos hacían suponer que aquel nuevo sistema tendría una poderosa capacidad de procesamiento acompañada de buenas capacidades para trabajar con polígonos; por todo ello intuimos que teníamos que pensar en un proyecto a gran escala para desarrollar algo que estuviese a la altura de la nueva máquina.
 

Debido al éxito de nuestros anteriores juegos de la serie Crash Bandicoot (en torno a 22 millones de copias vendidas), tuvimos una fuerte tentación de seguir con la ya probada y exitosa fórmula del pasado, es decir, volver a crear una aventura lineal con diferentes niveles acompañado de una historia sencilla y personajes carismáticos. Con no pocas dudas, nos aventuramos a decir adiós a la serie Bandicoot para embarcarnos en el desarrollo de una nueva aventura épica que esperábamos estuviese a la altura de las expectativas que todo el mundo tenía depositadas en la nueva generación del hardware que aún estaba por llegar.

Uno de nuestros primeros deseos para Jak & Daxter era que el jugador se sintiera en todo momento inmerso en un detallado mundo, de forma contraria a los discretos niveles de detalle que habíamos creado anteriormente en los mundos de Crash Bandicoot. Aunque estábamos todavía trabajando en los primeros conceptos del juego, tuvimos claro desde un principio que queríamos crear un mundo conectado sin tiempos de carga entre niveles, ni cambios repentinos entre escenarios.

Deseábamos construir unos escenarios donde además de poseer un alto nivel de detalle, el jugador pudiera ver a grandes distancias incluyendo los niveles que le rodeaban. Nuestra intención era que el jugador fuese capaz de ver constantemente un horizonte donde pudiese localizar un lugar a donde ir y viajar hasta esa zona manejando su personaje a través del mapeado.

Era importante para nosotros pues, que el mundo de Jak & Dexter fuese coherente y estuviese conectado. De esta forma el jugador y la historia se mezclarían, construyendo un desarrollo más profundo del personaje sin distraerlo de la acción del juego.

También decidimos que el mundo donde se desarrollaría el juego debería estar poblado por personajes animados que proporcionasen tareas a Jak para completar. Estos personajes le darían ayudas al protagonista y le irían revelando el argumento del juego a la par que añadiría humor a la aventura. Queríamos además, que los puzles y los enemigos superasen a todo lo que habíamos realizado con anterioridad.

Para conseguir todo esto y superar otras dificultades, necesitamos tres años de exhausto trabajo que incluyeron 2 años de producción. Encontramos no pocos baches en el camino y en muchas ocasiones, el proyecto se convirtió en una batalla que parecía imposible de ganar. Pero al final conseguimos crear un gran juego y aprendimos un montón de importantes lecciones durante su desarrollo.


¿Que fue bien?

1. Planificación

Quizás el logro más importante de Naugthy Dog's siempre ha sido conseguir desarrollar juegos de gran tamaño en el periodo de tiempo estipulado, aun enfrentándose a serios contratiempos durante su creación. Este, es uno de los hechos menos atendidos en la industria y aunque es verdad que existe una componente de suerte involucrada en las estimaciones, también existen razones muy válidas para explicar porque en Naugthy Dog conseguimos una vez más, manejar y solventar todos los contratiempos a tiempo.

La experiencia, nos ha demostrado que es imposible predecir con exactitud que tareas serán dificultosas de realizar a vista de más de uno o dos meses. Demasiadas compañías caen una y otra vez en la trampa de crear detalladas planificaciónes que intenta estimar y predecir lo que sucederá en un horizonte de trabajo demasiado lejano.

Lo que no es efectivo en estas planificaciones, es que no se tienen en cuenta de una forma real, asuntos tales como los tiempos de debug, los cambios de diseño, enfermedades de los componentes del equipo, reuniones, nuevas ideas y toda una pléyade de impredecibles sorpresas que a menudo son regadas en las planificaciones de un optimismo desmesurado.

En Naugthy Dog, preferimos ser mucho más flexibles en los esquemas de planificación a gran escala y con los cumplimientos de hitos en ciertas fechas, por ello la planificación sólo se detalla para las tareas que se van a abordar en un horizonte cercano.

Si se fallaba al conseguir un hito planificado, entonces el equipo hacia un análisis sobre por qué no se había logrado el hito y se cambiaban los planes en consecuencia. Por ejemplo, si un cierto nivel era planificado para que su fondo estuviese modelado en una fecha determinada y no se conseguía realizar en dicho tiempo, se reconsideraba el hito proponiendo soluciones tales como que el fondo se redujera de tamaño, o una tarea futura de ese artista podía ser dada a otro artista para liberarle más tiempo o el artista podía recibir orientación sobre cómo modelar de forma más productiva o incluso se podía eliminar alguna tarea futura.

En el caso de Jak & Daxter, utilizamos todos los conocimientos que habíamos adquirido previamente en la creación de los juegos de Crash Bandicoot para ayudarnos a estimar cuánto tiempo deberíamos tardar para modelar un nivel. Sin embargo al modelar algunos niveles comprendimos pronto que nuestras estimaciones iniciales eran demasiado cortas, y por ello tomamos las medidas adecuadas para solucionar el problema. Uno de los elementos clave fue la creación del color para la selva prohibida, el juego requirió de dos artistas conceptuales a tiempo completo durante casi dos años de producción para esta tarea.


Si hubiéramos intentado mantener a largo plazo un calendario detallado y poco flexible, habríamos pasado demasiado tiempo teniendo que actualizar algo que era inexacto desde su concepción original. Además, esto hubiera supuesto ser un enorme desperdicio de tiempo y la constante reprogramación de las planificaciones podrían haber tenido un efecto desmoralizador para todo el equipo.

2. Técnicas de localización eficaz


Desde el principio, sabíamos que íbamos a vender Jak & Daxter en muchos territorios alrededor de todo el mundo, así que éramos conscientes de que nos enfrentaríamos a muchos problemas de localización, tales como crear versiones PAL y NTSC, diversas traducciones y la grabación de audio en varios idiomas.

Una cuidadosa estructuración de nuestros datos y del código del juego, nos permitieron localizar el juego a cada territorio intercambiando solamente algunos archivos de datos. Esto, significaba que sólo teníamos que depurar un archivo ejecutable para cada versión, lo que nos permitía realizar de forma simultanea el desarrollo de todas las versiones localizadas del juego.

Todo nuestro código para la reproducción de la animación ,fue escrito de tal forma que se ajustase automáticamente a las animaciones a un ritmo de 1.2 (60 fps/50 fps) cuando se jugaba en PAL. También utilizamos un número estándar de unidades por segundo que nos permitía relacionar la cantidad de tiempo transcurrido en un marco de juego a nuestra medida de unidades por segundo. Una vez que todo fue consistente, ya no tuvimos que preocuparnos por las diferencias entre las versiones PAL y NTSC.

Los cálculos de las físicas entre versiones PAL y NTSC fueron harina de otro costal, si el movimiento de por ejemplo un balón cayendo se calcula agregando una fuerza gravitacional a la velocidad de la pelota por cada fotograma, entonces después de un segundo la velocidad de la bola se veía acelerada en su gravedad por 60 veces en NTSC, pero sólo 50 veces en PAL.

Esta discrepancia, era lo suficientemente grande como para convertirse en un problema entre las versiones PAL y NTSC. Para corregir este problema, nos aseguramos de que todos nuestros cálculos de física se realizaban utilizando segundos, para luego poder convertir la velocidad por segundo en velocidad del juego, lo que provocaba que la conversión fuese correcta.


3. Un mundo transparente, con grandes vistas y sin tiempos de carga.

Sabíamos desde un principio, que en el desarrollo de Jak & Daxter queríamos sumergir al jugador dentro de un gran mundo expansivo y que no queríamos que el juego, se detuviese con cargas entre las distintas áreas de este mundo.

Los diseñadores de Jak & Daxter, tuvieron que superar muchos obstáculos para lograr estos entornos abiertos. Tuvieron que establecer los niveles del mundo cuidadosamente para que los niveles pudieran trasladarse dentro y fuera de la memoria, sin que el juego se detuviese y sin causar bajadas de rendimiento en la apariencia visual.

Además también se tuvieron que crear desafíos atractivos para mantener el interés del jugador en estos grandes entornos, aunque el jugador pudiera moverse libremente alrededor del mundo. Para ello se tuvieron que ajustar todos los desafíos de tal forma que la dificultad se incrementase gradualmente, sin dar la impresión de que dichos desafíos estuvieran siendo excesivamente dirigidos a los jugadores sino que se integrasen como parte del desarrollo de la aventura.

Los programadores tuvieron que crear diversas herramientas para procesar los diferentes niveles interconectados, dichos niveles contenían millones de polígonos y para ello se creó un código rápido de juego que permitía representar el mundo con un alto nivel de detalle.

Desarrollamos varios esquemas complejos de (LOD) nivel de detalle, con distintos esquemas utilizados para diferentes tipos de cosas (criaturas de frente y de fondo) y distintos esquemas utilizados en diferentes distancias, tales como mallas utilizadas para representar la geometría distante y simplificando los modelos utilizados para representar orígenes lejanos.

El corazón de nuestro LOD era nuestro esquema de teselación de la reducción de malla patentado, que habíamos desarrollado originalmente para Crash Team Racing y que fue mejorado radicalmente para Jak & Daxter.


Debido a esta característica de entornos abiertos, los artistas tuvieron una enorme carga de trabajo para poder generar la enorme cantidad de contenido que requerían estos entornos. Su tarea era complicada, puesto que las normas de construcción que tenían que seguir eran muy especializadas para apoyar a nuestros diversos equipos de renders.

Muchas herramientas de soporte y plug-ins fueron creados para ayudar a los artistas, pero dependíamos en gran medida del personal de arte para superar todas estas dificultades.

4. Control de la cámara.

Desde las etapas iniciales de Jak & Daxter, observamos los diversos tipos de cámaras utilizados en otros juegos y llegamos a la deprimente conclusión de que todos los tipos de cámara existentes tenían serios problemas. Llegamos a sospechar que hacer una cámara con un buen comportamiento quizás era un problema irresoluble en entornos 3D. Nos planteamos la siguiente cuestión, ¿cómo podemos crear una cámara capaz de maniobrar de forma inteligente a través de un complejo mundo 3D?.

Sólo los necios creen que todos los problemas tienen una solución, por ello como buenos cabezotas, decidimos intentarlo. La cámara resultante se comportaba muy bien, y aunque tenía sus limitaciones, resultó al final que el problema tenia solución!. Jak podía saltar a través de los árboles y arbustos, caminar bajo arcos, entre andamios, escalar acantilados y esconderse detrás de rocas, todo ello con una cámara que tenía en cuenta la acción.

Queríamos que el jugador pudiese controlar la cámara, pero no queríamos forzar al jugador a tener que hacerlo de forma obligatoria. Los jugadores pueden utilizar el segundo joystick para manejar la cámara (girar la cámara o moverla más cerca o más lejos de Jak), pero nos preocupaba que algunas personas no quisieran manipular la cámara, y otros, como los niños, no tuvieran la destreza o coordinación necesaria para hacerlo.

Por lo tanto, trabajamos muy duro en hacer que la cámara realizase un trabajo razonable de tal forma que mostrase a los jugadores lo que necesitaban, con el fin de que pudiesen completar los diversos desafíos sin tener que manejar la cámara de forma manual.

Logramos todo esto a través de una combinación de volúmenes y parámetros de cámara especialmente ajustados y tuvimos que crear otros modos de cámara más especializados para situaciones difíciles. También, las criaturas podían enviar mensajes a la cámara a fin de ayudar a la cámara a centrar la acción.

Esto puede sonar gracioso, pero una característica importante de buscábamos para la cámara era que no marease a las personas ya que este era un grave problema que plagaba las cámaras en otros juegos. Pasamos un tiempo analizando por qué la gente se mareaba, y ajustamos la cámara para reducir los movimientos de rotación extraños que contribuían a este problema.

Quizá el mayor éxito nuestra cámara es que parece ser que gustó a todo el mundo y por ello consideramos que fue un logro importante dada la dificultad que tenía esta tarea.


5. Reglas GOAL.

Prácticamente todo el código en tiempo de ejecución (aproximadamente la mitad un millón líneas de código fuente) fue escrito en GOAL (objetos de juego ensamblados en Lisp). GOAL es un lenguaje desarrollado internamente por Naughty Dog que se basa en el lenguaje de programación Lisp.

Antes de que nos cataloguéis como locos, hay que considerar las muchas ventajas que supone tener un compilador personalizado.

Lisp contiene un conjunto pequeño de reglas sintácticas de construcción y una evaluación de las listas muy consistente, de tal forma que las listas que representan el código se ejecutan mediante la evaluación de los elementos que están en dicha lista. Si la cabeza de la lista es una función (o alguna otra acción), se podría pensar el resto de los elementos de la lista como los parámetros asignados a esa función. Esta simplicidad de la sintaxis Lisp, la hace trivial para crear potentes macros, algo que sería muy difícil o imposible de implementar mediante C++.

Escribir macros, sin embargo, no era una justificación suficiente para escribirnos un compilador; pero había funcionalidades que sentíamos que no podríamos lograr sin tener un compilador personalizado como el que creamos.

El código GOAL, por ejemplo, puede ser ejecutado con un indicador de escucha mientras se ejecuta el juego. No solamente pueden verse los valores y ajustarlos en tiempo de ejecución, sino que el propio código puede ser compilado y descargado sin interrumpir o reiniciar el juego. Esto nos permitió tener una rápida depuración y puesta a punto, ya que los efectos de la modificación de funciones y estructuras de datos podían verse de forma instantánea.

Hubo otras ventajas importantes de tener nuestro propio compilador: gracias a que tuvimos un conjunto unificado de códigos-operación en ensamblador consistentes éramos capaces de ejecutar el código en los cinco procesadores de la Playstation 2, lo que nos permitía optimizar tareas tales como colorear polígonos gracias al código ensamblador y a la capacidad de combinar las instrucciones de montaje sin problemas con el código de nivel superior. Los bucles externos podían escribirse como código de alto nivel "más lento", mientras que los bucles internos podían ser escritos en ensamblador optimizado.


 
¿Qué salió mal?

1. GOAL nos consumió

Si bien es cierto que GOAL nos dio muchas ventajas, también nos causó muchos dolores. Un único programador (que fácilmente podía ser uno de los diez mejores programadores de Lisp del mundo) escribió GOAL, mientras que él llamó a sus técnicas de programación en Lisp "prácticas y revolucionarias", otros se refirieron a ellas como "código cifrado" ya que sólo él era capaz de entenderlas.

Debido a esto, todo el apoyo para correcciones, mejoras de características y optimizaciones se centraban en una sola persona, creando el consecuente cuello de botella. Además, llevó un año completar todo el desarrollo del compilador, tiempo durante el cual los otros programadores tuvieron que contentarse con la falta de características, peculiaridades y numerosos errores.

Finalmente GOAL se convirtió en un sistema muy robusto, pero incluso ahora C++ tiene algunas ventajas sobre GOAL, como la facilidad de declarar métodos en línea, y mejores destructores y constructores. Una de las principales dificultades fue que trabajamos demasiado aislados del resto del mundo.

Dimos hasta herramientas de desarrollo a terceros, tales como generadores y depuradores, así como bibliotecas que incluían código previamente desarrollado internamente.

En comparación con los miles de programadores con muchos años de experiencia en C++, había relativamente pocos programadores con experiencia en Lisp y ningún programador (fuera de Naughty Dog) con la experiencia que necesitábamos, lo que hacía mucho más difícil la contratación.

2. Programación del juego.

Estábamos tan ocupados creando la tecnología para nuestro mundo que no tuvimos tiempo para trabajar en el código del juego hasta bastante tarde en el proyecto. Esta situación causó una gran frustración a los diseñadores, quienes se vieron obligados a diseñar niveles y criaturas sin poder comprobar si lo que estaban haciendo iba a ser divertido o se iba a jugar bien.

Finalmente los programadores fueron trasladados fuera de las tareas de tecnología para introducirse en las tareas del juego, permitiendo de esta manera a los diseñadores poder hacer los cambios y probarlos al mismo tiempo. Nos arriesgamos, ya que sin la experiencia de nuestros diseñadores, su diligencia y su previsión, el resultado podría haber sido un desastre.


3. Audio.

Estuvimos plagados de problemas relacionados con el audio desde el principio.

Nuestro primer indicio de que las cosas no iban por el camino correcto lo pudimos descubrir cuando nuestro programador de sonido se marchó y se trasladó a Australia. Contratar rápidamente a otro programador de sonido hubiera sido la decisión correcta, pero decidimos probar otras soluciones. Sin embargo si a esto le añadimos que tomamos otras malas decisiones y que tuvimos algo de mala suerte, al final todo acabó convirtiéndose en un desastre.

No reconocimos hasta bastante tarde en el desarrollo, la tarea monumental que suponía realizar el audio para este proyecto. No sólo Jak & Daxter contenía partituras originales, sonidos de criaturas y ruidos de gadgets, sino que además contenía sonidos de ambiente y elementos animados, y para colmo también existían más de 45 minutos de secuencias de la historia con discursos grabados en seis idiomas diferentes.

Nuestros problemas con el audio se podían dividir en cuatro categorías: efectos de sonido, la cola de efectos, la música y la localización del diálogo. Debido a la gran cantidad de efectos de sonido del juego la aplicación de estos efectos se convirtió en una pesadilla de mantenimiento.

No solo los efectos de sonido eran particularmente difíciles o lentos; sino que además crear todos estos efectos y mantenerlos equilibrados suponía una lucha constante. Hubiésemos necesitado dedicar más tiempo a este problema para poder mejorar la compatibilidad con las herramientas que creamos.

Utilizamos la cola de efectos para sonidos prolongados que no encajaban bien en el sonido de la RAM. La cola de impresión de audio tenía muchas ventajas, pero desarrollamos la tecnología demasiado tarde en el proyecto y tuvimos bastantes dificultades para integrarlo en el juego debido a problemas de sincronización.

Nuestra música, aunque compuesta por expertos, carecía de la dirección y atención al detalle que habíamos logrado con los juegos de la saga Crash Bandicoot. En los anteriores juegos, tuvimos una persona que era la responsable de la dirección de la música, desafortunadamente no tuvimos esa misma figura durante el desarrollo de Jak & Daxter.

Los diálogos se convirtieron en un difícil problema debido a la complejidad de la escritura, grabación, edición, creación de la cola de efectos y administración de todos los archivos de audio.

Además, a nuestros problemas de localización se le añadieron más dificultades motivadas por nuestro gran desconocimiento de los diferentes idiomas. Una vez terminado el desarrollo comprendimos que deberíamos haber tenido pruebas más redundantes de los archivos de audio realizadas por personas que hubiesen tenido una mayor fluidez en los idiomas específicos de cada territorio.
 

4. Largos tiempos de procesamiento.

Una de nuestras mayores frustraciones vinieron de la enorme pérdida de productividad debido a nuestro lento tiempo de respuesta cuando realizábamos cambios en un nivel o animación para posteriormente ser probados en el juego real.

Ya que todas nuestras herramientas (incluyendo el compilador) corrían a través de nuestra red, tuvimos serios problemas de ancho de banda en la red. Hacer un mejor uso de los discos duros locales, habría sido un enfoque considerablemente más inteligente.

Además, encontramos problemas extremos de desaceleración de red relacionados con sellos de fecha y hora del archivo de lectura, incluso algunas herramientas se tomaban varios minutos para determinar que nada necesitaba ser reconstruido. Cuando compilamos algunas de nuestras herramientas bajo Linux, observamos notables mejoras en el rendimiento de la red, y por ello estuvimos planeando para un futuro el uso de Linux más extensamente en nuestros próximos proyectos.

5. Herramientas de artista.

Creamos muchas herramientas mientras desarrollamos Jak & Daxter, pero muchas de nuestras herramientas eran demasiado difíciles de usar, y muchas de las herramientas que hubieran sido necesarias nunca fueron creadas.

A menudo no sabíamos exactamente lo que necesitábamos después de varias revisiones de nuestra tecnología. Además, no gastábamos mucho tiempo puliendo nuestras herramientas, por lo que desperdiciábamos demasiado tiempo cuando se hacían modificaciones en la base tecnológica del proyecto.

Lamentablemente, no tuvimos tiempo de crear las herramientas del programa que se necesitaban con urgencia por los artistas, algo que provocó que trabajasen en un entorno difícil y confuso generando muchos problemas de productividad.

Debido a esto, se creó un cuello de botella durante la producción del juego, que supuso una carga añadida a los artistas muy necesaria aunque no por ello menos desagradable.


 
Carecimos de muchas herramientas de visualización que habrían mejorado notablemente la capacidad de los artistas para encontrar y solucionar problemas. Por ejemplo, el principal método utilizado para examinar la colisión, era un modo de depuración que coloreaba una pequeña sección de geometría de colisión que rodeaba a Jak. Una solución mucho mejor hubiera sido crear un proceso para mostrar la colisión a nivel completo.

Creamos plug-ins que se utilizaron dentro del paquete de modelado 3D; sin embargo, para tener una mayor flexibilidad la mayoría de los plug-ins utilizaban una interfaz de línea de comandos para tomar parámetros y como salida de resultados, todo ello mediante texto.

Definitivamente no fue una buena interfaz para los artistas, incluso uno de nuestros polifacéticos artistas creó menús y otras ayudas de visualización que mejoraron significativamente la productividad.

Muchas de nuestras herramientas estuvieron basadas en script, lo que hizo que las herramientas fueran extremadamente flexibles y adaptables. Sin embargo, las secuencias de comandos a menudo eran difíciles de comprender y utilizar por los artistas, por ello intentamos en la medida de lo posible reemplazar en un futuro muchas de estas secuencias de comandos por interfaces gráficas de usuario mucho más fáciles de usar para nuestro próximo proyecto.


 
El legado

La creación de Jak & Daxter fue un esfuerzo monumental realizado por muchos trabajadores, todos ellos personas de gran talento. En perspectiva, probablemente fuimos bastante tontos al observar como solucionamos muchos desafíos, pero ello nos sirvió para aprender dolorosas lecciones para futuros desarrollos. Pero también hicimos muchas cosas bien y logramos acabar con éxito nuestros principales objetivos.

En Naughty Dog existe una fuerte devoción por la calidad, algo que a veces es fronterizo con el caos, pero siempre tratamos de aprender de nuestros éxitos y de nuestros fracasos, a fin de mejorar nuestros procesos y crear un mejor juego.

Las cosas que hemos aprendido de Jak & Daxter, nos han convertido en una empresa más fuerte, y estamos deseosos de aprender de nuestro pasado para prepararnos para afrontar los nuevos retos que tendremos por delante.

 

Datos del juego

Publisher: Sony Computer Entertainment
Número de desarrolladores a tiempo completo: 35
Tiempo de desarrollo: 1 año de desarrollo inicial, además de 2 años de plena producción
Fecha de lanzamiento: Diciembre de 2001
Plataforma: PlayStation 2
Software utilizado: Allegro, Common Lisp, Visual C++, Maya, Photoshop, X Emacs, Visual Slick Edit, tcsh, Exceed, CVS


Fuente: Gamasutra

0 comentarios:

Publicar un comentario