ES KAsi UN blog

Blog de Unkasoft, donde hablamos de programación de juegos para móviles, advergaming, marketing móvil, la industria de los videojuegos, metodologías ágiles y todos aquellos temas que nos preocupan en nuestro día a día

29 abril 2006

Unkasoft busca jóvenes talentos


Aquí en Unkasoft, siempre estamos abiertos a nuevos talentos en la programación de videojuegos y herramientas, así que si quieres trabajar en una start-up joven y tienes ganas de llegar muy lejos, no te lo pienses dos veces y envía tu currículum a jobs@unkasoft.com

A continuación tenéis los distintos perfiles que buscamos continuamente:

Etiquetas:


27 abril 2006

Battlewizard: plataforma de desarrollo de juegos para móviles

Ya va siendo hora de que hablemos de nuestra plataforma de desarrollo de juegos para móviles: Battlewizard.


Uno de los principales problemas a la hora de desarrollar un producto para teléfonos móviles, es que la gama y capacidades de los dispositivos es muy amplia. Aunque desarrollemos para móviles con soporte para Java (concretamente J2ME, CLDC 1.1 y CDC 1.1), hay que tener en cuenta que no es lo mismo desarrollar para un Nokia 3100 que para un Sony Ericsson S700, por ejemplo. No tienen la misma pantalla, no tiene la misma potencia de cálculo, ni soportan los mismos APIs (el S700 soporta 3D a través de JSR-184).

Este "problema de la fragmentación", nos afecta en muchos aspectos: hay que controlar el contenido que sale pantalla, ya que los tamaños de las pantallas, el número de colores y la resolución es variable, hay que controlar el tamaño de los juegos, ya que cada móvil soporta un tamaño máximo distinto, hay que controlar la ocupación del heap, hay que controlar el tamaño de datos persistentes (Record Store) almacenados... y un sinfín de aspectos más.

La solución tradicional a este problema suele ser desarrollar el mismo juego varias veces, aunque intentando reutilizar la mayor cantidad de código posible. Es decir: un equipo grande desarrolla un juego, pero repite su código para los distintos dispositivos que quiere soportar, intentando extraer todo el código común, y cambiando algunas partes para ajustarse a las peculiaridades de cada dispositivo. Esto genera es un montón de código repetido, propenso a errores y muy rígido ante el cambio.
Pensad que en las últimas fases de desarrollo de un juego es cuando surgen las mejores mejores ideas para hacer el juego realmente divertido, y en ese punto ya está casi todo el código escrito, así que hay que intentar que el código sea lo menos rígido posible.
Este enfoque de desarrollo requiere un equipo grande de personas, normalmente un programador para cada plataforma a soportar, y es el modelo que siguen algunas de las empresas más grandes de desarrollo de juegos para móviles, como por ejemplo GameLoft.

Otra opción que se está imponiendo, es la de desarrollar el juego completo en una única plataforma, y subcontratar a una empresa (habitualmente de bajo coste y en países en vías de desarrollo como China), la migración al resto de plataformas, que se encarga del trabajo sucio. A parte de consideraciones éticas (¿alguien se ha parado a pensar las condiciones en las que trabajan esos programdores?), este modelo requiere más dinero y una coordinación extra con la empresa que hará la migración. Y ni que decir tiene que una vez hecha la migración, el juego es intocable, y no podremos añadir o eliminar características en ciertos dispositivos.

La tercera opción se llama Battlewizard: con nuestra herramienta es posible se desarrollar el juego una vez, tener un único código fuente y que funcione en todos los móviles que se quieran soportar. Incluso un único programador podría generar 150 ó 200 versiones distintas sin mucho esfuerzo.
¿Magia? No, simplemente se tiene en cuenta el problema de la fragmentación desde el principio del desarrollo y se corta de raíz con las herramientas adecuadas.
¿Que quieres sacar tu juego para pantallas pequeñas (128x128) y grandes (240x320)? Pues defines ambos perfiles, añades el contenido gráfico teniendo en cuenta ambos tamaños, y generas la versión para todos los teléfonos que encajen en esos tamaños de pantalla.
¿Que necesitas sacar tu juego para móviles MIDP 2.0 y Nokia? Pues defines ambos perfiles, y al generar la versión se utilizará un motor específico para cada tipo de móvil.

Battlewizard está formado por varios componentes:

Battlewizard soporta cualquier juego para J2ME (ya sea CLDC o CDC), aunque estamos trabajando en las versiones para Symbian y Brew.

Pero como siempre, la magia no existe, y nosotros no somos menos: el principal inconveniente de este modelo es que los juegos deben tener en cuenta el mínimo común de todos los dispositivos que vamos a soportar. Por ejemplo, si nuestro juego debe funcionar en un abanico de teléfonos con un heap desde 500 KB hasta 4 MB, hay que programar teniendo en cuenta los picos de memoria en el dispositivo menos potente, aunque en los dispositivos más potentes no estemos aprovechando toda la memoria que nos ofrece. Es decir: la plataforma más pequeña limitará a las plataformas más potentes.

Bueno, como introducción yo creo que ya está bien. En los próximos posts hablaremos más sobre Battlewizard y todo lo que nos permite hacer.

Etiquetas: ,


22 abril 2006

Piensa en perfiles y capacidades en vez de dispositivos

Hace tiempo iniciamos un cambio de arquitectura de nuestras herramientas y en nuestra forma de pensar hacia las plataformas para las que desarrollamos. Pasamos de pensar en dispositivos a empezar a pensar en perfiles y capacidades.

Nuestro dolor de cabeza comienza cuando nuestros desarrollos orientados a una serie de dispositivos tienen que ser actualizados para nuevos dispositivos que salen al mercado y nuestras herramientas empiezan a ser más complejas de usar y menos intuitivas. Poco a poco y con nuestra experiencia anterior en sistemas como UAProf, empezamos a cambiar nuestra forma de pensar para ser más ágiles y que nuestras herramientas resulten naturales.

El mercado cambia de dispositivos muy rápido y las propiedades de estos dispositivos, aunque estables, cambian de valor bastante a menudo. Por ejemplo, Nokia decide con frecuencia el cambio de tamaño de pantalla en su Serie 40, el cambio de memoria de HEAP y de RMS. Si esto lo llevamos al número de marcas del mercado de móviles, nos obliga a actualizar nuestra base de datos de dispositivos con demasiada frecuencia y no disponemos de tiempo y recursos infinitos.

Nuestra problemática nos lleva a pensar en la comunidad de desarrolladores y en las decisiones que está tomado al respecto y nos encontramos que hay comunidades orientadas a J2ME como J2ME Polish que han creado una base de datos de dispositivos J2ME especialmente diseñada para conocer las diferencias entre los diferentes dispositivos; también nos encontramos otras comunidades, como la de los desarrolladores de WAP que llevan más tiempo luchando con esta problemática y que basándose en sistemas como UAProf , han creado bases de datos orientadas a capacidades, por ejemplo WURFL .

Esto nos lleva a pensar como ya lo hacíamos antiguamente con los problemas de WAP, ya que al final nuestro objetivo es el mismo, presentar contenidos en un dispositivo móvil: PIENSA EN CAPACIDADES.

Usar capacidades consiste en no saber de marcas, modelos y cosas así, sino más bien en tamaños de pantallas, formatos de audio y vídeo, características J2ME, memoria disponible, etc. De esta manera creamos el concepto de perfil, que al final no es más que agrupar una serie de capacidades.

Ahora por fin, nuestros contenidos pueden ser manejados de manera independiente de la base de datos de dispositivos. Nuestra base de datos crecerá y nuestros contenidos se ajustarán a dichos dispositivos según sus capacidades.

Por ejemplo, si creo un perfil que sea “Medio-Bajo” donde apunto que las pantallas van desde 128x128 a 128x160, que soporto PNG como formato de imágenes, que mi HEAP máximo de memoria es de 500 KB, que mi JAR máximo es de 125 KB y que soporto MIDI como formato de audio, es seguro que un grupo de dispositivos de diferentes marcas coincidirá con estas características ahora y dentro de un año.

Nuestra manera de afrontar la problemática de la fragmentación de los teléfonos móviles es pensar en perfiles y capacidades. El objetivo del desarrollo hacia dispositivos no se puede mantener en pequeñas y medianas empresas y tendrá que ser abolido en las grandes compañías en cuanto decidan ahorrar costes de producción.

Etiquetas: ,


05 abril 2006

Integración continua y gestión de la configuración

Como decíamos "ayer", una de las tareas propias de las metodologías ágiles es la llamada "integración continua".
Esta práctica consiste en llevar al límite el proceso de construcción automática y diaria. Si conseguimos automatizar este proceso ¿porqué no lanzarlo cada vez que hagamos algún cambio, por pequeño que sea?
Pues precisamente esa es la clave de la integración continua, pero como es lógico, no todo es tan fácil como puede parecer a simple vista.

El primer paso para la integración continua es, como ya hemos dicho, automatizar el proceso de construcción. Para ello nos basamos en herramientas como Ant, Maven, el antiguo MAKE, Jam, etc., que nos permiten ir lanzando distintas tareas de forma secuencial y sin nuestra intervención.
Una vez que hemos logrado ejecutar todos los pasos necesarios, tenemos que conseguir que ese proceso se lance automaticamente, cada vez que algún cambio de código se integra en el repositorio. Lo podemos conseguir facilmente gracias a un montón de herramientas para ello, que nos ayudan a programar las construcciones, aunque también podríamos habilitar una máquina dedicada y conseguir que todo el equipo se comprometa a lanzar una compilación después registrar cada cambio. Ummmm, creo que va a ser mejor instalarse alguna herramienta ¿no?
Empresas que manejan proyectos muy grandes dan a este aspecto una importancia vital. Por ejemplo: Microsoft, en su equipo de desarrollo de Windows, tiene todo un laboratorio de construcciones diarias: un montón de servidores y personas responsables de que la compilación y las pruebas se ejecuten correctamente todos los días.

Bien, el modelo de integración continua, si no se hace con cabeza, puede traernos más problemas que ventajas.
Pongamos el caso en que tenemos un repositorio con nuestro código fuente. Nosotros usamos Subversion, pero valdrían otros como CVS, Source Safe, Perforce, etc. Cada vez que integramos un cambio en el repositorio, existe alguna posibilidad de que el programa deje de compilar (por ejemplo si hemos olvidado subir un archivo nuevo), o que hayamos generado algún bug, así que podemos decir que en ese momento, y hasta que se valide de nuevo, el repositorio está en estado inestable. Si hacemos que se lance una construcción cada vez que integramos algo en el repositorio, muchas de esas construcciones fallarán. Por ejemplo: todas las tardes, antes de irnos a casa, registramos nuestro trabajo, aunque no esté terminado, y muchas veces la construcción resultante no es válida. Pensad que esto lo hacemos todos los desarrolladores, así que a la mañana siguiente tenemos el repositorio lleno de bugs y en un estado caótico, y si ese mismo día necesitásemos entregar una versión, estaremos en apuros.

A continuación podéis ver el diagrama que representa esta situación:


Cada flecha es un cambio hecho en el repositorio, y como véis, algunos cambios desestabilizan el producto, bien introduciendo bugs o errores de compilación.

Para conseguir que la integración continua tenga su efecto beneficioso, tenemos que organizar el desarrollo en distintas ramas, o branches.
Para este modelo de gestión de la configuración tenemos varias opciones, aunque las más habituales son las siguientes:

Cada desarrollador tiene su propia rama de código, donde trabaja a diario, hace sus cambios, registra código, etc. Esa rama es privada, y podrá hacer lo que quiera con ella y mantenerla en cualquier estado. Lo habitual es que esa rama esté muy inestable al comenzar con una nueva tarea, y vaya ganando estabilidad conforme avance en el desarrollo.
En el momento en que el desarrollador termina con su trabajo, se compila una versión de esa rama y se pasa a pruebas. El departamente de pruebas validará la funcionalidad sobre la que ha estado trabajando el desarrollador, se reportarán los bugs oportunos, y cuando se de por correcta, se etiquetará esa rama y se integrará en el repositorio principal. En ese momento se lanza una construcción del producto de la rama principal, y se vuelve a pasar a QA el producto ya integrado, para validar que la integración ha sido correcta.
En este caso, hemos pasado a tener una funcionalidad más, reduciendo al máximo los tiempos de inestabilidad de la rama principal. Una vez que la rama principal se da por buena desde el departamento de QA, se etiqueta y se continua con la siguiente funcionalidad.
Podemos verlo representado aquí, y fijaros que la rama principal tiene muchas menos zonas en rojo:


Existe todavía otro modelo, muy parecido al anterior, y que consiste en tener una rama de desarrollo para cada nueva funcionalidad. El esquema es el mismo que hemos visto, donde los desarrolladores que trabajan en una misma funcionalidad lo hacen sobre una rama separada. La diferencia es que cuando la funcionalidad se da por terminada, se integra en la rama principal y esa rama queda muerta, teniendo que crear otra nueva para la siguientes funcionalidad.

Bien, como véis, es tema no es sencillo de gestionar, y requiere algo de infraestructura de por medio.
Yo os recomendaría que, al igual que se automatiza el proceso de construcción, intentéis hacer lo más automático posible la gestión de la configuración, teniendo scripts para la creación de ramas para desarrolladores, para funcionalidades, de integración en el principal etc.

Pero... ¿donde queda la integración continua en este jaleo de ramas? Pues en la rama principal, que es donde se registrarán los cambios definitivos y estables. No tiene sentido que intentemos compilar el producto cada vez que se cambie algo en una rama secundaria, ya que habrá muchos momento de inestabilidad. Así que cada vez que una tarea es dada por buena, se integrará en el repositorio principal y se construirá el producto final.

Y ya para poner la guinda al pastel, puedes poner un "ambient orb" en la oficina, para que todo el mundo vea el estado de la rama principal.

Automated Continuous Integration and the Ambient Orb
Using an Ambient Orb to show continuous integration build status
The Build Indicator Lamp

Nosotros no llegamos tan lejos, ¿y tú?

Etiquetas: ,


This page is powered by Blogger. Isn't yours?