La gestión de los FPS en un juego es mucho más compleja de lo que parece a primera vista. Para MotoGT 1 usé la técnica más simple y menos elegante: framerate constante. Para MotoGT 2 empezé tratando de independizar la velocidad de la física de la del rendering, usando para lo primero un velocidad constante, pero implementando el código de forma tal que esa constante pudiera ser ajustada luego. Pero ahora la cosa mutó, y resulta que al final el framerate ya no es constante, para ninguna de las dos. Hubo que resolver algunos conflictos, pero la inversión pagó, la diferencia se nota mucho más de lo que había imaginado.
martes, 29 de septiembre de 2015
miércoles, 16 de septiembre de 2015
Nuevos atajos en ZinjaI (parte 2/2)
En el post anterior les comentaba que la última release de ZinjaI traía algunas funcionalidades nuevas que no están tan a la vista pero que pueden ser muy útiles para acelerar nuestra codificación. Y les conté de lo nuevo en el menú "Generación de código" (si no lo leyeron, empiecen por ahí antes de seguir con este). Lo que quedó para la segunda parte son los cambios en los autocódigos y una nueva forma de edición múltiple.
jueves, 10 de septiembre de 2015
Nuevos atajos en ZinjaI (parte 1/2)
Las versiones de agosto de ZinjaI traen unas pocas novedades, pero creo que a pesar de ser pocas tendrán un gran impacto, ya que parecen muy útiles. Son algunos atajos para escribir más rápido. Por ahora están algo verdes, pero hay muchos escenarios en los que ya se pueden utilizar. Particularmente les vengo a comentar de tres cosas: las nuevas opciones en el submenú "Generación de código" del menú "Herramientas"; una mejora interesante en el mecanismo de autocódigos; y una nueva forma de editar varios lugares al mismo tiempo. La primera en este artículo, las otras dos quedarán para la segunda parte.
En lo personal, para mí son las tres cosas que no sabía que quería, pero que ahora que las probé las uso cada dos minutos y ya no puedo programar sin ellas. El objetivo de todo esto es como siempre escribir el código muy rápidamente. Y con acento en el "escribir". En un mundo ideal, el tiempo lo tenemos que invertir en "pensar" y no en "escribir". Entonces, mejor aprender a sacarle provecho a todo lo que el IDE nos ofrezca para el "escribir", para que consuma mucho tiempo menos que el "pensar". Sin más preámbulos, he aquí los nuevos trucos.
En lo personal, para mí son las tres cosas que no sabía que quería, pero que ahora que las probé las uso cada dos minutos y ya no puedo programar sin ellas. El objetivo de todo esto es como siempre escribir el código muy rápidamente. Y con acento en el "escribir". En un mundo ideal, el tiempo lo tenemos que invertir en "pensar" y no en "escribir". Entonces, mejor aprender a sacarle provecho a todo lo que el IDE nos ofrezca para el "escribir", para que consuma mucho tiempo menos que el "pensar". Sin más preámbulos, he aquí los nuevos trucos.
lunes, 7 de septiembre de 2015
And the winner is... (II)
Todas las semanas alguien del staff de SourceForge elige 10 proyectos para destacar, con algún criterio que no estoy seguro cual es, pero que por suerte le da iguales oportunidades a proyectos chicos y grandes. Luego, a fin de mes, de entre todos los destacados de ese mes, se elige un subgrupo de 9 o 10 proyectos y se somete a votación para determinar cual es el próximo "Community Choice Project Of The Month" (proyecto del mes (POTM) elegido por la comunidad). El ganador ostenta el título durante un mes. A veces, los editores eligen uno más como "Staff Choice POTM". Si entran al home de SF, lo primero que verán serán los proyectos destacados del mes, y lo segundo, los de la semana. Para cada proyecto destacado del mes, además, SF publica una entrevista con alguno de los desarrolladores en su blog. Pues bien, este mes (Septiembre 2015) el "Community Choice POTM" es nada más ni nada menos que PSeInt!!!
viernes, 28 de agosto de 2015
¿Dónde consigo un anti-antivirus?
Hoy planeaba a publicar otra cosa, pero necesito hacer catarsis. Ayer recibí dos quejas consecutivas sobre que el instalador del último ZinjaI parecía contener algo malicioso a ojos de algunos antivirus. Es muy poco probable que tal afirmación sea verdad, más abajo les cuento por qué. Y efectivamente no lo era, el antivirus estaba confundido. Pero me resultó muy alarmante descubrir dónde estaba la confusión. Y para colmo la experiencia de uso de un antivirus me pareció inverosímil. Como programador, entiendo el trabajo de locos que requieren y las concesiones que se deben hacer. Pero creo que pasaron la raya, y por mucho. Lo que vi no tiene justificación, prefiero mi PC llena de bichos antes que trabajar así. Ahora les cuento.
viernes, 21 de agosto de 2015
La zona del programador
Soy de esa clase de personas que les gusta mucho perder invertir tiempo buscaaando y probaaaando herramientas, o peor aún, haciéndose las propias. Y no es raro que se me valla más tiempo y esfuerzo en esa búsqueda o construcción, del que llevaría resolver el problema particular para cuya resolución quiero esa herramienta. Sin ir más lejos, hace muy poquito les conté sobre un error tonto que me llevó a programar dos nuevas funciones en ZinjaI, y que encima al final ni las necesitaba. Este tipo de cosas (el desviarme para buscar, hacer y/o automatizar herramientas y procesos) me ocurre todo el tiempo, y creo que es común en muchísimos programadores. El problema es que cuando uno desarrolla estas herramientas no-indispensables uno tiende a sentirse algo culpable por no trabajar directamente en la solución del problema, sino posponerla por una deformación profesional propia. Si esto también te pasa a vos, mi valioso lector, este post viene a darte algunas excusas para que dejes de sentirte culpable y valores ese trabajo.
lunes, 10 de agosto de 2015
Preguntas frecuentes sobre PSeInt
Hay tres preguntas acerca de las funcionalidades o el futuro de PSeInt que recibo periódicamente una y otra vez, ya sea en los foros, en mi correo, o a veces hasta en persona. Básicamente, sobre PSeInt para Android, sobre PSeInt en otros lenguajes, y sobre el uso de registros/structs en el pseudolenguaje. Les adelanto que son tres cosas que actualmente no están disponibles en PSeInt, pero si siguen leyendo les cuento mejor por qué no, y qué podemos puede hacer al respecto.
jueves, 30 de julio de 2015
ASM caliente para el alma del programador
Depurar programas paralelos es terriblemente complicado. Y cuando uno le suma a eso su propia idiotez el combo se torna mortal. Esta semana perdí dos días completos por culpa de un error de tipeo. Pero, como toda historia para que merezca ser contada debe tener algún lado bueno, en este caso, mis dos días de caza incluyeron el desarrollo de un par de funcionalidades nuevas en ZinjaI. Funcionalidades que al final de cuentas no necesitaba en absoluto para resolver ese problema, pero que en algún momento pensé que sí, y supongo que a futuro ya les daré mejor uso. Se trata de un par de paneles para inspeccionar el código de máquina generado por el compilador, y el estado de los registros internos del procesador durante la depuración. He aquí la anécdota completa y el resultado.
jueves, 23 de julio de 2015
La escencia de la programación de computadores
El gran Brian Kernighan escribió una vez, hace como mil años (circa 1976), la siguiente frase:
Una posible traducción sería: "El control de la complejidad es la esencia de la programación de computadoras." Debo haber leído esta cita por primera vez hace al menos 10 años. En su momento me pareció una más. No eran palabras rimbombantes, ni conceptos extraños. Parecía más bien un punto de vista, una opinión, con algo de cierto, algo de exagerado, como tantas otras. Otras frases me impactaron/gustaron mucho más cuando las leí por primera vez. Sin embargo, con esta pasó algo muy especial. Con el tiempo, muuuy lentamente, a medida que cometía mis propios errores e iba aprendiendo con cada uno de ellos a programar un poquito mejor, me fui dando cuenta de que esa no es una frase más, sino una de las verdades más profundas e indiscutibles que podemos enunciar sobre la programación.
"Controlling complexity is the essence of computer programming."
Una posible traducción sería: "El control de la complejidad es la esencia de la programación de computadoras." Debo haber leído esta cita por primera vez hace al menos 10 años. En su momento me pareció una más. No eran palabras rimbombantes, ni conceptos extraños. Parecía más bien un punto de vista, una opinión, con algo de cierto, algo de exagerado, como tantas otras. Otras frases me impactaron/gustaron mucho más cuando las leí por primera vez. Sin embargo, con esta pasó algo muy especial. Con el tiempo, muuuy lentamente, a medida que cometía mis propios errores e iba aprendiendo con cada uno de ellos a programar un poquito mejor, me fui dando cuenta de que esa no es una frase más, sino una de las verdades más profundas e indiscutibles que podemos enunciar sobre la programación.
miércoles, 8 de julio de 2015
El Para y los diagramas de flujo: ese pequeño gran detalle
jueves, 2 de julio de 2015
Mientras tanto, en... (III)
Van dos meses sin novedades visibles en PSeInt: sin publicar versiones nuevas, sin hacer comentarios en el blog y sin terminar de ponerme al día con el foro. Por el lado de ZinjaI, pasa algo similar (no hay versiones desde hace 4 meses), aunque es más común dado que los cambios en ZinjaI usualmente requieren más tiempo y más pruebas. Y para completar, hace casi un mes que no escribo nada en el blog. En ambos proyectos hemos visto períodos mucho más largos sin novedades, pero no quiere decir que esa situación me simpatice. Me gusta que siempre haya algún movimiento, por mínimo que sea. Y en verdad lo hubo. Tratando de seguir la filosofía "release erale, release often", en breve lanzaré un par de actualizaciones para compartirlos. Mientras tanto, les cuento por dónde pasan los cambios y les adelanto un "trailer" de la próxima release.
viernes, 5 de junio de 2015
std::function: Ya tengo mi (nuevo) martillo
Todos conocen la frase "si solo tienes un martillo, todo te parece un clavo" o alguna variación con la misma idea. A mi, con la programación me pasa algo curioso. Tengo una caja repleta de herramientas de todo tipo, pero cada vez que agrego a la caja un martillo nuevo, todo lo demás se me convierte en clavo. Mi caja está mayormente llena de C++. Diría que casi todo C++03 está en la caja, y que gradualmente he ido agregando herramientas de C++11/14. En algún punto me pasó con eso de SFINAE y los trucos que se podían hacer, y los apliqué por todos lados. En otro momento, agregé a la caja las maravillosas "Variadic Templates" y grité "I have a hammer!", y variadic templates para todos.
Ahora, la funcionalidad de C++11 que se está tornando increíblemente "martillosa", es la aparición de las funciones lambda, y como yapa de la clase auxiliar std::function. Es decir, la posibilidad de crear funciones y clausuras "al vuelo", sin siquiera ponerles tipo ni nombre, y la facilidad que provee la clase std::function para apuntarle a esos pequeños monstruitos sin que nos importen ni preocupen sus especies. En MotoGT 2 están martillando cuanto clavo (y tornillo) se les cruza. Y el resultado es una delicia. Un buen motor puede dar muchas más libertades sin agregar ruido cuando hace uso de estas cosas, y permite al programador ser mucho más productivo.
Ahora, la funcionalidad de C++11 que se está tornando increíblemente "martillosa", es la aparición de las funciones lambda, y como yapa de la clase auxiliar std::function. Es decir, la posibilidad de crear funciones y clausuras "al vuelo", sin siquiera ponerles tipo ni nombre, y la facilidad que provee la clase std::function para apuntarle a esos pequeños monstruitos sin que nos importen ni preocupen sus especies. En MotoGT 2 están martillando cuanto clavo (y tornillo) se les cruza. Y el resultado es una delicia. Un buen motor puede dar muchas más libertades sin agregar ruido cuando hace uso de estas cosas, y permite al programador ser mucho más productivo.
domingo, 31 de mayo de 2015
Las bases de MotoGT 2: overview
Hace un tiempo les comenté que pienso reescribir MotoGT desde cero. Llamo a este proyecto MotoGT 2. Aunque por fuera, al principio será un clon del primer MotoGT con apenas unos pocos detalles nuevos visibles, por dentro la historia es totalmente diferente. El objetivo es obtener una base de código más sólida con la cual experimentar fácilmente agregando y quitando cosas al juego, para que lo que limite su desarrollo sea mi creatividad y mi poca idea de game-design, y no un código complicado y difícil de modificar o mantener.
Entonces, tengo que escribir un pequeño motor de juego. Lo suficientemente general como para que me provea esa flexibilidad. No tan general como para renegar con cosas que no necesito. Con una interfaz de alto nivel para no lidiar con detalles finos de implementación al concetrarme en la lógica del juego. Con capas o subsistemas desacoplados para que, por ejemplo, la biblioteca que use para gráficos y sonido no me condicione la forma de programar esa lógica del juego. Y más, como para que un imprevisto no tire abajo el proyecto.
Entonces, tengo que escribir un pequeño motor de juego. Lo suficientemente general como para que me provea esa flexibilidad. No tan general como para renegar con cosas que no necesito. Con una interfaz de alto nivel para no lidiar con detalles finos de implementación al concetrarme en la lógica del juego. Con capas o subsistemas desacoplados para que, por ejemplo, la biblioteca que use para gráficos y sonido no me condicione la forma de programar esa lógica del juego. Y más, como para que un imprevisto no tire abajo el proyecto.
martes, 26 de mayo de 2015
Constructores privados y std::shared_ptr
Tuve un problema de diseño/implementación con una clase en particular mientras escribía algunas cosas básicas para el nuevo MotoGT, que me resultó muy interesante por lo simple que es el planteo, y por los caminos rebuscados que puede tomar la respuesta. Básicamente quería garantizar que las instancias de una clase particular solo se pudiesen crear por medio de una función auxiliar. La solución habitual es poner el constructor de la clase como privado/protegido y hacer a la clase amiga de la función. Pero esto no es 100% seguro desde algún punto de vista y, por sobretodo, se complica cuando queremos usar std::shared_ptr y std::make_shared con esa clase. Si no se van, les cuento mejor dónde aparece el problema, para qué sirve, y a qué solución llegué.
martes, 19 de mayo de 2015
Problemas con la terminal y el depurador (parte 2)
Empecé el artículo anterior diciendo que iba a mencionar dos problemas con las terminales y la depuración en ZinjaI, pero como se hizo largo describí solo uno. Pues aquí viene el segundo. Es un problema levemente relacionado, muy molesto, pero generalmente inofensivo. Es el mensaje "&warning: GDB failed to set controlling terminal: Operation not permited" que se muestra al comenzar la depuración en GNU/Linux. Desde la versión 7.0 de gdb, muchos IDEs sufren este mensaje, que asusta al usuario inexperto y genera consultas de lo más variadas. Hay miles de hilos al respecto en foros varios en Internet, pero absolutamente ninguna solución. Yo tampoco pude solucionarlo, pero al menos llegué a entenderlo y me convencí de por qué en general no se puede, y qué consecuencias puede traer. Vengo a documentarlo porque leí miles de respuestas, y la mayoría no están ni remotamente cerca de la verdadera causa, y sus consecuencias.
Suscribirse a:
Entradas (Atom)