De Homero a Kirby

Usted está aquí

Palabras desde otro mundo

Bajo un océano de bits, mes XI

El mes pasado dejábamos esto con una duda: ¿fuentes o testing?.
Y, la respuesta a esta pregunta es, como de costumbre, ninguna de las anteriores.

En su lugar me puse a mirar patrones de programación en C++ orientados a la creación de vídeo juegos.

Regresando a una de esas entradas que tenía empezadas desde hace años1 llegué hasta otros textos. Más concretamente hasta un libro2 que puedes comprar, leer online, o descargarte desde GitHub.

El libro está escrito en un tono desenfadado pero tengo con él el mismo problema que con otros tantos: No soy capaz de entender por completo los ejemplos de código que muestra.
Los textos que preceden a los ejemplos son interesantes, y puede entrever más o menos lo que se pretende con las muestras, pero no veo cómo integrarlos en mi código. Aparte de esto, no sólo se dedican a defender a lo suyo, sino que también hablan de las filias y fobias de su autor, algo que he visto que es muy común también en las entradas dedicadas a este tipo de temas en Wikipedia. Dependiendo de a quién leas cualquier cosa es buena o es una mierda.

Tras terminar con el tercero de los patrones que mencionaba este libro decidí seguir buscando más lectura acerca de aquel asunto fuera del este texto. Por un lado, el tema del encolado de eventos era algo sobre lo que ya había leído un poco, aunque de buenas a primeras se me hacía un tanto complejo de hacer con mi nivel actual. Por otro, creo que va a ser lo que me va a hacer falta a la hora de actualizar ciertas variables cuando implemente la pantalla de configuración, o a la hora de actualizar los datos de la clasificación de jugadores.

El concepto del Sujeto/Observadores se me hacía algo más sencillo que las colas de eventos, así que decidí profundizar un poco más… en ambos3.

Porque sólo con los ejemplos del libro se me veía capaz de terminar de entenderlo. Así pues, me puse a buscar otras implementaciones… sin erótico resultado. Aún estoy muy verde en esto.

Casi todas entradas hablan acerca de las bondades del polimorfismo y las clases virtuales4. Temas de C++ en los que aún no he profundizado y que me hacen pensar si debería retomar el libro de Stroustrup sobre la última versión de este lenguje.

Al final la decisión fue… lo habéis adivinado: No hacer ninguna de estas cosas.
Quizás cuando termine con el menú. Algo para lo que me queda ¿poco?.
No. No me queda poco.

Las últimas dos semanas me he dedicado a crear la clase que dibujará los textos en pantalla. Algo que parecía ser sencillo pero que no lo es. Creía tenerlo cuando me encontré con ciertas particularidades de las variables estáticas dentro de las clases a la hora de trabajar con Superficies de SDL (o, al menos, con SDL 1.2).

Si declaro la superficie de origen (donde “cargo” el texto antes de que sea pintado en pantalla) como estática, no se actualiza aunque el en el siguiente ciclo le envíe un texto distinto. Si no la declaro como estática el programa se autoinmola al rato como ya me hacía en su momento la animación del menú. La misma característica que me salvó en un caso me putea en el otro.
Una vez con esto claro, tengo que replantearme la manera en la que iba a almacenar el texto dentro de mis archivos JSON. De ser líneas independientes tengo que planteármelas como si todo el texto que va a ir rotando en pantalla fuese una única imagen. Un mural del que voy ir mostrando a recuadro a recuadro. Esto, claro está, siempre que no utilice otra biblioteca de funciones que no sea SDL6 para el pintado del texto.
Pero esto es algo que, por el momento, quiero evitar. Vamos a la vía dura.

Así pues, la cosa sigue más o menos como el mes pasado. Bueno, miento.

Ya he creado la pequeña clase que se encargará de pintar la pantalla de presentación previa al menú, la que se dedica a gestionar en qué modo de juego nos encontramos, y la dedicada a gestionar la reproducir de la música.
Estas tres clases no me costó demasiado hacerlas y todas ellas funcionan correctamente, aunque aún tengo que conseguir que se pase desde la presentación hasta el menú cuando se pulse cualquier tecla, botón del pad, o se mueva el ratón.

A pesar de que en las últimas entradas no he puesto nada a este respecto, también he seguido viendo vídeos de las GDC7, al igual que alguna que otra charla curiosa8 (que siguen haciendo que quiera ponerme a aprender ensamblador).

Esta semana también ha salido otro uso para el controlador de Microsoft para gente con discapacidades. En este caso para usarlo en la Switch9. Parece que aunque los grandes no se mueven demasiado se puede confiar en la comunidad.

Y más o menos esto es todo. A ver por qué derroteros me estoy moviendo cuando llegue la última entrada de este primer año para el reto computacional.

Enlaces:

1. Writing a Game Engine from Scratch I

2. Game Programming Patterns
- La web del libro
- Su ficha en goodreads
- Y su Github

3. Observador o colas de mensajes
- El observador (no confundir con el personaje de mis relatos)
- En Wikipedia
- Powerful C messaging/
- How to implement and use a message queue in your game
- Game programming tutorial messaging systems in C
- Publish–subscribe pattern
- Understanding and Implementing Observer Pattern
- Setting up msysmingw build system for compiling sdlopengl applications

4. Más cosas de C++
- Polymorphism
- https://en.wikipedia.org/wiki/Virtual_class>Clases virtuales

5. Estatismo del malo

6. GUI Without Extravagant Nonsense

7. GDC
- GDC 2018: Classic Game Postmortem: 'The Bard's Tale I and II'
- Classic Game Postmortem: Gauntlet
- GDC Classic Postmortem: Warren Robinett's Adventure
- The Journey to Creating SHANK
- Yars' Revenge: Classic Game Postmortem
- The Shapes in Your Story: Narrative Mapping Frameworks
- Girl Games of the 1990s: A Retrospective
- Classic Game Postmortem: Alone in the Dark
- Classic Game Postmortem - Raid On Bungeling Bay

8. Y amigos
- Renderizando tilemaps con scroll por software [GameDev asm Z80][5.4][2018]
- How we fit an NES game into 40 Kilobytes

9. Nintendo joins the limited-mobility club with Xbox Adaptive Controller (unofficially)

Bajo un océano de bits, mes X

Seguimos avanzando sin movernos del mismo lugar, cambiándolo todo sin que sea apreciable desde el exterior.

Datos. Necesito datos1.

Durante este mes me he centrado en sacar todos los valores que puedan ser utilizados en mas de un lugar fuera del código. Aparte de eso, el “contenedor maestro” que había creado para abarcar a todos los objetos se ha visto separado en cinco. Todo eso y poco más en esta edición de “Bajo un océano de bits” en su entrada más ¿técnica?.

Aún estoy dando pasos de bebé en esto de la programación en general, y el C++ en particular, pero estoy comenzando a “entender” estos lenguajes. Me estoy dedicando a jugar con ellos. Porque, por mayor que sea el misticismo que le queramos dar, la programación no deja de ser eso, otro idioma que tenemos que aprender a hablar, leer y escribir. Otra manera de describir las cosas.

Cuanto más profundizo, más claro tengo que es una cuestión de tiempo, práctica, paciencia, inventiva y objetivos acotables. Cuanto más básico es el nivel del código que leo, más me doy cuenta de que… tiene sentido. Que “eso habría sabido hacerlo yo”.
Si con el dibujo los engranajes de mi cabeza aún no han hecho “click”, parece que estos sí que van cogiendo velocidad.

Y es entonces cuando pienso que me estoy perdiendo algo. Que no puede ser tan sencillo. La historia de mi vida.

Pero la cosa es que muevo y reescribo, retuerzo las líneas en otro sitio y siguen funcionando. Que siguen haciendo lo que tenían que hacer (o al menos lo mismo que hacían cuando las describí de otra manera). Y eso hace que me sienta bien.

No dudo de que, hasta cierto punto, este no-avanzar de los últimos meses se debe a que he encontrado algo similar a una zona de confort, pero creo que lo que estoy haciendo tiene sentido. Tardaré más en ver resultados en la pantalla, pero tengo claro que los pasos llevan la dirección correcta.

Y claro, luego me pongo a leer más cosas y me doy cuenta de que, si quiero hacer las cosas bien desde el principio, voy a tener que esperar mucho más hasta que lleguen esos resultados y sean “visibles” (o jugables). No quiero empezar con pasos apresurados y darme cuenta a medio camino de que tenía que haber hecho algo distinto desde el principio.
No sé cuántas veces me han dicho que estoy tomando el camino difícil, pero yo no he venido hasta aquí a hacer sólo las cosas fáciles.

Quizás por deformación de mi trabajo en el día a día, sigo pensando en la arquitectura del programa a alto nivel. En tratar de desglosar los componentes de la forma más general, abstracta y óptima posible. De decidir a qué capa correspondería cada uno de ellos. En que todo lo que haga ahora sea reutilizable para cualquier cosa que pueda hacer después.

Dentro del nivel más básico de esta arquitectura que voy improvisando con cada nueva revisión, he situado los datos en crudo; lo que quiero que esté fuera del código. Un contenedor al que, en un alarde de originalidad, he dado en llamar “Datos”.

Para ello he creado una clase central a la que he llamado (redoble de tambores) “Acceso_datos”. Una clase que se basa en archivos de texto plano en el que iré insertando los valores que usará el programa y para cuya estructura he decidido utilizar JSON2

Por el momento Acceso_datos sólo tiene una función llamada “Leer”, que me devuelve los valores guardados en los archivos y los convierte en variables a utilizar por el código. Cosas de un amplio espectro que abarcan desde el idioma hasta la anchura de un rectángulo en el que voy a dibujar un sprite o la clasificación de los jugadores. Más adelante tendré que crear los métodos “Actualizar”, “Crear” y “Reiniciar”.

Nada más arrancar el programa, lo primero que hace es inicializar este contenedor, con lo que leerá cuatro archivos JSON con nombres tan genéricos como “datos_globales”, “datos_recursos”, “datos_controles” y “datos_clasificacion”.

Tras la creación de “Datos” le llega el turno al segundo elemento central que he creado. Algo que, en un nuevo alarde de originalidad, he bautizado como “Sistemas”. Este contenedor se encarga de albergar los objetos que hablan con los dispositivos de entrada y salida. Por el momento, dentro de “Sistemas” se instancian los objetos de otras dos clases; Pantalla y Controles.

Como ya digo, es el segundo objeto que se crea en el arranque del programa y, tras leer los valores que le proporciona “Datos”, inicializa los objetos “pantalla_principal” y “controles”.

Una vez hecho esto, procedemos a pasar al tercer gran contenedor; “Recursos”. En él, en estos momentos, sólo se inicializa el objeto “LOGO” de la clase “Imagen”, pero más adelante (cuando existan) será el encargado de albergar objetos de las clases “Fuentes”, “Sonidos”, “Música”.

Cada uno de estos objetos estará almacenado en vectores3 que se crearán dinámicamente a partir de la información del archivo “datos_recursos.json”. Con esto, una vez que tenga creadas todas las clases que aglutina, para meter un nuevo “recurso” no tendré que tocar para nada el código de este contenedor.

Para terminar tenemos el contenedor “Modos” (al que igual termino llamando “Presentacion” para que suene más parecido a la capa OSI que sería su homóloga). Los miembros de este contenedor utilizarán los objetos instanciados en los anteriores y, a su vez, instanciarán objetos de las clases “Presentacion”, ”Menu”, “Juego”, “Editor” y “Configuracion”.

De las clases que debe albergar “Modos” por ahora sólo existe “Menu” y aún se encuentra en un estado casi embrionario. Cuando cree la clase “Juego” también tendré que crear otra clase hijo a la que llamaré “Nivel”, pero aún no sé en que consistirá ninguna de las dos, así que tiempo al tiempo.

Aún me queda por definir el último contenedor que se debería crear. El que he dado en llamar “Motor” y que se ocupará de cosas como las físicas, detección de colisiones, animación (y otro montón de cosas con las que me pegaré cuanto toque).

Todo un berenjenal.

Últimamente tengo abiertos todos los archivos pertenecientes a las clases mencionadas y los archivos de datos que les corresponden. Esto significa que mis editores tienen abiertos de manera permanente cerca de treinta archivos entre los que navego. Cada vez que toco uno de ellos tengo que andar modificando alguno de alguno de los restantes, así que hay momentos en los que hago sufrir mucho al compilador con mis descuidos.

Hasta este mes no existía la parte de acceso a datos, y todos los demás contenedores se encontraban apretados dentro de uno que había denominado “Nucleo”. A priori esto resulta más sencillo, sólo tendría que tocar un archivo tocho, pero he preferido separarlos para que su estructura se parezca a algo que tenga un poco más de orden, sentido y estructura en mi cabeza. Hoy “Nucleo” era manejable, de aquí a un tiempo se habría convertido en un infierno (y en algo menos reutilizable).

El sacar los datos a los archivos JSON también me ha supuesto algún que otro problema adicional. En los archivos de cabecera podía definir los datos con el tipo que me de la gana, pero al importarlos desde fuera todos son cadenas de texto. Con ciertos valores, como las opciones de inicialización de la ventana la cosa se complica. Este valor, que en código puede ser una cadena de texto, por detrás hacía una conversión a hexadecimal, algo que no se puede (o no he conseguido) hacer directamente.
Tras analizar un poco el código de SDL he visto que donde yo ponía “SDL_HWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF”, él hacía tres sustituciones:

#define SDL_HWSURFACE 0x00000001 /**
#define SDL_RESIZABLE 0x00000010 /**
#define SDL_DOUBLEBUF 0x40000000 /**

Así pues, al final la cosa se quedaba como la suma de esos tres valores, ergo: 0x40000011 (que es el valor que ha quedado en el archivo de configuración).
A saber con cuántas más de estas me voy a encontrar.

Otra parte que me ha consumido bastante tiempo ha sido la generación dinámica de los vectores de “Recursos”. Algo que, si bien no era un requerimiento ahora mismo, sí que me facilitarás las cosas de cara a futuro.

Por otro lado, la parte de una posible traducción de los textos que aparezcan en pantalla, por el contrario, ha sido una de las más sencillas de implementar. Ahora sólo falta que no me olvide de poner los valores correctos donde toca en cada nueva clase.

Una vez conseguido todo esto, se me abren varios caminos. Podría plantearme el meterme en serio con las fuentes de creación propia4 o que empiece a mirar maneras ágiles de probar las cosas que hago5.
Cualquiera de las dos cosas me va a llevar bastante tiempo. Aunque creo que la primera será más rápida de solventar, la segunda me va a a aportar más en el largo recorrido y este es un buen momento para ponerme a ello.

No sé. Mañana me podré con ello.

Enlaces:

1. Más datos

2. JSON
- JSON en la Wikipedia
- Jsoncpp en Github
- Jsoncpp en WikiBooks
- Json Parser 1
- Json Parser 2

3. Vector

4. Dibujando texto y fuentes
- Text Imput
- Getting String Input (SDL1)
- Introducción de texto con SDL (SDL2)
- Text Input And Clipboard Handling (SDL2)
- SDL_ttf
- Ejemplo de implementación de SDL_ttf
- Bitmap Font Generator
- Bitfont Maker 2
- Unicode

5. Probando que es gerundio
- Test-driven development and unit testing with examples in C++
- Ten C++ Testing Tools for Developers to Consider
- CppUnit
- Google Test
- Boost.Test
- Catch2
- Bandit
- Cpputest
- TUT (C++ Template Unit Test Framework)

Bajo un océano de bits, mes IX

Y sin embargo se mueve...

Pues sí, tras cerca de tres meses de no ver por dónde me venían los golpes, parece que comienzo a ver la luz. Por supuesto, aún me queda mucho camino por recorrer, pero la salida de este túnel en concreto parece más cercana.

Ya tengo la animación del menú en funcionamiento, he logrado pintar un texto sobre una parte concreta de la pantalla y he conseguido cambiar el color de fondo de ese rectángulo cuando pulso una par de teclas concretas.

Lo sé, todo eso ya os suena, pero la novedad es que ese proceso ya no se come toda la memoria de mi máquina en cuanto lo arranco.

Desde el principio la parte de los constructores de clases se me habían atragantado, y tampoco terminaba de ubicar el estado de cada uno de sus miembros, pero esto es algo a lo que (creo que) ya les he pillado el punto.

Al final y, como de costumbre, contradiciendo a mis vaticinios del mes pasado me puse a mirar cómo se "debugea". Gracias a esto (y a Insight1) logré dar con la parte concreta del bucle en el que la memoria se me iba de madre.

Cómo no, aún estoy muy verde como para ser capaz de interpretar en su totalidad la información que me muestra el debugger, pero tiempo al tiempo.

Por otro lado, el solucionar el tema de la memoria no solventó otra clase de problemas que también estaban teniendo lugar en un segundo plano. Tras corregir esa parte el menú se me autoinmolaba cuando el bucle se repetía por vez número 1019.
La razón exacta detrás de este comportamiento concreto (el por qué funcionaba hasta ese momento) sigo sin saberla, pero sí que localicé el punto en el que se producía el error y lo corregí.

Gracias a los libros de “Aprende como si estuvieses en primero” he conseguido centrar algún que otro concepto que tenía difuso, y ha sido gracias a leerme cosa de cuatro veces la parte dedicada a los constructores que he obtenido la sensación de que voy entendiendo su función y funcionamiento.
Para tratar de confirmar mis teorías he dividido el programa aún en más archivos, cambiando de sitio objetos, punteros y funciones, y todo parece indicar que sí. Que sí que lo tengo.
Bien por mi.

Ahora ando dándole vuelas al pensamiento desacoplado y los patrones de programación. Esto es algo acerca de lo que supe hace tiempo en alguno de los vídeos las clases de programación en C++ del Profesor Retromán2 y que creo que ha llegado el momento de afrontar.
Gracias a esos vídeos también supe que puedo compilar una aplicación para Windows desde Linux3. Una cosa más sobre la que tengo que mirar, y otra capacidad más hacia la que evolucionar mi script de compilación.

Más allá de la teoría pura acerca de los patrones que puedes encontrar en Wikipedia4 hay bastante literatura a este respecto por ahí5, pero aún tengo que terminar decidirme por una lectura básica en concreto por la que comenzar.

Otra predicción incumplida fue la de Git. Ya tengo integrado Vim con el control de versiones, y también he logrado descifrar cómo configurar la parte servidora (algo con lo que comencé a pelearme hace mucho). No es que lo haya usado para gran cosa, pero es una cosa menos que tengo pendiente.

Por supuesto, este mes también he visto unas cuantas charlas de la GDC6, por donde han aparecido una conferencia que dio la gente detrás del Ultima Online (incluido Richard Garriott con su corona) contando un poco de su intrahistoria.

Tengo un poco abandonado el tema de la accesibilidad, y tampoco ha aparecido por mis blogs habituales nada relevante a este respecto. Menos mal que tengo amigas que se acuerdan de mi cuando leen sobre estas cosas. Si cuando leí sobre el mando adaptativo de X-box no terminaba de ver muy claro su valor, parece que hay gente que lo entendió bastante mejor que yo7.

Más sobre lo que leer, más sobre lo que investigar. Pero eso ya para la próxima entrada.

Enlaces:

1. insight
- Insight
- Insight FAQ
- Script para instalar Insight
- GCC - Options for Debugging Your Program
- Working with Insight, the Debugger Interface
- Cgdb

2. Clases de Programación en C++

3. Compilación en/para Winows
- MinGW: A native Windows port of the GNU Compiler Collection (GCC)
- GCC Mingw

4. Patrones de diseño
- Design pattern
- Abstraction layers
- Facade (fachada)
- Abstract factory
- Singleton
- RAII (Resource acquisition is initialization)

5. C++ Programming (Wikibooks)
- Versión Wiki
- Versión PDF
- C++ Programming: Code patterns design
- Repaso a C++11 en Genbeta
- L-Values y R-Values
- Referencias a un R-Value
- Moviendo objetos no copiables
- Tipos automáticos
- El principio RAII y los cuatro miembros implícitos

6. GDC
- How to Find and Engage a Great Artist: A Non-Artist Primer
- Designers Are from Saturn, Programmers Are from Uranus
- Classic Game Postmortem: Ultima Online

7. El controlador de X-box en acción

Tirando tinta 2018

Interrumpimos la programación habitual para informar a la audiencia de que ha comenzado el Inktober 2018.
Y empieza con malas noticias. Me entero de que hoy mismo nos deja el gran Carlos Ezquerra1, así que he decidido comenzar con un homenaje a su personaje más popular.
Como de costumbre, no estoy contento con el resultado y es ya tarde para corregirlo, pero es lo que tiene la tinta.
Más allá del casco y los detalles, no me gusta el mentón, pero claro, es que nadie dibuja los mentones como Ezquerra.
Mañana seguiré con un homenaje a Norm Breyfogle2 que nos dejó hace un par de semanas. Después de esto iré viendo las obras de qué autores voy a ir maltratando.

Podréis acceder a lo que vaya haciendo desde la galería de imágenes que he creado3. Algo que, si no la he cagado a la hora de entender cómo funciona el módulo que he instalado, se debería actualizar automáticamente en cuanto suba cualquier nueva imagen.

Más adelante, y si esto funciona como promete, ya veré cómo voy estructurando el histórico de mis dibujos para publicarlos por aquí.

Enlaces:

1. Carlos Equerra

2. Norm Breyfogle

3. Galería de Inktober 2018

Bajo un océano de bits, mes VIII

Lo que empezó siendo un único archivo de código, y el mes pasado se convirtió en tres, a día de hoy son ya más de media docena. Todo para conseguir hacer un poco menos de lo que hacía el primero.

Y, aun así, pese a seguir más o menos en las mismas, cada vez vamos logrando que sea un poco “más” que “menos” que el mes pasado.

La sensación general es la de que no hay avance. Seguimos tratando de terminar de pintar el menú, sólo que ahora con clases, constructores y objetos diversos. Pero sí que los hay. Es lo que tiene la perspectiva. Si miramos los resultados desde fuera, pueden parecen retrocesos, pero poquito a poco van las piezas van encajando. Hace falta tener al mismo tiempo la visión global y la de detalles para ver cómo ha cambiado todo.
Por supuesto, esto no evita que siga dando bandazos.

Voy avanzando en el análisis, comprensión y reescritura del código del juego de Antonio García Alba. Cogiendo pequeños pedazos de su código, adaptándolos a lo que busco de acuerdo a lo que entiendo de él, y dándome de cabezazos una y otra vez contra el muro de mi ignorancia.
Mas no importa1.

Sigo buscando webs y libros que me ayuden a aclarar los conceptos más básicos que me faltan2. Desde el tour llegué hasta el libro de Bjarne Stroustrup, el papi del C++, y empecé con él. Pero no era lo más adecuado para mí.
De ahí iba a pasar a los “Piensa en C++”, pero aparecieron en mi camino los textos de “Aprende como si estuvieses en primero” de la Universidad (Privada) de Navarra, que son con los que estoy ahora.

Una versión previa de estos textos ya me habían aparecido por otras partes, y están bastante extendidas, pero he preferido dejar el enlace a los últimos (que tampoco es que sean lo más moderno del mundo). Ambos tienen una marca de agua de su facultad, pero al César lo que es del César. La atribución se le tiene que hacer a quien corresponde.

Por supuesto esto no es lo único que he hecho durante este último mes a este respecto y sigo buscando información acerca de cómo integrar Git y GDB con VIM. Más adelante me meteré también con Make.

He encontrado un par de cosas a este respecto3 que aún no he probado, pero en algún momento me tendré que poner a ello. Cuanto más crezca el código más necesidad tendré de una herramienta para poder cazar bichos y errores. Por un lado, la opción de ponerme a insertar “std::cout” tras cada línea no es muy óptima para saber en qué momento está petando la cosa. Por otro, me dedico a mantener código comentado por todos lados para conservar las cosas que funcionaban antes de ponerme a separar las funciones, lo que no deja de ser otra guarrada que manda a paseo la legibilidad del código.

Pero si me meto con esto tengo claro que perderé mucho tiempo cacharreando. La investigación para hacerlo funcionar por primera vez es divertida pero, una vez superada esa fase, cada nuevo paso requiere de mucho más tiempo para entender realmente lo que estoy haciendo. No es que sea menos divertido, todo lo contrario, pero mientras dedico tiempo a eso (lo divertido) mi casi nulo avance se ralentiza aún más (porque el poder de la frustración es poderoso).

Supongo que me pondré a ello cuando termine con el menú, pero no voy a ponerme a hacer predicciones acerca de cuándo llegará ese momento, porque siempre he sido nefasto en esos menesteres.

También ha habido vida más allá del código. Pequeños momentos de ver cómo les ha ido esto a otros.
Cómo no, hemos tenido charlas de la GDC4 y ha aparecido algún que otro pequeño atisbo de desarrollo orientado a la accesibilidad5. No sé muy bien a través de quién (quizás gracias a las recomendaciones de mi página principal) llegué como por arte de magia hasta el canal de Youtube de Dan Root6 del que puedo sacar ideas para cuando llegue el momento de “mi” juego.
También sigo buscando cosas acerca de Hyper Light Drifter y Transistor7. Dos juegos que, si bien no encajan con lo que quiero que sea el mío, me parecen auténticas bellezas y obras de las que sí que puedo extraer lecciones acerca de narrativa dentro del juego.

Como no podía ser de otra manera, también he realizado infinidad de visitas a Stack-Overflow y otros foros similares, pero no veo que aporte demasiado el listar por aquí todas las indicaciones que me han ayudado a solventar problemas concretos que me van ido saliendo a lo largo del camino.

Y… no hay mucho más que contar.
Nos leemos de nuevo en cuatro semanas.

Enlaces:

1. Shen Comix me sigue representando (a veces)
- Hablando del Diablo
- Actitud positiva I
- Actitud positiva II
- El muro

2. El camino de C++ es complejo
- A Tour of C++
- Bjarne Stroustrup
- The C++ Programming Language
- Thinking in C++, Volume One: Introduction to Standard C++
- Thinking in C++, Vol. 2: Practical Programming
- Aprenda c++ como si estuviera en primero
- Básico
- Avanzado

3. Más cosas para Vim
- vim-fugitive
- Conque-GDB

4. GDC
- Tech Toolbox for Game Programmers
- Learning from Our Mistakes: A Postmortem of Guacamelee!
- Empowering the Player: Level Design in N++
- How We Created Mark of the Ninja Without (Totally) Losing Our Minds
- Cuphead's Animation Process and Philosophy
- Owlboy: The Evolving Art of a 10 Year Project
- Game a Week: Teaching Students to Prototype

5. La accesibilidad
- Serie de vídeos con consejos de diseño sobre accesibilidad en videojuegos
- Game Maker's Toolkit explores how devs can design for colorblindness

6. Dan Root
- Su canal
- The Importance of Key Frames // Run Cycles
- The Animation of Wonderboy: The Dragon's Trap
- Fez's Animated Environments

7. Hyper Light Drifter y Transistor
- Hyper Light Drifter - Trailer
- Hyper Light Drifter - Applying 3D Level Design Skills to a 2D World
- Hyper Light Drifter - From Kickstarter to Release
- Hyper Light Drifter - The Sound of
- Hyper Light Drifter - The Sound and Music
- Transistor - Launch Trailer
- Transistor - Reveal Trailer
- Jen Zee en DeviantArt
- Galería de imágenes de Transistor

Bajo un océano de bits, mes VII

Lentamente pero con paso firme (y frases hechas) continuamos avanzando y extendiendo esto. Porque al ponerme a picar código se me había olvidado que tenía por ahí la idea de no limitarme a C++ y hacer también algo con Python1 (para quien también está disponible SDL).
Dicho y hecho, ya logré crear mi ventanita con un gráfico en SDL1, SDL2, SFML, OpenGL y PySDL.
Una vez conseguido eso, tocaba pensar en los siguientes pasos. Más concretamente dos de ellos; Las animaciones y la estructura /claridad /reutilización del código.

Hasta el momento estaba trabajando con un único archivo pero, sólo con lo que llevaba, ya estaba empezando a ocupar mucho. Cada vez que tocaba algo para hacer una prueba era un tanto complejo el acotar dónde empezaba una cosa y terminaba otra.

Así pues, y volviendo a curso de SDL como referencia, he tratado de definir las clases que me puedan ser necesarias. Esto es, analizar con un poco más de experiencia sobre mis hombros lo que aparecía en el juego de ejemplo, y comenzar a escribir con mis propias palabras y estructura mental las agrupaciones de funciones.

Por el momento tengo dos clases: Pantalla y Controles, pero Pantalla ya ha crecido y voy a ir dividiéndola en otras subclases como puedan ser las generación de imágenes o fuentes. Para terminar con el bucle del menú también tengo que crear otra clase para los sonidos, pero esto no cae dentro del paraguas de “lo que se muestra en el monitor”.

Ya he conseguido recrear la animación del logo del Traz con SDL. Lo he hecho de tres maneras distintas, lo que me ha ayudado a entender algunas de las estructuras gráficas de esta biblioteca2; las superficies, los rectángulos y el “blit”. Cosas que no terminaba de entender sólo con su lectura.

Entre tanto, también he dado con una herramienta que me permita extraer los gráficos de un disco virtual de Commodore3, aunque aún me quedan cosas por terminar de centrar. No he logrado encontrar la ubicación de todos los gráficos y las fuentes o el logo no las he visto por ningún lado, así que para lo que he hecho he seguido utilizando los pantallazos que saqué el mes pasado. Las fuentes me las tendré que hacer también desde cero.

Por otro lado, de los gráficos que sí que he extraído no todos ellos parecen tener la proporción que se muestra en el juego, así que asumo que utilizaron algún truco de código para cambiar esa proporción. Pero al menos sí que tengo a mi disposición las animaciones de los enemigos.
Tampoco he visto dónde se encuentran los sonidos, pero eso no será demasiado difícil de sacar del emulador, ya que permite grabar el audio de las partidas a mp3.

Para llegar hasta este punto he vuelto a retomar la lectura de cosas relacionadas con el Commodore4, algo sobre lo que hay todo un mundo ahí fuera. También he encontrado que hay diferentes versiones volcadas del Traz volcadas por la red5, una de las cuales incluye la imagen de carga del juego. Otra cosa más a incluir.

Como el Pisuerga pasa por Valladolid, también he llegado hasta lugares sin relación aparente con el tema, pero igualmente interesantes. Lugares como estos en los que te presentan el proceso de creación de un emulador de GameBoy6. Web a las que igual vuelvo dentro de un tiempo.

Y han llegado las vacaciones. El asueto del trabajo remunerado pero no de los deberes autoimpuestos.
Durante estos días he continuado con todos los retos que tengo activos, aunque he de reconocer que con un ritmo un poco menor. En tirar de los datos del móvil ha hecho que racione un poco la búsqueda de soluciones a los problemas con los que me he ido encontrando, pero he ido derivando parte del tiempo a la lectura de temas relacionados. Materias como pueda ser el funcionamiento de la propia máquina7.

Porque este es un tema muy importante. Algo que me debería ayudar a ganar perspectiva y que, como de costumbre, provoca que quiera profundizar más. Otra cosa que también consiguen estos viajes al pasado es confirmar lo que sólo asumes. Ratificar esa gran verdad que afirma que todos los conceptos que los “visionarios” afirman “inventar” o “descubrir” en la actualidad ya estaban ahí desde hace mucho.
Quizás su presencia adopte formas más toscas y complejas, quizás los hombros de los gigantes sobre los que viajamos sean tan anchos que a veces no somos capaces de ver dónde terminan, pero desde la posición adecuada puedes ver todo el panorama.

Y más o menos esto será todo por hoy. Aún tengo pendiente el tema del escalado de los gráficos con SDL1, pero parece que puede haber una vía8. La probaré cuando tenga ya listos todos los elementos de la pantalla de inicio.

Enlaces:

1. PySDL2
- Crear una ventana con PySDL
- Sprite, texture and pixel surface routines

2. SDL y los gráficos
- SDL_Surface
- SDL_Rect
- SDL_BlitSurface

3. Extrayendo gráficos de un Snapshot de C64
- SpritePad
- Exporting sprites via vice and spritepad

4. Leyendo sobre el Commodore
- Ripping sidtunes
- N0STALGIA C64 TOOLS
- Working with Maps, Tiles, Chars and Compression
- C64 Sprite / Charset Ripper
- Graphics Extractor and Inserter
- Spritemate - browser based sprite editor for the Commodore 64
- Spritemate - browser based sprite editor for the Commodore 64
- C64 Sprites
- How "oldschool" graphics worked Part 1 - Commodore and Nintendo
- How "oldschool" graphics worked Part 2 - Atari and Apple
- CGA Graphics - Not as bad as you thought!

5. Traz en CSDB
- Búsqueda general
- Ficha general
- TRAZ +7DH

6. Emulando Gameboys
- Writing a Game Boy emulator, Cinoop
- BGB (GameBoy emulator/debugger)

7. Libros y más cosas sobre el Commodore
- Anatomy of the Commodore 64
- Supermon
- Entrevista a Jim Butterfield
- Supermon en Github

8. Escalando gráficos
SDL - Pixel Access
SDL - Scale Surface

Daegon, mes XXX

Como he ido anunciando a lo largo de todo el último mes, una vez alcanzado el número Diesel comenzamos con la despedida.

Parece que fue ayer cuando...
No es cierto, parece que fue hace cien vidas.

… comencé con este reto1. Y no me refiero e este último, sino al momento en el que decidí que sí, que Daegon merecía la pena a por más que me pesase, por más que todas las señales pareciesen indicar lo contrario.
Y aquí sigo. Cien vidas después, cien Javis después, acurrucado en mi nicho juntando palabras y negándome a aceptar la derrota a pesar de que tengo claro que no lograré ganar. Luchando por algo que me importa.
Porque, como no me canso de repetir, soy increíblemente tenaz y competente a la hora de darme de cabezazos contra los muros.

Más no importa.
Porque en las horas bajas todo es una mierda, y ha habido muchas de esas, pero esas horas son una parte necesaria e inevitable del viaje. Son momentos que también me han servido para mejorar. Para reflexionar, pero no para tomar decisiones… casi siempre. Porque las decisiones que he tomado en esos momentos casi siempre han sido erroneas.

Recordad amigüitos: Cuando vayáis a mandar algo a la mierda, aseguraros antes de que ese no es el lugar en el que te encuentras en esos momentos.

Así pues, y por si esto me puede estar quedando ambiguo, lo recalco: El reto, “La experiencia Daegon” seguirá, pero esta sección muere.

A estas alturas me gustaría encontrarme en otro punto en la evolución del proyecto, pero si algo ha quedado demostrado a lo largo de estos dos años y medio, es que mi capacidad de realizar predicciones no vale gran cosa.

¿Seré capaz de terminar con el libro básico antes de que termine el año?
Ni pajolera idea.

En estos momentos parte introductoria ya ha alcanzado las ochenta y siete páginas, y la respuesta a ¿Qué es Daegon?, cuando aún no está terminada, ocupa más de la mitad de ellas. Soy un hacha en esto de la concreción.
Me habría gustado cerrar esta etapa habiendo finiquitado esta sección pero… eso, se empeña en seguir creciendo. Ha crecido tanto que, muy probablemente (por más negado que sea en este arte, no dejo de hacer vaticinios), acabará dividida en dos partes distintas:

O igual no, ¿yo qué se?
Hasta que me he puesto a escribir esto iban a ser tres las divisiones, pero mientras avanzaba lo he recudido a dos, aunque sigo dudando. Todo muy yo.

No me gusta poner entradas en la web que sean superiores a veinte páginas en el editor de textos y la primera de ellas ya supera esa cantidad, así que convendría reducirlo pero, por otro lado, me parece que corte por donde corte la cosa quedaría como un pegote… salvo que vuelva una vez más al principio y lo estructure de otra manera.
La decisión, en este momento y lugar es que la cosa se quede así, pero todo se andará.

También tengo claro que para primeros de agosto, cuando vaya a las TdN, tampoco tendré cerrada esta sección. No es que tuviese intención de arbitrar nada allí, o de hacer SPAM por el lugar, pero habría sido un hito de esos estúpidos e inútiles que me gusta alcanzar.

Aún recuerdo la anterior vez que me pasé por estas jornadas allí por dos mil doce. Cuando me planteé que, si me ponía las pilar, para las del año siguiente podría tener escrito el material suficiente para hacer una presentación y, de haber alguien interesado, indicarle dónde podría encontrarlo y usarlo.
Entonces andaba buscando ilustradores. Había apartado dinero para pagarles y mandado correos a unos cuantos pidiendo presupuestos y también había enviado y pagado a un corrector para que revisase los primeros textos. En definitiva, me estaba planteando muy seriamente el sacar un libro.

Voz del narrador: No lo consiguió.

Y así siguen las cosas. El libro ya lo he descartado, no he conseguido encontrar a un ilustrador que tenga mi misma pedrada y los textos que me corrigieron ya ha sido reescrito desde cero.

Pero seguimos avanzando y retrocediendo. Juntando letras y alumbrando ideas que me reformular preguntas. El proyecto me sigue emocionando cuando pienso en él y cabreando cuando lo plasmo.
El ciclo sin fin que decían nosédonde.

3Mientras tanto, la espiral sigue y sigo peleando contra el miedo a un mundo opaco. Porque esto es mucho más que la nostalgia, mucho más que un recuerdo. Es una victoria en potencia, algo que me permite tomar aire, que me permite saber que sigo vivo, que me hace revelarme contra un universo injusto y mandarlo a paseo.

Tened por seguro que continuará.
Volveré.

1. I wanna make art, but i don't know how to get started

2. Tierra de Nadie

3. Pista oculta - Banda sonora
- Tool - Lateralus
- Porcupine Tree - Fear of a Blank Planet
- Hoobastank - More Than A Memory
- Wolfmother – Victorious
- Sia - Breathe me
- Lisa Minkovsky - Still Alive
- Lily Allen - Not Fair
- Lily Allen - Fuck You

Bajo un océano de bits, mes VI

Llegó el momento de lanzarse a la piscina; ergo he empezado a tirar líneas de código.
No es que me sienta especialmente preparado para ello, pero tengo la impresión de que leyendo sin más no voy a lograr llegar mucho más adelante. Cosas mías.

Tras continuar con mis búsquedas, por fin logré dar con los materiales completos del curso de Antonio García Alba1 detrás de los que andaba el mes pasado. El enlace a ellos que aparecía en la primera versión de la wiki que encontré (OSL2) estaba mal, pero no fue muy complicado adivinar cuál podía ser la url correcta.
Aun así, y mientras buscaba más información acerca del autor, a través del repositorio de proyectos de fin de carrera de su universidad llegué hasta otra wiki con ese mismo material. Vista la fuente, a partir de ese momento asumí que esa era la web oficial y con la que continué.

Pero la cosa no ha terminado muy bien. Una vez finiquitada la parte más descriptiva del libro, las últimas ciento y pico páginas están dedicadas a un caso práctico, lo cual está muy bien, pero...

Esta sección está centrada en explicar el proceso de creación de un juego de principio a fin, empezando con la parte más organizativa y terminando con el código completo. La primera parte, a pesar de ser un tanto pesada era comprensible, la teoría es lo que tiene, lo aguanta todo, pero una vez superada esta llegó el batacazo.

Porque, a pesar de tener el código, de ser capaz de compilarlo, y de lograr que me desaparecieran algunas advertencias debidas a métodos obsoletos de C++ que usaba (no olvidemos que el curso es de 2008), no he sido capaz de “leer” el flujo interno de cada una de las clases y objetos que creó. Y esto es un problema.

En la sección ligada a código del juego el foco está centrado en tratar de explicar algunas de las decisiones de diseño que se han tomado... y son decisiones que no acabo de entender. No se trata de que yo las habría afrontado de otra manera (que sin duda será lo que haré), sino que la forma de abstracción que ha elegido es demasiado… abstracta para mi.
Al final la programación consiste en eso, en realizar abstracciones. En buscar otra manera de observar el mundo real y modelar un caso de forma que lo entendáis tanto tú como el ordenador. Y la manera en la que ha planteado el juego el autor se me hace muy difícil de seguir. No se trata únicamente de que los mecanismos lógicos por los que ha optado me resulten demasiado abstractos, sino que tampoco soy capaz de aterrizar lo que explica a través de la lectura del propio código.

Me falta una base muy seria en cuanto a la programación estructurada en general, y la programación orientada a objetos en particular (por no hablar de C++).
Comencé mirando cada comando, cada “include” y cada función en la web2, pero esto no me hacía entender el conjunto. Demasiados detalles entrelazados, demasiadas cosas por probar y entender sin tener claro el contexto para el que han sido creadas.

Así pues, toca ignorar el vértigo, empezar a ensuciarse las manos y equivocarse mucho. Toca hacer, que es la única manera que sé de entender.

Pensando sobre el asunto me ha dado por darle vuelta a la expresión de "tirar" líneas. No sé si la primera persona que lo utilizó quería decir "arrojarlas" sobre la pantalla o la CPU o, como lo hago yo, tirar línea tras línea a la papelera de lo inservible.
Vaya, como en Daegon.
En fin.

Porque sí, apenas he empezado y con cada revisión se va mucho más de lo que había en origen.

Claro está, es muy probable que mi nivel de madurez programática tenga mucho que ver en esto. Que estoy muy verde.
Al menos eso espero.
Me queda año y medio para descubrirlo.

Haciendo caso a una de las alternativas que me planteé en los comienzos de este reto, no voy a lanzarme directamente a por "mi" juego, sino que empezaré rehaciendo desde cero uno que ya existe. A escribirlo utilizando mis propias palabras.

Con esto espero no desviarme de la parte pura del aprendizaje con temas de diseño. Conociéndome como me conozco, sé que me iba a empezar a centrar en los asuntos que me resultan más interesantes o cómodos y lo otro iba a quedar en un segundo plano. Ya habrá tiempo para eso. Por ahora empezaremos analizando otro. Teniendo un objetivo concreto que reflejar.

Así pues, voy a empezar con un clon del Traz de Commodore 64, que no deja de ser una evolución del Arkanoid, que no deja de ser una evolución del Breakout de Wozniak (que no Jobs) para Atari, que no deja de ser una evolución del Pong, que no deja de ser una copia del Tennis de la Magnavox, que no deja de ser una evolución del Tennis for two “programado” en un osciloscopio en el 583.
Y hago esto porque es un juego que siempre me gustó, porque parece una idea en apariencia sencilla y asequible, porque tiene un editor de niveles y porque... viejunismo.

En paralelo a todo esto también he comenzado a buscar a las personas que desarrollaron el juego original para pedir su beneplácito a la hora de usar las ideas, gráficos y música que ellos crearon, pero la cosa está complicada.

Por lo pronto he empezado a extraer los gráficos a partir de un emulador de Commodore. Esto no se limita a los "Tiles" en sí mismos, sino también a cada uno de los frames de animación. Un coñazo, pero algo mucho más sencillo y rápido que hacerlos yo desde cero.
Tengo pendiente mandar correos a la gente que anda metida en el desarrollo retro para indagar acerca de la posibilidad de extraer esta información desde el binario de la versión original, pero no tengo muchas esperanzas sobre ello. Lo máximo que he logrado por el momento ha sido sacar un volcado en ensamblador y hexadecimal del archivo "prg" gracias a Droid D644, pero tener eso es lo mismo que no tener nada.

Ya que estábamos, también he buscado varias implementaciones de Arkanoid hechas con SDL5 para ver si saco ideas pero, como de costumbre, queda mucho para que sea capaz de entender la totalidad de su código.

Pero dejémonos de dar vueltas, y vayamos a lo concreto. Despiecemos esta cosa y vayamos por partes.

Objetivo inicial:
Crear cuatro versiones del juego cada una de ellas con una biblioteca de funciones distinta.
Estas bibliotecas serán:

SDL 1.2
SDL 2
SFML
OpenGL (… ya veremos)

Como no quiero limitarme a aprender a utilizar una API, me lanzo a lo bruto. La parte puramente programática será común, pero la forma en la que se pintan los gráficos, se utiliza la música o se interactúa con los los dispositivos de entrada me las tendré que currar con cada una de ellas.

A grandes rasgos, el programa completo tendrá tres bucles:

1. Menú de selección.
2. Editor de niveles.
3. Juego.

Ahora mismo me estoy centrando en el primero de esos bucles el cual, a su vez, está dividido en otros tres bucles menores.

Casos de uso del Menú.

- Primer bucle

Al arrancar el programa suceden dos cosas:
Se muestra una pantalla con el menú.
Suena una canción.

Gráficamente el menú consiste en tres bloques:
El fondo.
Centrado en la parte superior tenemos el logo, que tiene una animación propia (39 pasos distintos de animación, de los cuales no sé cuántos frames debería ocupar cada uno).
Centrado en una franja marrón de la parte inferior tenemos una rotación de textos (Programador, grafista, músicos, y TOP 10 jugadores)

- Segundo bucle

Cuando se pulsa cualquier tecla la parte inferior da inicio el segundo bucle, y cambian dos cosas:
El ciclo de textos se detiene para ser sustituido por el menú de selección.
Se puede interactuar con él.

En esta interacción se puede seleccionar entre las 3 opciones que da el menú:

- Un jugador
- Dos jugadores
- Editor de niveles.

- Tercer bucle

Una vez que se ha terminado una partida se vuelve al menú.
El programa te dice que has logrado una puntuación digna de estar dentro del Top 10.
Se muestra un cursor para que el jugador introduzca su nombre. Este cursor aparece en la franja inferior, pero el color de esta franja no es marrón sino azul.
Se actualiza el Top 10 que se muestra en el primer bucle con ese valor.
Se vuelve al primer bucle.

Y hasta aquí puedo leer por el momento. Una vez que consiga hacer funcionar esto, "lo fácil", me pondré con el siguiente bucle (aunque sí que tengo una idea general de lo que me espera).

De todo lo descrito por ahí arriba, por ahora sólo he conseguido pintar un rectángulo sobre la pantalla y que esta muestre una imagen estática que tengo almacenada en el disco duro.
A partir de ahí comienzan los problemas.

Porque quiero que ese rectángulo sea escalable.
Con SDL 1.26 he conseguido que el rectángulo pueda cambiar de tamaño, pero no que la imagen que se encuentre en interior le acompañe.
Aparte de esto, esta librería me ha dado un problema adicional: Si no controlas los tiempos de refresco de pantalla se zampa todos los recursos de la máquina.
He conseguido paliar esto parcialmente, pero aún me queda para terminar de entender todo el proceso.

Por si con esto no fuese sucifiente, a la hora de cambiar el tamaño de la ventana también me hace cosas raras. En fin, es una biblioteca de funciones algo vieja, pero se han hecho cosas interesantes con ella, así que yo no seré menos.
Por más que me requiera más trabajo también me resulta la más interesante. Por un lado es en la que está basado el curso que he leído y, por otro, al ser más básica también “ofusca” menos cosas que las demás. Tengo que entender mejor lo que estoy haciendo, así que me quedo con ella.

Con SDL 27 he conseguido que, si defino un multiplicador al tamaño inicial del rectángulo, este también se aplique a la imagen, pero si cambio el tamaño de la ventana de manera manual tengo el mismo resultado que con la versión previa (pero sin los raros).
Espero que cuando termine de entender el segundo enlace pueda finiquitar esta parte.

Con SFML8 he conseguido que haga ambas cosas y es con la que menos código he usado. Por un lado, guay, por otro, casi todo es totalmente opaco.
Quizás cuando entienda todo lo que sucede por detrás me decante por ella, a fin de cuentas es la biblioteca más nueva, sobre la que más documentación y libros he encontrado, y la que parece más sencilla de usar.

Con OpenGL9, tras mucho buscar, también he conseguido que lo haga todo... aunque ha sido "tuneando" uno de los ejemplos de Lazyfoo. Un ejemplo bastante complejo cuya lógica aún no he terminado de pillar que, de premio, me da un warning al compilar.
Funciona, sí, pero tengo que entender el por qué y arreglar ese mensaje de alerta.
Antes de llegar hasta este punto había conseguido crear el rectángulo escalable con facilidad, pero no hubo manera de lograr que pintase nada en su interior.

OpenGL es con mucho la más clásica de las bibliotecas que he usado, pero su filosofía no tiene nada que ver con la de las otras tres. Tira mucho de otras bibliotecas externas para otras funcionas auxiliares como la carga de gráficos (de las que probé con libpng, SOIL y STB) y todo se vuelve un poco cristo.
Al final la cosa ha quedado funcionando con DevIL, la que se usaba en el ejemplo, pero tengo la impresión de que esto va a ser lo que más me retrase, así que no sé si llegaré a mandarla a paseo antes de terminar.

Y creo que ya vale por hoy. Como broche final diré que la Fundeu acepta el vocablo “Renderizar”10, lo que me ha dejado un poco loquer, pero bueno, hay que modernizarse. Igual cualquier día de esto aparece en uno de esos diccionarios de la RAE que están regalando.

Enlaces:

1. Repositorios de la Universidad de Cadiz
- Proyectos de fin de carrera
- Wikis – UCA: Ejemplo de la creación de un videojuego
- Wikis – UCA: Ejercicios del curso
- OSL2 – UCA: Ejemplo de la creación de un videojuego
- OSL2 – UCA: Ejercicios del curso

2. La C con el ++
- la STL - Standard Template Library
- Programación en C++ - Objetos y Clases
- Repaso a la stl, introduccion a los contenedores
- C++ Punteros y referencias
- C++ Map
- Headers and Includes: Why and How

3. Tennis for Two y sus clones
- El original
- La Magna disputa
- La causa de la disputa
- La historia del Breakout de Atari
- Y las secuelas

4. Droid D64, tú y yo tenemos que conocernos mejor

5. Clones de Arkanoid con SDL
- Breakout
- SDL-ball
- Breaker 10
- Breaker 10 dentro de una suite de emuladores para la consola Coolbaby RS-97
- Breaker 10 dentro de una suite de emuladores para Dingux (consola Dingoo) ya no disponible

6. SDL
- Resizable Windows
- SDL - Regulating Frame Rate
- Resizable Windows and Window Events

7. SDL2
- Draw an Image with SDL2
- SDL Scale Surface

8. SFML
- SFML and Linux
- SFML - Sprites and textures

9. OpenGL
- Libpng
- STB
- DevIL - A full featured cross-platform Image Library
- SOIL - Simple OpenGL Image Library
- OpenGL Window Reshaping
- OpenGL - Lesson 06 Texturing Update
- OpenGL - Loading a Texture

10. Renderizar en Fundéu

Daegon, mes XXIX




Y llegó el día en el que la cosa se movió… un poco.

A lo largo de estas últimas dos semanas, finalmente, he ido subiendo material a la web de Daegon1. Como no podía ser de otro manera, todo ha cambiado un poco desde lo que vaticinaba el mes pasado a estas alturas.

Cada vez que me ponía con cualquiera de estas entradas su orden cambiaba. Aquella con la que estaba siempre me encajaba como la primera… o igual es que, entre que había decidido escribir estas últimas versiones en el orden en el que debían ser leídas, y que me estaba sugestionando tanto para dar con un comienzo válido, todo cuadraba siempre. No sé, quizás sea un poco de todo.
La cosa es que ha habido mucho baile y el orden ha sido el mismo en el que aparecen en la sección de enlaces.

Si os soy sincero, a estas alturas no tengo muy claro el concreto de lo que he tratado en cada una de ellas. Tengo una idea vaga, eso sí, pero de tantas veces que las he reescrito ya no sabría decir qué ha quedado dentro y qué bloques han terminado yendo a la papelera.

La guía de lectura de la que hablaba el mes pasado ha sido segmentada por categoría con lo que, esta primera instancia de ella, renombrada ahora como “Mapa de la web” ha quedado contenida en seis páginas.

El tamaño de la Introducción ha pasado de una a dos páginas y ha sido renombrado a Presentación, que ha terminado ocupando la tercera posición en cuanto a su orden de lectura. Aunque claro, técnicamente, sería la cuarta.
Y todas han sido desplazadas porque el índice es quien ha terminado haciéndose con la primera posición1. Un índice que, a estas alturas, ya ocupa ocho páginas.

Llevo desde el fin de semana pegándome con él. Quería crear una estructura “plegable” por cada una de las categorías / capítulos de la web, pero no conseguía dar un desglose adecuado, una estructura intuitiva y las tabulaciones correctas.

Al mismo tiempo he ido haciendo acopio de todo lo que está ya publicado en la web, algo cercano ya a las quinientas páginas, las distintas separaciones temáticas que hay en cada una de ellas, y los enlaces para que todas estén accesibles desde un punto centralizado.
No termino de estar del todo contento con cómo ha quedado, no he conseguido que el “plegado” de las secciones funcione en Explorer o en la bandeja de entrada de Gmail, o que el color de fondo se vea en condiciones en el navegador de Android; vivan el HTML 5 y los estándares, pero es un comienzo. Eso sí, quinientas páginas y está todo muy desangelado a la espera de que todo lo que tengo iniciado aterrice en sus ubicaciones finales.

Entre el “Mapa de la web” y las “Aclaraciones previas” he tratado de dar una visión del estado en el que se encuentra todo esto pero, aún así, me da la impresión de que todo el vacío que hay dentro del índice eche para atrás a un hipotético lector.

La entrada del mes que viene que haga referencia a este reto, y más por el tema de terminar con un número redondo, será la última. El reto en sí mismo continuará hasta enero del año que viene (como mínimo), pero dejaré de contaros mis penas a ese respecto por aquí. A partir de agosto, las entradas que les habrían correspondido serán sustituidas por algún otro de los proyectos periféricos.

Me da un poco de pena, pero está más que claro que con su elaboración no he conseguido conectar con nadie. Creo que, si en dos años y medio nadie ha dado muestras de interés por esto, por el mero hecho de alargarlo hasta tres años no voy a conseguir allanarle el camino a nadie.

Así pues, el mes que viene se despedirán los meses daegonitas en su entrega Tripe X. Espero no ponerme demasiado moñas con la despedida.

Enlaces:

1. Lo nuevo viejo
- Mapa de la web
- Aclaraciones previas
- Presentación
- ¿Qué es un juego de rol?
- Sobre quien esto escribe

2. El índice

Introducción

Jugando en Daegon

El mundo

Libro del jugador

Aventuras

Mapas

Relatos

Descargas

Bajo un océano de bits, mes V

Cinco meses después seguimos sin haber picado una sola línea de código propio. Aun así, la cosa avanza.
Cuando no estoy pensando en que esto no me va a terminar de entrar en la cabeza en la vida, hasta logro emocionarme al lograr entender algo. Me reafirmo en el comentario del mes pasado en el que decía que el curso de SDL de Antonio García Alba era el mejor encuentro aleatorio que me podía haber salido en el camino.

Pero cuesta, vaya si cuesta.
Aunque... ¿qué diablos?. Si uno montón de chavales de quince años pudieron hacer juegos en ensamblador sólo con los medios disponibles hace más de tres décadas, esto no va a poder conmigo.
O al menos eso me repito una y otra vez.

Llevo ya más de cincuenta ejercicios del curso completados y he logrado hacerlos funcionar todos. Para algunos de ellos he necesitado tirar de la gran G, y ha sido de esos de los que más he aprendido, pero aún estoy muy lejos de ser autónomo o de verme capaz de entender y asimilar todo lo que estoy copiando.

Ando siempre a medio camino entre la versión Wiki del curso y el PDF. Por un lado, la wiki es más cómoda a la hora de copiar el código de los ejemplos pero, no sé si porque han hecho alguna conversión automática del texto de otro lado, o vete tú a saber porqué razón, me sigo encontrando con ejemplos que están mal transcritos.
El PDF me da una mejor visibilidad del avance, y además tiene algún ejemplo que no aparece en la wiki, pero cada vez que tengo que copiar uno de ellos la cosa es un poco infernal y tengo que andar quitando números de línea, puntos y comas a saco.
Debería escribirlos yo a mano en lugar de hacer un copia pega, pero… pereza.
Pero bueno, por el momento no me he tenido que saltar ninguno de ellos movido por la desesperación, y eso me parece todo un logro.
Eso sí, al menos ya le tengo pillado el truco al script de compilación.

Ya he terminado con las lecciones dedicadas a las bibliotecas principales y las auxiliares, y en estos momentos me encuentro animando sprites.
En la sesión de ayer logré que arrancasen dos de ellos, pero no hace caso a las órdenes que le doy desde el teclado, así que va a tocar investigar, y eso es algo que, aparte de ser un poco coñazo en ciertos momentos, me hace entender las cosas mejor, lo que es bien.
Puede que no avance demasiado rápido en este curso y por momentos eso resulta frustrante, pero no estoy dispuesto a dejar pasar ningún un ejercicio sin hacerlo funcionar.

Por otro lado, a cada paso que doy se me abre otro nuevo frente. Más detalles cuya existencia ni me había planteado y que lo hacen todo aún más complejo, pero esta ha sido mi elección.
Mi elección, mi funeral, que diría el amigo Logan, pero es lo que hay y esa decisión se sigue manteniendo firme.

También he conseguido compilar las versiones SDL de Prince of Persia, Rick Dangerous y Super Mario Bros. Eso sí, cada vez que me pongo a leer su código no tengo la más mínima idea de por dónde seguir (y en algunos casos ni siquiera sé por dónde empezar a mirar).
Y sin embargo se mueve(n).

En el resto de embolados en los que me voy metiendo la cosa tampoco ha estado parada.
Por un lado, el tema de la accesibilidad está aún muy verde, y no sólo por mi lado. Apenas hay información pero por lo menos una de las grandes (EA), ya ha comenzado una iniciativa a ese respecto. Claro, EA (bueno, uno de ellos) es el mal y esta iniciativa no ha sido algo impulsado desde las altas instancias. Todo ha venido instigada por una desarrolladora sorda que tienen en plantilla1, y no sé cuánto tiempo, dinero y esfuerzo le van a dedicar, pero es un comienzo.

Ha dado también a casualidad de que, otra de las grandes, Microsoft en este caso, ha sacado durante este mes un nuevo mando para la X-Box orientado a la accesibilidad2. No sé cuál será su utilidad real, si será algo de largo recorrido o un mero ejercicio de márketing, pero es más que nada.

Por el momento lo único que tengo claro es que voy a tener que dedicarle más tiempo del previsto al tema del sonido, los menús y la vibración del PAD. Tengo ideas pero, para no variar, el esfuerzo que me puede llegar a implicar es una incógnita. Y ya van...
Igual cuando la cosa avance (otra incógnita más), trato de buscar por las redes a gente con distintas discapacidades para ir ganando esas perspectivas, pero tiempo al tiempo.

Cambiando de ámbito, también ha aparecido por el horizonte una herramienta más; en proyecto español diseñado para analizar el código fuente de otros juegos llamado ViGaSoCo (Visual Game Source Code)3.

En su “léeme” se puede… leer lo siguiente:

VIGASOCO es un framework diseñado para entender como funcionaban algunos juegos clásicos.
Su propósito principal es ser un instrumento de aprendizaje para comprender el funcionamiento interno de los juegos.

Los juegos soportados por VIGASOCO son conversiones "funcionalmente equivalentes" de los juegos, escritas en C/C++ y obtenidas mediante reingeniería inversa del código original del juego.

Por el momento, y por lo que he logrado sacar en claro, sólo está para Windows pero existe un proyecto para portarlo a SDL y, por lo tanto, hacer que pueda correr en otras plataformas. Lleva parado un par de años y, por el momento, al utilizar algunas de las APIs de Windows, no compila en Linux (o al menos yo no he sido capaz de hacerlo).

Aún me pierdo mucho con los vaivenes de este proyecto pero, por lo que me ha parecido entender, nació para analizar el funcionamiento de la Abadía del Crimen (aunque también mencionan por algún que otro lado al Pac-Man).
A priori no se adapta al proyecto que tengo en mente, pero sí que tengo curiosidad por ver cómo está armado un juego en perspectiva isométrica (aunque me temo que habrá por en medio mucha matemática de la que no me enteraré).

¿Hemos acabado?
No. Aún queda más.

Este mes también han tenido lugar dos eventos retro.
Sólo he podido ir a uno de ellos, RetroMadrid, más por la gente la que iba a ver fuera de la feria que por la feria en sí misma, pero ha tenido cosas interesantes que ya están disponibles en el Tutubo4 y de las cuales aún me queda alguna por ver.

La otra feria, Explora Commodore5, ha tenido lugar en la zona más conflictiva de la ¡¡¡España!!! actual; Barcelona. No he podido ir con gran dolor para mi corazón Commodoriano, pero estoy tratando de hacer un seguimiento a las cosas que se han presentado por ahí. Algún día llegará Daegon para el C64, recordadlo.

Dentro del terreno retro también he hecho un descubrimiento esta última semana; The New 8-bit Heroes6, un proyecto de documental sobre la gente que hace juegos para 8 bits en la actualidad, y un curso para quienes quieren lanzarse a ello.
Algún día…

Y eso es más o menos todo por hoy. Por supuesto han habido más cosas. Más vídeos de la GDC8, he mirado un poco más acerca de Vulkan9, quien vaticinan que será el sucesor de OpenGL, y también ha caído algún que otro artículo interesante10.

Y la rueda no para. (Quizás) El mes que viene más.

Enlaces:

1. Sobre la accesibilidad en los vídeo juegos
- AAA Gaming While Blind
- Karen Stevens
- Portal de accesibilidad de EA

2. El nuevo mandaco de X-Box

3. VigasocoSDL (VIdeo GAmes SOurce COde)
- Proyecto original
- Sitio original
- Repsitorio en GitHub
- En ensamblador
- Cuenta de Tuister
- Y aquí algo parecido a una cronología del asunto

4. Charlas Retro Madrid
- Entrevista a Jon Ritman
- Programando videojuegos pseudo-3D con 8BP
- Lo que siempre quisiste saber del Apple II
- HispaMSX BBS
- Cómo desarrollar videojuegos retro y no morir en el intento

5. Explora Commodore 2018
- Página del proyecto
- Reportaje sobre la edición de este año

6. The New 8-bit Heroes
- The New 8-bit Heroes, Trailer
- NESmakers - Episode 1
- Vídeos del canal

8. La GDC nunca para
- Building Games That Can Be Understood at a Glance
- Level Design Workshop: Architecture in Level Design
- Practical Procedural Generation for Everyone
- The Art of The Witness
- Manifold Garden: Level Design in Impossible Geometry
- Temporal Reprojection Anti-Aliasing in INSIDE
- Designing Journey
- How Cameras in Side-Scrollers Work
- Animation Bootcamp: 2018 Tricks of the Trade
- Ebb and Flow - Conversations on the recent momentum of Japanese games
- My To-Do List: Organizing a Producer's Work
- Classic Game Postmortem: Sonic the Hedgehog
- Animation Bootcamp: Animation Prototyping for Games
- Fizzy Brushstrokes: The Art of Knights and Bikes
- Level Design Workshop: Designing Celeste

9. Vulkan
- Wikipedia
- Página de Khronos Group
- Guía de portabilidad para Vulkan
- Godot adopta Vulkan
- Vulkan y el OpenSource

10. Y lo demás
- Sonic the Hedgehog – Developer Interview Collection
- Código fuente de Aladdin
- Five Productivity Tips for Solo Devs
- A Study Into Replayability - Defining Variance

Páginas

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer