@ agnasg

agnasg


Bugs

08-02-2019 9:18 AM

En el post anterior el tema de los bugs quedó sin mucha explicación, y dado que he hablado poco de ellos, más allá de una que otra queja, este post es entonces un post sobre bugs.

Para los pocos que no lo saben, los programadores llamamos bugs a las fallas en los programas. El nombre (bug es insecto en inglés) viene dado por razones históricas. En los albores de la computación los equipos fallaban por insectos que se introducían en los antiguos circuitos y tubos que lo formaban, en una época en que nadie soñaba con los circuitos integrados, chips y otras tecnologías modernas.

Todo el tema de programación orientada a objetos (oop), clases, encapsulamiento, cero variables globales, las metodologías de software engineering  y otras ideas son mecanismos para evitar los bugs y otras alimañas que hacen que los programas no funcionen. Los resultados son mixtos.

Mi último juego, khpx, está implementado utilizando una idea descabellada: nada de clases, nada de encapsulamiento, y cientos de variables globales para mantener el estado del juego. Luego de programar decenas de aplicaciones y juegos en C++ y su parafernalia, llegué a la conclusión de que hay que usar C++ por las razones correctas, no necesariamente para evitar los bugs, pues C++ tiene un costo. Un programa en C++ es 50% más voluminoso y complejo que su equivalente en C.

No tengo una estadística que sustente ese 50%, puede ser 20% o 100%. El punto es el siguiente: ¿cuál programa tiene más probabilidad de tener bugs, uno de 1000 líneas o uno de 100? Algunos programadores sesudos argumentarán que los bugs blah, blah, blah y blah. En realidad la probabilidad de un bug no es directamente proporcional a nada, porque los bugs se rigen por la ley de Murphy, por lo que ambos programas, el de 1000 líneas y el de 100 líneas pueden tener bugs, o puede que no lo tengan. Y si ese es el caso, entonces ¿por qué voy a pasar el trabajo de escribir un programa de 1000 líneas, y la desventaja de tener que entenderlo y darle mantenimiento, en lugar de un programa de 100 líneas que con una mirada rápida puede revelar sus misterios rápidamente?

Mi respuesta es no, no tienes que pasar trabajo. Claro que hay unos beneficios adicionales de la programación orientada a objetos (oop): el código queda más organizado, se supone que es más fácil de entender para el grupo de trabajo, es más fácil de mantener. Puesto que soy un lobo estepario (un programador solo)  esos beneficios no existen o al menos estoy hastiado del costo involucrado. Y para ello, baste mencionar como ejemplo el bug que tuve esta semana que involucró 12 horas de pesquisa y trabajo detectivesco para su solución (sí, en el post anterior decía que yo estaba muy sagaz resolviendo bugs, famosas últimas palabras, horas después apareció uno que me callaría la boca).

khpx está implementado con unos arreglos que guardan la información de los sprites. Hay un arreglo g_spr_obj_tbl que guarda los objetos que no requieren modificar el vertex buffer, g_modified_spr_obj_tbl guarda los objetos que lo requieren. Modificar el vertex buffer significa hacer la llamada Lock (), modificar los vértices de los meshes (estoy hablando en términos de DirectX) y Unlock () para terminar las modificaciones.

El punto es que esta semana estuve implementando el fadein/fadeout de la cónsola que muestra los datos de los sensores y controles de la nave, y cuando agregué los objetos para manejar los sensores y controles correspondientes a una batalla, comenzaron a suceder cosas inesperadas: él nuevo sprite perdía su posición en la pantalla y su su tamaño (scale). Era claro que cuando estaba de último en el arreglo fallaba, cuando lo movía a la posición penúltima funcionaba. 12 horas después y luego de revisar el codigo decenas de veces descubrí que el objeto que muestra la posición del scroll en los listados (SCROLL_BAR) estaba mal inicializado, debía estar en el arreglo de los objetos que no modifican el vertex buffer (g_spr_obj_tbl) y en cambio estaba en g_modified_spr_obj_tbl. El índice de este objeto está indicado con un define SCROLL_BAR cuyo valor es 10, que casualmente corresponde al último índice en g_modified_spr_obj_tbl. Esto producía un cambio en cualquiera que fuera el objeto que estuviera en esa posición, que resultó ser el nuevo sprite que yo estaba insertando esta semana.

Este bug me recordó mis proyectos usando oop, porque parece el tipo de bugs que sucede con frecuencia en ese tipo de proyectos. De hecho, en todo el tiempo que tengo programando khpx (un año) primera vez que sucede algo así. El encapsulamiento de la data persigue que este tipo de fallas no ocurran, pero todo depende de que coloques la data en la variable correcta. Si te equivocas de variable, el bug sucede, con o sin oop.

Claro que una alternativa a arreglos e índices son los containers, std::vector por ejemplo, y su iterator’s. El uso de índices y arreglos son peligrosos, o al menos deben ser utilizados con suma precaución. Hay ocasiones que requieres usar ciertos objetos por nombre y apellido, por ejemplo un sprite, y su uso incorrecto afecta todo el sistema. Si revisas el código de Doom (el juego de Id Software los creadores de Quake) está llenos de arreglos, y de accesos por índice. No hay ningún mecanismo especial para evitar este tipo de bugs, más allá de un programador alerta.

Hay múltiples moralejas, y hay múltiples formas de decirlo, pero una de las que más me gusta, está en este libro “Essential C” de Nick Parlante: ” The C programming model is that the programmer knows exactly what they want to do and how to use the language constructs to achieve that goal. The language lets the expert programmer express what they want in the minimum time by staying out of their way” (“El modelo de programación en C es que el programador sabe exactamente lo que quiere hacer y cómo usar las construcciones del lenguaje para lograr esa meta. El lenguaje permite que el programador experto exprese lo que quiere en el mínimo tiempo, manteniéndose fuera de su camino”). El lenguaje C es una herramienta que ayuda a resolver problemas, en múltiples formas, pero principalmente no estorbando. Y eso es realmente una gran ayuda.

Aclaratoria: como está dicho en los posts anteriores khpx, está programado en C++ pero utilizando al mínimo los paradigmas oop. Es prácticamente C pero con el STL. Utilizo intensamente los containers std::vector y std::map lo cual garantiza un código robusto y simple (y por añadidura el mínimo uso de arreglos, pero al parecer, no lo suficiente)

Una decisión acertada por accidente

04-02-2019 1:31 PM

Programar un juego es una aventura en sí misma. Por ello puedo decir con toda la autoridad de mis años programando juegos que es un juego difícil de jugar. Hay sistemas que combinan múltiples interfases, pero los juegos las tienen todas: graficos, bases de datos, scripting, inteligencia artificial, redes, interpretadores, interfases de usuarios muy complicadas, y muchas otras cosas.

Por todo ello, los bugs son especialmente espeluznantes. Desconcertantes. A veces puedo tardar horas en resolverlos. Los he tenido de toda una tarde.

Pero… últimamente he estado muy acertado resolviendo bugs en khpx. Ayer apareció un bug al crear un reqNrew (requerimientos y recompensas) desde una misión, que hacía que el sistema olvidara la operación original en la misión (la operación puede ser agregar o actualizar). Resolverlo fue fácil porque simplemente tuve que agregar una variable para guardar este estatus. Bien interesante. El viernes otro bug pero esta vez en khpx, el sistema mostraba caracteres desordenados al presentar el inventario, claro como cada línea en una columna es un objeto era obvio que dos objetos estaba quedando en la misma posición. ¿Por qué? Un nombre puede ocupar más líneas que una descripción. Ups.

Lo que me lleva a responder cuándo voy a terminar khpx: cuando lo termine. Acabo de tener la brillante idea de que cuando un equipo armado  de penetración profunda en terreno enemigo entra en combate, la consola de la nave se transforma en una consola de combate. Estaba pensando en una fedeout/fadein (transición entre cónsolas) tipo persiana, una baja y la otra sube, y mientras escribía esto me dí cuenta que eso sería igual al sistema de worl of warcraff. No. Noo. Nooooo.

Pero en otro orden de ideas, Niko (irrlicht) acaba de twitear que el interés en la versión Mac y Linux de su próximo juego es menos del 1%. Afortunadamente ya yo había pensando en hacer khpx solamente para Windows. Ups, khpx está programado en DirectX que es Windows only. Ups, fue una decisión acertada por accidente.

Los juegos “nacen”

19-01-2019 7:42 AM

“Without insight into the process and without the perspective of work over time like this, games “just come out”, and when struggling with my own despair at the seemingly pointless slog of working on my own projects and the endless churn of not feeling like things are actually getting done, logs like this are a firm reminder that a result is a product of work multiplied by time. The time aspect can sometimes be forgotten, or imagined as some kind of hill that just needs to be climbed: I for one get the absurd idea that if only I worked more and harder the time could be traversed quicker, but all it winds up doing is bleed me dry, and the project as well.”

(“Sin comprender el proceso y sin la perspectiva del trabajo a lo largo del tiempo, los juegos “nacen”, y cuando lucho con mi propia desesperación ante la aparente inútil tarea de trabajar en mis propios proyectos y la interminable perturbación de no sentir que las cosas se están haciendo realmente,  registros como este son un firme recordatorio de que un resultado es un producto del trabajo multiplicado por el tiempo. El tiempo como elemento a veces se olvida, o se imagina como una especie de colina que sólo necesita ser escalada: Yo por lo menos tengo la absurda idea de que si trabajara más y más duro el tiempo podría ser atravesado más rápido, pero todo lo que termina haciendo es desangrarme, y desangrar al proyecto también.”)

De un hilo sobre el juego Obra Dinn

De regreso de vaca

10-01-2019 10:59 AM

Así sin más, decidí irme de vacaciones a Ecuador y visité los familiares que accidentalmente viven allá. Guayaquil es una ciudad bien organizada. Los autobuses interurbanos tienen aire acondicionado, se puede ver una película, tienen wi-fi. En cada parada se llenan de vendedores ambulantes que realizan una danza tipo Cirque du soleil, con bandejas de mango condimentado, papi-pollo (una bandejita con papitas fritas y una presa suculenta de pollo), humitas (cachapas de hoja rellenas con queso), agua y refrescos, maduros (plátanos), y otros productos difíciles de identificar o recordar. Alguna vez se para un vendedor a hacer un discurso como los que hacen los vendedores de resorts, con una sección motivacional, reflexiones, comentarios sobre los problemas que agobian a la humanidad, y cómo la solución presentada los resuelve, gratis, o por $1. La moneda en Ecuador vale un dólar estadounidense, ambas monedas están amarradas. No me imagino una solución más honesta y simple que esa.
Los supermercados están atiborrados de todo tipo de productos, es difícil imaginar que falte algo. Todos los anaqueles están repletos, y los productos parecen ser reemplazados a los minutos de ser adquiridos.

Estas notas sobre Guayaquil, ahora que las releo y que esperaba acompañar con comentarios similares de Ambato y Baños (otras dos ciudades ecuatorianas que visité) ahora me resultan tan obvias que no me parece que valgan la pena. Que las cosas funcionan como se supone que debe ser no es noticia, o relevante, o digno de ser mencionado, es al revés, Venezuela es la excepción. En Venezuela las cosas dejaron de funcionar hace 20 años. El mecanismo fácil y absurdo de resolver los problemas se volvió la norma. Por eso cuando encontramos algo funcionando correctamente resulta tan raro. Porque a veces en Venezuela te encuentras con cosas que funcionan muy bien y te preguntas si se trata de un ardid. Es perturbador.

Ecuador tiene sus idiosincrasias por supuesto. Dicen pollo hornado (en vez de la forma correcta pollo horneado), llaman “maduros” a los plátanos, se explayan en disminutivos (“compren los panecitos rellenaditos de quesito por un dolarito”). Todos los taxis tienen el mismo tipo de corneta (o, las cornetas de los taxis todas suenan igual) Y la tocan cuando pasan por el lado. No suelen acompañar las comidas con pan, sino con arroz, mucho arroz (lo cual es razonable dado que el arroz es más barato que el trigo), y además le agregan menestra (frijoles, lentejas, caraotas y otros granos). Hay un pueblo a un lado de la playa que se llama Playas, así que es posible ir a la playa en Playas. Tienen un pueblo maravilloso llamado Baños (no Los Baños) con una calle llena de bares, discotecas y pubs como los anglosajones (varios se llaman o tienen al leprechauns en la puerta). Tiene una temperatura exquisita, la gente es jovial y feliz. Es un pueblo digno de visitar de nuevo y dedicarle por si sólo varios dias. No tienen autopistas, todas las vías son de uno o dos canales en algunas secciones, por lo que un trayecto de 200 y pico kilómetros que en Venezuela sería cosa de un par de horas puede durar 5 ó 6 en Ecuador, porque las carreteras serpentean por las montañas, entre una neblina aterradora y curvas imposibles. Los precipicios están por doquier, y las múltiples paradas, a veces inexplicables demoran más la travesía. No existen perimetrales ni nada por el estilo (una avenida que bordee la ciudad), la carretera atraviesa los pueblos por lo que tenemos que esperar en el tráfico de cada pueblo que nos encontramos. En realidad es un milagro que el trayecto de Guayaquil a Ambato dure 5 horas. Con tantas aventuras debería tardar más.

La comida es endemonidamente barata: con $3 dólares te metes una comida completa con plato principal y sopa. Si quieres algo más sofisticado (aunque no necesariamente más abundante) $5-$7 puedes ser apropiado. La comida es muy sabrosa: en todas partes, siempre. No tengo idea cómo es posible. Hasta en París me he encontrado en alguna ocasión un fiasco: en Ecuador nunca, durante 18 días.

¿Me quedan recuerdos? Muchos. Me acuerdo de un parque enorme, el parque Samanes, parecido al Parque del Este, tiene muchas canchas de deporte, caminerías, una concha acústica, edificios administrativos de organismos relacionados con el ambiente y el deporte. Recuerdo los dos malecones en Guayaquil (porque hay dos), con un enorme boulevard con máquinas expendedoras de refrescos cada 500 metros, y una rueda panorámica como las que hay en los parques de diversiones (o como la que hay en Londres). Me acuerdo de la gente, a la que sentí como mi familia: de hecho al entrar en cualquier vagón del metro de Caracas es posible que te encuentres con 5-10 ecuatorianos: todos se parecen, miden metro y medio y pico, rechonchos, hombres y mujeres: estas últimas están más claras que los hombres: no usan traje de baño en las playas, un pantaloncillo, una franela y ya. Y no te metas con ellas: te responderán con la más hermosa de las sonrisas. Quedarás desarmado.

¿Me iría a vivir a Ecuador? Con los ojos cerrados.