js13k y Miss City (postmortem)

Desde el 13 de agosto hasta el 13 de septiembre ha tenido lugar la competición js13kGames 2015. El objetivo es construir un juego en HTML5, en el plazo de un mes o menos que no ocupe más de 13kb. EL fichero que no debe superar los 13kb debe ser un fichero ZIP con compresión estándar que tenga un fichero index.html desde el cual arrancará el juego y todo lo necesario para su funcionamiento estará también en el fichero ZIP. JavaScript, CSS, imágenes, sonido, fuentes, etc deberán estar en el fichero ZIP que no supere los 13kb. Está explicitamente prohibido cargar algún recurso del exterior como Google Web Fonts, CDNs de JavaScript, imágenes en otro servidor, etc. Además hay un tema para los juegos, que fue anunciado el 13 de agosto. El tema ha sido Reversed.

js13k

MissCity

MissCityGameplay

El juego que he presentado se llama MissCity. El nombre viene de darle la vuelta a Sim de SimCity. Mis no existe, pero Miss sí, y es perdido. Así MissCity es ciudad perdida.

Euralia es la ciudad perfecta. Nuestra compañía desea construir un centro comercial en un solar abandonado pero el actual alcalde desea constuir una biblioteca. Dentro de poco son elecciones. ¡Debemos ganar las elecciones! Para ello puedes usar nuestro dron y repartir diversos tipos de ataques publicitarios a la población

Los controles son:

  • WASD para desplazarse (si estamos en móvil o tablet, se usa la inclinación del dispositivo)
  • VBNM para los 4 diferentes tipos de ataque (si estamos en un dispositivo táctil, aparecen cuatro botones en pantalla que realizan el mismo efecto)

Ganamos:

  • Si conseguimos suficientes votos entre el electorado

Perdemos:

  • Si pasan dos minutos
  • Si nos quedamos sin dinero (cada ataque publicitario cuesta una cantidad de dinero sin especificar)

MissCityOpera

Vamos a ver el postmortem en profundidad

Cosas que fueron bien

PathFinding

Los habitantes de Euralia son inteligentes, no van de una casilla a otra porque sí sino que tienen una ruta que realizar. El origen y el destino sí se calculan aleatoriamente, pero la ruta no, se usa un algoritmo de pathfinding. Debía encontrar una librería sencilla, pequeña, pero que implementase el algoritmo de manera limpia. Finalmente elegí EasyStar.js que es asíncrona, sin dependencias y entre sus características asegura que es pequeña (~5kb) lo cual comprimido en ZIP resulta menos de lo que esperaba. Usa licencia MIT así que perfecto. El único inconveniente que presenta es que la rejilla que usa es bidimensional y yo definí la ciudad y el sistema de renderizado con un array unidimensional que voy cortando al procesarlo. Así que el juego tiene que transformar el array unidimensional en otro bidimensional para que EasyStar lo procese correctamente. Al obtener los resultados, es necesario volver a transformarlos.

Recursos gráficos

Creía que mi juego iba a tener peores gráficos, sinceramente. Las imágenes en formato GIF ocupaban menos de lo que esperaba y pude incluir bastantes detalles. Al principio no usé imágenes, tiré de colores en CSS. Renderizar toda la ciudad fue muy sencillo. Esta no es la versión final por supuesto, pero no es muy diferente.

Debug en Firefox para Android

Me lo esperaba peor y realmente con WebIDE, el cable USB y ADB es muy sencillo ver la consola de JavaScript de Firefox para Android en tu ordenador.

Problemas

MissCityFirefox

Dichosas APIs de pantalla y orientación

En HTML5 siempre me torturo con los aspect ratio y demás temas relacionados con la pantalla. En HTML5 hay tantas pantallas diferentes que simplemente no sé por donde empezar. El método que he usado en este juego es diferente al usado en otras ocasiones y daría para una entrada de blog suelta. Pero también me gustaría decir que las APIs de gestión de pantalla (saber si estás en modo landscape o portrait) no funcionan entre navegadores todavía. Incluso tienen nombres incompatibles que surgen de distintas versiones del estándar. Es una cosa que las aplicaciones nativas de móviles saben hacer desde el día 1.

EasyZIP

En MissCity he usado Gulp como herramienta que se encarga de la automatización de todo (ya sabes ¡haz scripts!). Usé EasyZIP para generar el fichero ZIP y posteriormente comprobar que su tamaño seguía siendo inferior a los 13kb. Mi sorpresa vino cuando al subir el fichero ZIP provoqué un error en el servidor de js13kgames. Tuve que contactar con el administrador, hubo que borrar archivos que se habían extraído correctamente en el servidor aunque hubiese devuelto un error. La solución fue comprimirlo manualmente con File Roller y el tamaño del fichero aumentó (sin pasar los 13kb).

API de gestión de teclado

Firefox recomienda usar KeyboardEvent.key para leer el teclado y marca como obsoleta la manera antigua, que era KeyboardEvent.keyCode. Leyendo MDN uno piensa que usando KeyboardEvent.key es la solución sin más. Y efectivamente en Firefox funciona bien, pero en Chrome y Opera no. Y pudiendo usar keyCode, quién va a usar key. keyCode será obsoleto pero funciona en todos los navegadores. Finalmente implementé el teclado usando key y keyCode si no soportan key.

Juega

Si has leído hasta aquí, es un buen momento para jugar a MissCity. Hay un premio por compartir en redes sociales, si quieres ayudarme ya sabes.

Código fuente: http://github.com/AdrianArroyoCalle/miss-city

eurocookie-js

Hace ya algún tiempo que la ley europea en materia de privacidad se ha venido aplicando en España. La ley define que no se pueden almacenar datos que identifiquen al usuario con fines estadísticos (o publicitarios) a menos que se pida un consentimiento al usuario y este lo acepte. Solo lo deben cumplir aquellas personas que tengan un beneficio económico con la web. En empresas hay que aplicarlo siempre. El almacenamiento más usado para este tipo de identifición han sido las cookies, de ahí el nombre popular de “ley de cookies”.

UnionEuropea

Odisea entre las cookies

Yo uso cookies. Las uso en este blog y en otros sitios. Google Analytics requiere consentimiento, Disqus requiere consentimiento, Google AdSense requiere consentimiento. Los widgets sociales de Twitter, Facebook, Google+, etc requieren consentimiento.

¿Pero entonces todas las cookies necesitan consentimiento?

No. Sólo las que identifican al usuario con fines estadísticos, que en el caso de los gigantes de Internet es siempre. Si usamos nuestras propias cookies y no las conservamos para posterior análisis no haría falta y no hay que pedir consentimiento.

Cookies

Cookies son las más usadas, pero si usas WebStorage (localStorage) o almacenamiento de Flash también tendrás que cumplir

eurocookie-js al rescate

Basado en un pequeño plugin hecho por Google bajo licencia Apache 2.0. Se trata de un pequeño fichero JavaScript que al cargarse pedirá el consentimiento (si no ha sido preguntado antes). Este consentimiento es molesto, forzando al usuario a aceptar si quiere leer cómodamente la web. Una vez acepta el consentimiento se carga todo el JavaScript que necesitaba consentimiento. Esto último es algo que muchos plugins de consentimiento de cookies no hacen. Realmente no sé si simplemente avisando se cumple la ley, bajo mi interpretación no. Y por eso este plugin. Además eurocookie-js está traducido a una gran cantidad de idiomas de la Unión Europea (tomadas directamente de las traducciones oficiales de Google para webmasters sobre esta ley). Vamos a ver como se usa.

Instalando eurocookie-js

Instalar eurocookie-js es más simple que el mecanismo de un botijo. Hay 3 maneras:

Biscuit

Usando eurocookie-js

Identificar JavaScript que necesita consentimiento

Primero, necesitamos identificar que JavaScript necesita consentimiento. Si usa una etiqueta script es fácil. Es importante declarar el tipo MIME del script como texto plano y le añadimos la clase cookie.

En muchos casos bastará, por ejemplo con Disqus o con Google Analytics, puesto que cargan asíncronamente los archivos. En otros casos donde usemos el atributo src de script tendremos que modificar el código que se nos provee por el siguiente.

Aunque si el proveedor te requería usar script src posiblemente no soporte la carga asíncrona.

Activando eurocookie-js

Ahora solo nos falta activar eurocookie-js. Es fácil. Al final, antes de cerrar body tenemos que añadir lo siguiente:

Si usamos Bower o el método manual

Si usamos npm + browserify

El fichero generado por browserify podrá ser añadido directamente al HTML.

Más información

Como siempre, toda la información está en GitHub: http://github.com/AdrianArroyoCalle/eurocookie-js

Tutorial de WiX (Windows Installer MSI)

Siguiendo la estela del tutorial de CMake hoy traigo el tutorial de WiX.

¿Qué es WiX?

WiX es un proyecto opensource destinado a producir instaladores de la plataforma Windows Installer. Windows Installer es la plataforma de instalaciones preferida por Microsoft desde que comenzó su desarrollo en 1999. Los archivos MSI son los instaladores genéricos que usa Windows Installer. Provee de un entorno más seguro para modificar el sistema al de un EXE tradicional por el hecho de que Windows Installer es declarativo, no imperativo. Windows Installer es transaccional, facilita el despliegue en entornos empresariales, tiene APIs (Windows Installer API y Windows Installer SDK), permite la localización de manera sencilla, la validación de instalaciones y la gestión de reinicios. Tiene los siguientes inconvenientes: es complejo, los accesos directos, su línea de comandos, su uso del registro y sus herramientas. Así pues con WiX podemos crear paquetes MSI de Windows Installer con unos ficheros XML donde definimos la instalación.

WindowsInstaller

También conviene diferenciar los diferentes tipos de archivos que soporta Windows Installer.

  • MSI | Instalador convencional
  • MSM | Módulo de fusión
  • MSP | Módulo de parche
  • MST | Módulo de transformación

No hay que confundir estos archivos con los MSU, también usados por Microsoft pero para Windows Update y cuya estructura es diferente.

Instalando WiX

Para instalar WiX podemos usar Chocolatey. Abrimos PowerShell como administrador y ejecutamos.

Si queremos añadir las herramientas al PATH, en PowerShell.

Herramientas

WiX viene con un conjunto de herramientas diseñadas para trabajar con Windows Installer.

  • candle.exe – Compila los archivos .wxs y .wxi para generar archivos objeto .wixobj
  • light.exe – Enlaza los objetos .wixobj y .wixlib produciendo el .msi
  • lit.exe – Permite unir archivos .wixobj en una librería .wixlib
  • dark.exe – Convierte un archivo ya compilado en código fuente WiX
  • heat.exe – Podemos añadir archivos al fichero WiX en masa, sin especificar manualmente
  • insignia.exe – Permite firmar archivos MSI con las mismas firmas que los CABs
  • melt.exe – Convierte un archivo MSM a un fichero código fuente de WiX
  • torch.exe – Extrae las diferencias entre objetos WiX para generar una transformación. Usado para generar parches.
  • smoke.exe – Valida ficheros MSI o MSM
  • pyro.exe – Genera un fichero de parches MSP
  • WixCop.exe – Recomienda estándares en los ficheros WiX
  • WixUnit.exe – Realiza una validación a los ficheros WiX
  • lux.exe – Usado para tests unitarios
  • nit.exe – Usado para tests unitarios

Nota: Vamos a necesitar generar GUIDs. En PowerShell podeis usar [GUID]::NewGuid() o [GUID]::NewGuid().ToString(). Si teneis instalado Visual Studio, también está disponible uuidgen

El fichero .wxs

El fichero WXS es la base de WiX y es un fichero XML. Para el ejemplo voy a empaquetar Lumtumo. Lumtumo contiene un ejecutable, varias DLL y varios archivos como imágenes y fuentes que están distribuidos por carpetas. He depositado la carpeta con los binarios y todos lo necesario en SourceDir.

Ahora se genera el archivo MSI

Este ejemplo básico está muy bien, instala todo, añade un icono en el menú de inicio (también se puede poner en el escritorio pero no me gusta), se integra con el panel de control para hacer una desinstalación limpia e incluso con modificar un valor podemos generar el paquete para 64 bits. Sin embargo faltan cosas. No se puede especificar la carpeta de instalación, de hecho, el MSI no muestra ninguna opción al usuario al instalarse. Para introducir GUI en WiX tenemos que usar la librería WiXUI.

WixUI

Para usar WixUI tenemos que cambiar el comando que usamos para llamar a light

Con esto ya podemos usar la librería WixUI. La manera más básica de añadir una GUI es introducir la GUI Minimal. Al final de la etiqueta Product podemos insertar

Y LICENSE.rtf en un archivo que tenemos junto a los ficheros WXS.

Si queremos un buen resultado visualmente hablando toca diseñar dos ficheros BMP.

Aquí uso la interfaz Minimal que lo único que hace es pedir aceptar la licencia e instalarse tal como habíamos visto antes. Hay más interfaces: WixUI_Mondo, WixUI_FeatureTree, WixUI_InstallDir y WixUI_Advanced. Todas ellas permiten más ajustes que WixUI_Minimal. También podemos crear ventanas personalizadas pero en mi opinión es algo a evitar. Las instalaciones deben ser lo más simples posibles y dejar a la aplicación en sí toda la configuración que necesite. Respecto a cambiar el directorio de instalación, no soy partidario pero si quereis la cuestión es sustituir LumtumoDir por INSTALLDIR (en hate.exe y en el fichero Lumtumo.wxs) y en la etiqueta Feature añadir Display="expand" ConfigurableDirectory="INSTALLDIR"

Bundle y Bootstrap

Un archivo MSI está bien pero quizá nos gusté más un EXE que además instale las dependencias.

Y compilamos

Y se genera el archivo setup.exe. Por defecto el archivo MSI se instala en modo silencioso por lo que la GUI pasa a ser la de Bootstrap.

Más sintaxis WiX

Registrar un tipo de archivo

Escribir configuración en archivo INI

Escribir en el registro

Borrar archivos extra en la desinstalación