El blog personal de Morgul, donde escribe sobre sus aficiones, descubrimientos y actividades, compartiendo conocimientos.

1 de febrero de 2012

The Humble Bundle

English version below.

Me encanta esto: tres videojuegos de calidad (Anomaly, EDGE y Osmos), pagas por ellos lo que quieras, y tendrás disponibles las versiones de ellos para todas las plataformas: Android, Linux, Mac OS X y Windows. Si pagas más de la media de lo que se ha pagado hasta el momento, tendrás un juego más (World of Goo, este me encanta especialmente)... así incentivan a la que la gente se moje un poco más. Además, podemos elegir a quién exactamente va a parar el dinero que decidamos pagar, incluyendo dos organizaciones caritativas, y cúanto queremos dar a cada parte implicada. Ya lleván más de medio millón de dólares en ventas de esta manera... y eso sólo en esta temporada, lo han hecho varias veces ya ;D

http://www.humblebundle.com

I love this: three quality video games (Anomaly, EDGE y Osmos), you pay whatever you want for them, and you'll have the versions of those games for all platforms: Android, Linux, Mac OS X and Windows. If you pay more than the currently average purchase price, you'll have one extra game (Word of Goo, this one I specially love)... that way they gently push people to pay some more. Moreover, we can choose who exactly will receive the money we choose to pay, including two Charities, and how much we want to give to each implied part. They have already made more than half a million dollars in sales this way... and that's only this season, they've done it several times already ;D

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

21 de enero de 2012

Good bye, Megaupload

Good bye, Megaupload, I wish someday you can come back with my back up files there, but thankfully data is not what I am... so I'll always be fine without any of that. Oh, and I won't miss at all your twin site MegaPorn, haha :P

Kim Schmitz, Mathias Ortmann, Finn Batato and Bram van der Kolk: thank you all. I wish the best to all of you, and I wish the sick "industry" can completely destroy themselves as they've been trying so hard to do.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

13 de enero de 2012

Free coaching with Cory Skyy, in dreams

Hey guys. Receiving coaching in person with Cory Skyy is a truly priceless experience, that I highly recommend to anyone that wants to really be great with women. One of the advantages it has had for me, amongst other great ones, is that I've already had several free coaching sessions with Cory... in my dreams, hehehe.

Tonight I had one of those coaching sessions in a night dream. It was a group coaching one, and we were hanging out in a night club. An advantage for it happening in a dream is that, in dreams, subtle perceptions are super clear. Cory's energy was amazing: I could very vividly feel that he was a pristine chick magnet. He had all that really matters, and all of that openly exuding from him.

There were several lessons from him in the coaching session that I remember and still make sense in this reality:
  • We asked him about the times when we hit eye contact with a woman that we like, but it seems like there's no interest, she's for example just looking with a serious face... So, what do we do about it? His answer was simple, he just pointed out: "how it was when you found a great connection with a girl, did you had to do anything special to have it?"

    I immediately relived (another nice thing from dreams) one of those connections with a beautiful girl, where I was just checking the space around the room, and I automatically (without knowing why yet) stop my eyes on the girl, even she was looking partly away from me. A second later, she turns her head and looks directly at my eyes. And bam! We both know we're into each other, the connection is there and smiling more is inevitable :P Zero effort. That answers the question: no worries, it just happens, no need to go looking for it or doing anything special.
  • At some point in the club, someone asks Cory: "What if we go out some night but find no girl for us?". His answer was something like: "Don't go out with the purpose of meeting women, go out just to have a good time. If you have a good time that night, who cares if you meet any girl or not?". I think he told us also how it was for him if that happened to him, and from his energy, I knew he really didn't care at all, he was completely carefree about it.
  • The last interesting point to learn from, and the most bizarre one - but still can apply to this reality -, was when one of us mentioned that there was no comfortable space in the club to be with a girl, and the only interesting spot - long cushioned seating area attached to the wall - wasn't good enough for intimacy (the pictures of it I still have in my mind say otherwise, but he said that in the dream and it made sense). Cory showed him what he might do in there with her girl, actually doing it as he was saying it: lying down on his back completely, occupying what would be enough sitting space for at least four people... and he added that the girl would lay on him :D. That blew my mind, as it would certainly be out of my comfort zone, as I might be worried what other people in the club would think.
I realize now, that all of these lessons touched some of my sticking points, even ones I wasn't consciously aware of.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

28 de febrero de 2010

Función print compatible con Python 2.X y 3.X

Una de las características introducidas por el sencillo y potente lenguaje de programación Python, en su versión 3.0, es la sustitución de la orden interna print por una función de igual nombre. Esto supone algunas ventajas, pero también la desventaja de romper la portabilidad hacia atrás del código que haga uso de la orden print.

Como tengo varios proyectos de desarrollo en Python, como el motor de MUD de MUnDoCAAD (MUnDoCAAD MUD Engine, véase la entrada "MUnDoCAAD MUD Engine: pasado y presente") y mi intérprete de aventuras tipo-PAWS (véase la entrada "Mi intérprete de aventuras DAAD"), me interesa permitir que este código funcione tanto en versiones de Python 2.X como en las 3.X.

Es por ello que he desarrollado recientemente una solución, un conjunto de módulos Python, que permite tener la misma funcionalidad con independencia de la versión de Python de la que se disponga. Compartiré este código aquí, en mi blog, para quien le pueda servir.

El módulo principal de la solución se llama prn_func, recomiendo su uso con una orden como: from prn_func import prn, y después sustituir todos los usos de print por prn, usando esta función del mismo modo que la nueva función print de Python 3. Su código (a guardar como prn_func.py) es el siguiente:
# Función sustituta de print, compatible con Python 2.X y 3.X

from sys import version_info

if version_info[0] < 3:
  # La versión de Python es 2.X
  if version_info[1] < 6:
    # La versión de Python es menor que la 2.6
    try:
      from prn_2 import prn
    except SyntaxError:
      pass
  else
:
    # La versión de Python es mayor que la 2.5
    try:
      from prn_26 import prn
    except SyntaxError:
      pass
else
:
  # La versión de Python es 3.X
  try:
    from prn_3 import prn
  except SyntaxError:
    pass

Los otros módulos (prn_2, prn_26 y prn_3) son auxiliares a este. Cada uno de ellos ofrece el soporte de la función de impresión para un conjunto de versiones específico de Python.

El módulo prn_2 ofrece el soporte de la función de impresión para versiones de Python menores que la 2.6. Su código (a guardar como prn_2.py) es el siguiente:
# Exporta la función sustituta de print, en versiones de Python 2.X

from sys import stdout

def prn (*args, **keywords):
  textos = []
  for arg in args:
    textos.append (str (arg))
  fichero = keywords.get ('file', stdout)
  fichero.write (keywords.get ('sep', ' ').join (textos))
  fichero.write (keywords.get ('end', '\n'))

El módulo prn_26 ofrece el soporte de la función de impresión para versiones de Python 2.X mayores o iguales que la 2.6. Su código (a guardar como prn_26.py) es el siguiente:
# Exporta la función sustituta de print, en versiones de Python 2.6.X

from __future__ import print_function

prn = print

El módulo prn_3 ofrece el soporte de la función de impresión para versiones de Python 3.X. Su código (a guardar como prn_3.py) es el siguiente:
# Exporta la función sustituta de print, en versiones de Python 3.X

prn = print

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

1 de febrero de 2010

Mi intérprete de aventuras DAAD

Últimamente, he estado desarrollando un intérprete tipo PAW con el lenguaje de programación Python, lenguaje que además de ser muy potente, permite programar aplicaciones de cualquier complejidad en muy poco tiempo (este proyecto es una buena prueba de esta afirmación).

Mi intención es hacer este intérprete genérico, de modo que pueda extenderse fácilmente para soportar cualquier sistema tipo PAW existente, añadiendo en módulos aparte los condactos adicionales (los de The PAWS estándar ya los implementará mi intérprete) y funciones para cargar o importar las bases de datos. Y también extensible en cuanto a poder incorporarlo en un sistema de creación integrado, partiendo convenientemente en módulos para aprovechar el código de buen modo, sin necesidad de duplicarlo.

Como ya había avanzado bastante en la comprensión y aprovechamiento de las bases de datos de algunas de las primeras versiones del parser DAAD, me aventuré a probar y adaptar mi intérprete para aventuras con este sistema (sobre todo, el 'Jabato'), sin perder de vista el aspecto de facilitar la compatibilidad hacia atrás (The Quill, The PAWS, SWAN) y hacia adelante (otros sistemas tipo PAW posteriores, como NMP, SINTAC, SKC, etc.). Esto me ha permitido avanzar aún más en mi descubrimiento arqueológico de los recovecos de DAAD (y sus precursores).

Ayer mismo, me puse tan contento cuando vi que lo que tenía hecho funcionaba tan bien, y de modo tan parecido ya al mismo intérprete DAAD original de el 'Jabato' (ejecutando esta aventura), que grabé un vídeo para compartir con vosotros, y que podáis ver que esto es más que puro vaporware:



En el vídeo (sobre todo en la versión con mayor calidad, la del enlace de descarga que indico en YouTube), si se presta suficiente atención, se aprecian algunos defectos. Unos cuantos de estos los he corregido ya hoy, como:
  • Mayor velocidad de ejecución. Mi intérprete, cuando tenía la traza de banderas activada (el mostrar cómo van cambiando estas), iba bastante lento. Esto me hizo tener que enlentecer enormemente la emulación de DOSBox, para poder comparar de modo visualmente más fácil la ejecución de ambos intérpretes a la vez. Lo he solucionado haciendo que sólo se redibujen las banderas que cambien de valor o color. En comparación, ahora vuela... deshabilitando la acción de espera de los condactos PAUSE y ANYKEY, la ejecución de lo que en el vídeo dura más de un minuto, ahora tarda unos cuatro segundos, permaneciendo totalmente funcional la traza de condactos por consola y de banderas en la ventana.
  • En los créditos, cuando aparece el texto "PRESENTAN" bajo la cara de Jabato, en la versión original Jabato guiña un ojo, mientras que en mi intérprete parpadea (cierra ambos ojos). Una misma versión, con distinto efecto, del mismo problema es cuando la cara de Jabato sube a la parte superior derecha de la pantalla, una vez descrita la localidad inicial. El problema era que mi intérprete dibujaba imágenes siempre completas, sin respetar los límites de dibujado que indicaba el código de la aventura. Ahora ya respeta estos límites invisibles.
  • Otro problemilla menor (en el vídeo) era que, al borrar partes de la pantalla, a veces se borraban también zonas de la sección de impresión del estado de las banderas de mi intérprete. Esto era un problema pequeño, hasta la corrección del problema del primer punto, que lo convertía en un problema grande. Pero la solución ha sido más rápida que la de los puntos anteriores, si bien similar a la del segundo.
Eso es todo, por ahora. Aprovecho para pediros que no dudéis en compartir conmigo cualquier información técnica que tengáis de DAAD o de su precursor inmediato SWAN. Sobre todo, me encantaría conseguir la documentación de DAAD que venía con las copias del parser que se entregaron a los siete ganadores del concurso de Aventuras AD-Microhobby.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

20 de enero de 2010

Cómo cambiar la fecha de una entrada de Blogger

Esta entrada responde a la pregunta: ¿cuál es la forma más sencilla de cambiar la fecha y/o la hora de una entrada de Blogger/Blogspot?

En un post mío anterior, 'Unificación de blogs con Blogger', comenté cómo había cambiado la fecha de varias entradas de este blog a través de las opciones de Blogger Exportar blog e Importar blog, editando a mano un fichero XML.

Pues hoy me he dado cuenta que hay una forma muchísimo más sencilla para hacer exactamente lo mismo. El procedimiento, que es válido sólo para entradas ya publicadas pero independientemente de si se utiliza el utiliza el editor nuevo de Blogger (del que hablaré en el futuro) o el antiguo, es el siguiente:


Abrimos con el editor la entrada a la que queremos cambiar la fecha, seleccionndo Editar en la línea correspondiente a la entrada en el apartado Editar entradas. Una vez abierta la entrada en el editor, nos fijamos en lo que hay inmediatamente debajo del campo de edición del contenido, y veremos que a la izquierda de donde se escriben las etiquetas, está la opción Opciones de entrada. Si hacemos click ahí, se desplegarán unas cuantas opciones, según la versión del editor que estemos utilizando...

Con el editor viejo veremos:



Y con el editor nuevo veremos estas otras opciones:



Una de las opciones que aparecen, que he resaltado en las capturas de pantalla anteriores, es: Fecha y hora de la entrada. Pues ahí está lo que buscábamos, eso es lo que debemos editar para cambiar la fecha y/o la hora de una entrada de nuestro blog.

Esta funcionalidad puede usarse también para realizar un truco con Blogger, que consiste en poner la fecha en el futuro, para que una de nuestras entradas aparezca siempre la primera de nuestro blog, como explica el artículo 'Cómo dejar una entrada siempre arriba del blog' de Ciudad Blogger. En caso de usarlo yo, ya puesto, aprovecharía también lo que dice en su otro artículo 'Mostrar el primer post de forma diferente' sobre la condición isFirstPost de las plantillas Blogger, para que no se mostrara la fecha de ese primer artículo (ocultando la fecha futura).

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

19 de enero de 2010

Código fuente de IMaZMor liberado

Así es, he liberado recientemente (hace un par de días) el código fuente de IMaZMor, cuyo nombre viene de 'Intérprete de Máquina-Z de Morgul'. Es decir, mi intérprete de Máquina-Z, el único que he hecho yo (hasta la fecha).

Para quien no lo sepa, la Máquina-Z es una máquina virtual diseñada por la compañía estadounidense Infocom, para soportar la ejecución de aventuras conversacionales (llamadas típicamente ficción interactiva por los angloparlantes) independientemente de la plataforma física, a través de intérpretes de esta máquina virtual para cada plataforma que se quiera soportar.

Pues bien, IMaZMor es un intérprete de Máquina-Z para dispositivos móviles, concretamente para la plataforma J2ME, para dispositivos que soporten el perfil MIDP 1.0 ó superior.

Aquí podéis ver un par de capturas de IMaZMor ejecutando 'Wishbringer: The Magick Stone of Dreams', aventura de Infocom:



De momento, está lejos de ser una implementación completa, soporta un subconjunto de las instrucciones de dicha máquina virtual, y sólo permite ejecutar aventuras de la versión 3 de la Máquina-Z. Esto limita bastante la actual utilidad de este intérprete, ya que la mayor parte de las aventuras conversacionales para Máquina-Z publicadas hoy en día, son para la versión 5 de la máquina.

La mayor fuente de aventuras para la versión 3 de la Máquina-Z que se puede encontrar, son las recopilaciones de antiguos clásicos (de la década de los 80) de Infocom, que todavía siguen comercializándose pero también pueden adquirirse de segunda mano, como: 'The Comedy Collection', 'The Fantasy Collection', 'The Mystery Collection' y 'The Sci-Fi Collection'.

El código fuente de IMaZMor lo he liberado bajo la licencia GNU General Public License versión 2, y lo he publicado en un repositorio Git en Gitorious, donde ya alojé otros proyectos. La dirección del repositorio de IMaZMor es: http://gitorious.org/imazmor

Con esta acción, ahora cualquiera tendrá libre acceso al código fuente de este intérprete de Máquina-Z, igual que ya se hizo con otros intérpretes anteriores para J2ME, como ZeeME o Z2me. Ahora ya no cabe la posibilidad de que pierda el código de esta creación mía, y a la vez otros podrán colaborar conmigo en su desarrollo, o simplemente divertirse mientras la prueban.

Las herramientas necesarias para que podáis compilar vosotros mismos IMaZMor son: el Java Wireless Toolkit versión 2, de Sun Microsystems; y el preprocesador de C de GNU: CPP. Como explicaré en otra entrada, CPP lo utilizo como preprocesador para el código Java, permitiendo el uso de constantes de preprocesador y de compilación condicional, lo cual resulta en un ejecutable del programa más pequeño y eficiente.

Otra captura de IMaZMor en acción, esta vez mostrando el inicio de 'Ballyhoo':


Aprovechando que tengo otro teléfono móvil, uno que tiene pantalla táctil pero no tiene teclado ni botones, tengo en mente añadirle en un futuro próximo las siguientes características:
  • Soporte de impresión en modo gráfico (en principio, solamente con una fuente de tamaño fijo, ya que es más fácil de implementar), detectando la resolución de la pantalla. Hasta ahora, IMaZMor escribía los textos usando un formulario J2ME, pero esta característica de J2ME es tan limitada que no admite un scroll de texto adecuado y predecible, y tampoco permitía poner la línea de estado más que como título del formulario.
  • Scroll de texto funcional, que guarde las líneas de texto anteriores para poder verlas de nuevo y, sobre todo, que se espere en caso de llenarse la pantalla (de momento, lo que ocurre depende de cómo implementa Java cada teléfono, por lo general, o se queda al principio del todo siempre, o al final del todo en todo caso).
  • Soporte de pantallas táctiles. Al menos, mi intención es permitir que se pueda hacer scroll del texto de la aventura pulsando sobre la pantalla. Sobre permitir la entrada de órdenes de manera táctil también, ya veremos, lo haré según su dificultidad. Probablemente lo más sencillo sea implementar un teclado virtual, en caso de que no haya ninguna otra forma de entrada funcional para mi teléfono. Si implementara algo como T9, estaría bien utilizar el diccionario de la propia aventura para el completado.
Si hacéis alguna adaptación de este programa, haciendo cambios sobre el código, y queréis compartir vuestra versión modificada, agradecería que compartiérais el código primero conmigo, para así añadirlo al repositorio y que todos puedan aprovecharse de vuestras aportaciones.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

17 de enero de 2010

Unificación de blogs con Blogger

Después de haber metido la pata, por haber hecho la transferencia de entradas desde el blog 'El hombre imperfecto' hasta este blog de forma manual, copiando las entradas antiguas y pegándolas como entradas nuevas (en lugar de con su fecha original); he descubierto cuál era el modo correcto de realizar dicha labor con Blogger:

Blogger proporciona la opción de exportar e importar entradas, guardándolo todo (como las fechas y los comentarios) en un fichero xml. Esto permite hacer copias de seguridad de un blog, pero también lo que yo quería hacer: unificar mis dos blogs en uno. Esta opción se encuentra en el apartado Configuración del blog, en la primera pestaña: Básico, donde dice Herramientas de blog. Allí aparecen las opciones Importar blog, Exportar blog y Suprimir blog.

Precisamente esa última opción era la que iba buscando, para eliminar del todo mi antiguo blog, y entonces me he dado cuenta de que debería haber hecho la unificación de blogs de ese modo, con lo cual las entradas habrían aparecido en sus respectivas fechas de publicación original.

Por si a alguien le resulta útil, el modo correcto de unificar dos blogs con Blogger es el siguiente: usando las opciones que menciono antes, exportar las entradas del blog que queremos que desaparezca, e importar el fichero xml que se genere desde el blog que va a contener todas las entradas.

De todos modos, no todo estaba perdido para mí, ya que anoté la fecha original de las entradas de 'El hombre imperfecto' cuando las creé en 'El blog de Morgul', tecleando al principio de cada entrada su fecha original. Lo único que se ha perdido ha sido las horas de publicación, pero me las he inventado de forma creíble, así que nadie que no lea esto lo notará :-D

Sabiamente, he jugado con los ficheros xml exportados para modificar las fechas de las entradas, poniendo las fechas originales. Y tras eliminar las entradas nuevas, que aparecían con fecha de 8 de enero, he reimportado las entradas desde el fichero xml modificado a mano, con lo cual ahora las entradas del antiguo blog 'El hombre imperfecto' aparecen en su fecha original de publicación. Asunto solucionado.

Como ya no está tan clara la diferencia entre esas entradas que formaban parte de mi alter blog, y las entradas que siempre han sido de este blog, indicaré aquí los enlaces de las inmigrantes:
Ahora ya puedo decir adiós para siempre a 'El hombre imperfecto'.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

8 de enero de 2010

"Merge" de blogs

He decidido hacer un merge de mis dos blogs, es decir, fundir los dos blogs que tenía en uno solo. El blog que quedará será este mismo, y el otro desaparecerá una vez haya transferido sus entradas al blog que estás leyendo ahora.

El blog que desaparece se llamaba 'El hombre imperfecto', era el blog donde iba añadiendo entradas sobre mi desarrollo personal, tanto como hombre, ser humano y a nivel espiritual. Lo del desarrollo espiritual es algo que no había previsto y que me ha venido automáticamente, casi sin darme cuenta. De hecho, creo que en ese blog no llegué a comentar sobre ello.

Hay varios motivos para esta decisión de unificación. A grandes rasgos, podríamos decir que mi mentalidad y punto de vista respecto al otro blog ha cambiado en gran medida, y esto efectivamente se manifiesta ahora como un cambio palpable. Paso a detallar los cambios que me parecen importantes mencionar (al menos, para dejar constancia de ellos para mí):

  • Inicialmente, quería mantener mi identidad en el anonimato, dentro de lo posible, como autor del blog 'El hombre imperfecto'. Por eso creé dos blogs separados, uno para autosuperación y el otro (este mismo) para todo lo demás, donde en el primero me cubría en anonimato y en el otro me daba igual. Pues bien, ahora veo que no tiene ningún sentido ocultar mi identidad de ningún modo, no hay nada de vergonzoso ni de malo en superarse a uno mismo, y tampoco lo hay en reconocer mis defectos, tanto pasados como presentes.
  • El título del blog: ya no lo siento como algo que me identifique. Reconozco que aunque pueda parecer imperfecto en apariencia, de hecho puedo observarme como imperfecto en muchas ocasiones, esta no es la realidad a un nivel elemental. Aprovechando la jerga informática, diría que a bajo nivel, a nivel de Código Original (podría entenderse también como el código fuente de la Creación) soy absolutamente perfecto en todos los aspectos, sin excepción. La imperfección que veo en mí (o en cualquier otra cosa), es código imperfecto que oculta el código original (volviendo a la jerga informática, digamos que lo encapsula), causándome efectivamente (y a otros) la percepción de imperfección. Pero este código imperfecto puede eliminarse, cosa que no puede hacerse con el código original. Por tanto, entiendo que es contraproducente decir que soy imperfecto cuando en el fondo todo, absolutamente todo, es divinamente perfecto en esencia, y tengo intención y decisión de eliminar el código erróneo que oculta el Original en mi experiencia.
  • Ha habido varios cambios importantes en mí que me han proporcionado esta nueva perspectiva, como una mayor autoaceptación, mayor respeto y amor de mí hacia mí mismo, en general una mayor autoestima; y la aceptación, desapego y trascendencia de mi pasado (no soy mi pasado, no soy un cúmulo de experiencias, soy mucho más que eso, siempre lo he sido aunque no siempre fuera consciente de ello), además de otros avances a nivel espiritual (soy uno más de los muchos que están despertando actualmente, que son cada vez más y más), como la trascendencia progresiva del ego y una mayor consciencia y responsabilidad aplicada.
Es posible que en el futuro escriba alguna entrada en inglés, e incluso haga alguna bilingüe, puesto que una gran parte de mis fuentes de influencia por escrito son en inglés, y sería para mí absurdo limitarme a usar sólo el castellano, cuando con el inglés estoy dando bastante más por un poco de esfuerzo extra.

Dicho esto, comienzo a portar entradas antiguas del blog que eliminaré en breve, indicando la fecha de publicación original de cada una.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

5 de junio de 2009

Coloreando el Jabato

Hacía tiempo ya que tenía este artículo en mi lista mental de artículos por redactar, al final me decido a soltarlo para aligerar un poco mi lista mental de tareas - más grande aún que la de artículos - que deseo realizar.

Al parecer, la versión original con gráficos CGA de el 'Jabato', la aventura conversacional de Aventuras AD, sigue sin estar disponible (aunque hay posibilidades de que finalmente aparezca), como se puede comprobar en el foro de CAAD '¿varias versiones de El Jabato?'.

Sin embargo, este hecho ya no me importa del mismo modo. Esto se debe a que mis investigaciones del formato en que se almacenan las bases de datos de las aventuras hechas con el parser DAAD (las de Aventuras AD, como el 'Jabato'), conforme las he ido desarrollando, han dado más y más frutos (y cada vez, mi herramienta undaad está más y más formada, aunque de momento sea por piezas separadas).

Así que, os voy a dar una pequeña sorpresa... he llegado al punto en que soy capaz de crear mi propia versión de el Jabato con gráficos CGA, y de hecho esa tarea la tengo iniciada y perfectamente funcional.

¿Sorprendidos? Ahora pasaré a daros más detalles del logro:

He desvelado en gran medida el formato de los ficheros de gráficos CGA en las aventuras de DAAD, tanto el de pantalla inicial (la portada del juego), como los de las localidades y objetos. Lo logré investigando con bisturí en mano sobre la 'Aventura Original' de Aventuras AD que, en su versión DOS, solamente vino con gráficos CGA. Con mucha paciencia y esfuerzo, conseguí desarrollar y dejar totalmente operativo un extractor de gráficos CGA para las aventuras de DAAD (otro paso más para mi undaad).

En DAAD, los gráficos de portada de la aventura en CGA utilizan la clásica paleta con los colores: magenta, cyan, blanco y el color de fondo (normalmente, el color negro). Esto es, la paleta CGA por defecto, pero sin brillo (queda por confirmar si esto es así en todas las versiones de DAAD). El ser sin brillo, significa que los colores no son muy intensos, por lo que el blanco es más bien un tono grisáceo.

Aparentemente, para la portada no puede usarse ninguna otra de las paletas CGA. Sin embargo, y esto es algo importante puesto que parece que Aventuras AD jamás hizo uso de esta característica, puede cambiarse el color de fondo por cualquier otro de la paleta completa CGA (con o sin brillo). Como ejemplo, os mostraré una captura con mi versión CGA de portada para el 'Jabato':


Como podréis apreciar, esta imagen no tiene color negro. En su lugar, tiene un tono azul oscuro que, junto con el cyan, el magenta y el blanco (sin brillo todos), dan un resultado que habría sorprendido de haberse utilizado en su época, cuando teníamos nuestras tarjetas CGA.

Para crear esta portada, así como para el resto de imágenes que he creado para 'Jabato' en CGA, he utilizado los gráficos con mayor colorido del 'Jabato' (los gráficos de la versión de Amiga). Teniendo de antemano todas las posibles paletas CGA, y utilizando la utilidad convert, que forma parte del paquete de procesado de imágenes ImageMagick, decido y utilizo la paleta que queda estéticamente mejor para cada imagen. Luego aplico retoques manuales, por ejemplo para que la imagen muestre bien todos los detalles, o para que pueda compactarse bien (según qué tipo de imagen sea).

En DAAD, las imágenes CGA dentro del juego, aunque no pueden cambiar el color de fondo (siempre es el negro), sí se les permite elegir entre dos paletas distintas CGA con brillo: la de cyan, magenta y blanco; y la de rojo, verde y amarillo. No obstante, es el gráfico de localidad el que escoge la paleta, los gráficos de los objetos utilizarán (obviamente, sólo una paleta puede aparecer a la vez en pantalla) esta misma paleta. No es demasiado problema para que yo aproveche esta característica, como mostraré con capturas de pantalla en breve.

Por cierto, Aventuras AD sólo utilizó esta función (usar ambas paletas) para la Aventura Original, que no poseía gráficos de objetos. Bueno, sí que los tenía, pero como caracteres, no como gráficos. ¿Había comentado ya que también logré decodificar el fichero con la fuente tipográfica típica de las Aventuras de DAAD? :-D

Como paso final creativo, utilizo un par de utilidades programadas por mí, que más que formar parte de undaad, formarían parte de un freedaad u opendaad. La primera utilidad convierte una imagen (almacenada en algún formato de imagen de uso común, como BMP o PNG) a portada CGA de aventuras DAAD (tiene un formato especial). La segunda utilidad convierte un conjunto de imágenes (en formato de imagen corriente, también) a un fichero de base de datos de imágenes CGA con el formato soportado por DAAD.

Los resultados de mis esfuerzos saltan a la vista, he aquí una comparación entre la única imagen que ronda por Internet de la versión CGA del 'Jabato' original (arriba, pero ¡ojo! el colorido de esta imagen es aproximado, la captura está algo emborronada, apareciendo con más de cuatro colores) y la misma captura con mi versión CGA particular del 'Jabato' (en medio) y con la versión a todo color Amiga (abajo):


La fuente de la captura de pantalla de la versión original CGA de 'Jabato' es la siguiente URL: http://macedoniamagazine.frodrig.com/masalla/ma-jab.htm

A continuación, os mostraré para vuestro deleite un par de capturas más de mi versión CGA de 'Jabato', de las cuales la primera utiliza la paleta CGA alternativa (con rojo, amarillo y verde):


Vaya, acabo de darme cuenta que en la segunda imagen, el gráfico de localidad está corrupto por algún motivo, como se aprecia observando con detenimiento su parte derecha. Algún día lo corregiré, de momento tengo otras prioridades.

Bueno, esto es lo que tengo para enseñaros. Si queréis más, no dudéis en hacerme alguna donación a mi cuenta de Paypal, que es mi dirección de correo en Yahoo!: jmfo1982 algarroba yahoo puto es (evidentemente, es arroba en lugar de algarroba y punto en lugar de lo otro :) Prometo avanzar en mi incursión DAADera y mostraros más información ante cualquier donación recibida, en proporción a su cuantía.

¡Hasta la próxima aventura!

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

1 de mayo de 2009

300 Sudoku

Estoy muy contento. Ayer mismo terminé de preparar un libro de Sudoku, sobre el que llevaba meses trabajando de modo discontinuo en él. Es como un deseo finalmente hecho realidad... bueno, no 'es como', es un deseo finalmente hecho realidad :-)

Al final me decidí a publicarlo en Bubok, que viene a ser el equivalente español al mundialmente conocido servicio Lulu. El proceso de publicación en Bubok es muy sencillo, y te facilitan muchísimo el diseño de tapas (portada, lomo y contraportada), sin perder por ello funcionalidad, como la opción de personalizar las tapas del libro con las imágenes que tú proporciones y los textos que te plazcan.

Me llamó la atención uno de los temas por defecto para el diseño de portadas en Bubok, uno en azul con una foto de unas piedras en la portada. Pero no quería utilizar un diseño de portada estándar, ya que seguramente estaría demasiado visto. Así que me centré en el color, que ciertamente me gustaba, y busqué por Internet fotos en dominio público que pudieran quedar bien con el libro.

Después de un tiempo, vi que no había ninguna fotografía que me gustara más que la del tema de las piedras de Bubok. Entonces recordé lo que molaban las carátulas en que venía la distribución SuSE Linux, que compré hace bastantes años ya. Estas carátulas contenían gráficos hechos por ordenador, como de gráficas matemáticas que formaban figuras preciosas.

Actué sobre tal idea, poniéndome a buscar imágenes fractales. En poco rato, di con un fractal en color azul que me encantó. Y ya no busqué más, usé tal imagen para la portada y elegí otro tono de azul a juego para el fondo de la contraportada y del lomo.

Es posible que a alguien pueda interesarle, así que explicaré el pequeño truco que utilicé para cambiar el color de fondo en el apartado de diseño de tapas de Bubok. Bubok no permite cambiar el color de fondo sin más, pero sí permite elegir imágenes de fondo. Lo que se me ocurrió para cambiar el color de fondo fue crear con un programa de dibujo (en esos momentos tenía a mano el Paint, que viene con Windows) una pequeña imagen que había rellenado (pintada toda del mismo color) con el tono que me gustaba. Guardando la imagen como .PNG para que no perdiera calidad, subí esa imagen a Bubok, y el sistema estiró la imagen para que ocupara todo el espacio, quedando todo el fondo del color uniforme que deseaba.

Creo que me ha quedado muy chulo el libro, y espero impaciente el momento en que me llegue por correo convencional, ya que me he pedido una copia impresa. Tal vez se lo regale a alguien conocido a quien le guste los Sudoku, o a lo mejor me lo quedo para mí, jejeje.

Bueno, acabo de darme cuenta que no he puesto cómo conseguir el libro. Pues es muy sencillo, el libro se llama como el título de esta entrada, '300 Sudoku'. Como bien dice, son trescientos los Sudoku que contiene, más que de sobra para poder estarse una barbaridad de horas entretenido. Además, decidí poner tantos Sudoku por el aspecto económico: cuantos más Sudoku metiera en el libro, más barato sería el precio de cada puzzle. En este caso, el precio de cada Sudoku del libro sale por unos cinco céntimos de Euro, lo cual está muy bien, pocas cosas se encuentran a este precio hoy en día.

Como dice en la página del libro (http://www.bubok.com/libros/9995/300-Sudoku), he añadido todas las soluciones al final. No es mi intención que se usen para hacer trampas... Pero bueno, a veces cuando uno se atasca o enfada con un Sudoku que se resiste, consultar la solución resulta una vía de escape de frustraciones muy interesante ;-D

El libro lo podéis adquirir tanto en papel como en formato electrónico. En este último formato, el libro sale más barato, pero luego tendrás que buscar algún modo para poder escribir sobre el documento, problema que no aparece con los libros en papel de toda la vida. También podrías usar uno de esos libros electrónicos que permiten garabatear sobre el documento, si tienes uno. Y si no, alguna otra forma se os ocurrirá, seguro.

Quiero advertiros que los últimos Sudoku del libro seguramente os llevarán de cabeza, así que aprovecharé para recomendaros una página web que encontré hace tiempo con estrategias y técnicas para la resolución de Sudoku. Está en inglés, pero merece mucho la pena: http://www.scanraid.com/Strategy_Families. Es muy útil, y divertido a la vez, utilizar este tipo de estrategias, mucho más que resolver los Sudoku sólo por intuición y, por supuesto, muchísimo más que mirar las soluciones.

Desde luego, te sientes muy bien cuando consigues al fin resolver un Sudoku que te ha llevado varias horas de resolver, me encanta esa sensación de querer gritar "¡¡¡Ueeeee!!! ¡¡¡Al final lo logré!!!". Aunque luego no quieras ver otro Sudoku nunca más... ¿nunca más? Sí, sí, eso dura hasta que vuelves a ver el libro al día siguiente :-D

Espero que os guste el libro tanto como a mí creándolo. Ya me diréis qué os ha parecido. Sobre todo, me encantaría saber si alguien es capaz de resolver todos los puzzles, los trescientos. Si alguien lo consigue, me gustaría mucho que me lo hiciera saber. ¿Cuánto tardará alguien en lograr ese reto?

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

7 de marzo de 2009

Autoanálisis para el éxito

Ha pasado mucho tiempo. Ahora que miro atrás, a la época en que emprendí este blog, me doy cuenta de lo muchísimo que he avanzado, como hombre y como ser humano. El camino que inicié de manera un tanto tentativa, ha acabado mostrándose a sí mismo como el camino que está haciendo y hará que todos mis sueños se cumplan.

No me extenderé demasiado, por esta vez, respecto a en qué he mejorado y cómo ha mejorado mi vida en consecuencia. Esto lo dejo para entradas posteriores, porque sobre lo que deseo escribir ahora es sobre cómo he visto que debo autoanalizarme a mí mismo para descubrir (y posteriormente poder corregir) todas aquellas cosas que debo cambiar para lograr lo que realmente quiero en mi vida. De todos modos, mi actual intencionalidad y energía, dejarán patente en estas palabras mi mejora personal, para aquellas personas que lean esto.

Esta entrada la escribo más por mí que para otras personas, aunque en el fondo viene a ser lo mismo. Quiero dejar huella de esta intencionalidad en el universo, por así decirlo, para realmente aplicar a menudo en mi vida una metodología de autoanálisis como esta.

Es muy importante el enfoque y el momento para realizar autoanálisis productivos y efectivos. Cuando estoy fuera, expuesto a los designios del destino, no suele ser un buen momento para juzgarme ni autoanalizarme. Lo que corresponde a dicho momento es vivir el momento presente (si no sabéis a qué me refiero, recomiendo leer el libro 'El poder del ahora', de Eckhart Tolle), profundamente, descartando en caso necesario toda duda respecto a mí o respecto a lo que el destino me prepara.

El momento ideal, es un tiempo dedicado específicamente a este menester (al autoanálisis), tanto si ha sido decidido premeditadamente como espontáneamente. Como comenté en alguna entrada anterior, los momentos de lucidez que tengo nada más despertarme son ideales para autoanalizarme de modo positivo: con autoaceptación y aceptación de mi situación actual, respetándome completamente, viendo los lados positivos de todo, concretando lo negativo como algo que realmente deseo corregir, metiéndome en la piel de otras personas en caso necesario.

Para averiguar qué me queda por mejorar (lo que debería, para ser el mejor hombre que puedo ser, y que además es lo que de verdad quiero mejorar), lo que debo preguntarme es una combinación de lo siguiente:
  • ¿Cuál es la mentalidad que quiero tener? ¿Qué parte específica veo que aún no está del todo dentro de mi realidad? es decir, ¿en cuáles de estos pensamientos no creo todavía lo suficiente? Sé que debo enfocar mi mente para integrar estos pensamientos positivos, que formen parte de mi realidad. Por ejemplo, en mi caso, actualmente evito de vez en cuando mostrar mi opinión, como por miedo a crear confrontaciones; esto choca con la mentalidad que quiero tener de no tener miedo a nada, y de mostrarme tal y como soy.
  • ¿Qué espero de los demás? ¿Tengo para ellos el mismo trato que deseo de ellos para mí? Un ejemplo de mi situación actual: deseo que las chicas que estén interesadas en mí y yo en ellas, inicien conversaciones conmigo mostrando directamente la intención de conocerme. El caso es que hasta ahora yo no he hecho lo mismo con ellas (esta misma mañana me he dado cuenta), no estoy mostrándome de modo coherente con este deseo mío. Debo iniciar conversaciones con ellas de modo totalmente directo y honesto, mostrando lo que quiero, sin temor, siendo yo mismo. De hecho, nada tengo que temer, porque es muchísimo más importante el comportarme de modo coherente con mi mentalidad, que cualquier consecuencia inmediata que suceda en alguna de esas situaciones.
  • Y, en general: ¿Qué es lo que realmente deseo conseguir? ¿Me estoy alineando con estas cosas específicas que deseo? ¿Actúo coherentemente con cómo intento ser? ¿Vibran mis acciones con la intencionalidad de mis deseos? Tengo que alinearme con lo que deseo, mostrar al universo cuáles son mis intenciones, moverme para recibir lo que deseo conseguir.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

26 de enero de 2009

Vapores de Visual SINTAC 2

En pleno periodo de exámenes, escribo esta breve entrada para mostraros una visión que quiero compartir con vosotros, los vapores de un dragón imaginario... Visualizad conmigo lo siguiente:

Visual SINTAC 2.

El clásico español de la programación de aventuras conversacionales resurgido de sus cenizas una vez más, como el ave Fénix. Y una vez más, trayendo novedades interesantes, esta vez tanto desde el punto de vista del programador como el del jugador. Damos un repaso a su lista de características nuevas más destacadas:

- Multiplataforma. Tanto el intérprete como el entorno visual de desarrollo están implementados con KBasic: un entorno tipo BASIC (compatible en gran medida con el mítico Visual BASIC, despedazado tiempo ha por Visual BASIC .NET) que se apoya en la librería Qt para ofrecer portabilidad trivial hacia sistemas UNIX, Windows y MAC OS X.

- Todo el código fuente sito en un repositorio público, como en Gitorious, por ejemplo. La licencia del mismo sería establecida por acuerdo con el autor original, Javier San José (el cual, una vez más, se desentiende de esta criatura... pero no por mucho tiempo, porque al final le terminará recuperando el cariño que le tenía).

- Mayores capacidades multimedia. Soporte de los formatos de audio, imagen y vídeo más populares, pero sólo de aquellos que realmente merecen la pena en todo caso: los que son abiertos, están libres de patentes y con implementaciones de código fuente abierto con soporte para la mayor parte de las plataformas soportadas por Visual SINTAC 2.

- Visual, pero sólo opcionalmente. El entorno de desarrollo visual es una opción más, no la única, puesto que es posible programar una aventura completamente usando tu editor de textos favorito, y ejecutando el compilador/empaquetador desde la consola, si así lo deseas. Con este movimiento, se abren las puertas a los programadores de aventuras invidentes, así como a los que tienen alergia a los sistemas de ventanas. Siguiendo esta misma línea de razonamiento, se ofrece también:

- Versiones alternativas del intérprete. Permitiendo jugar desde un entorno gráfico, (con lo que se puede disfrutar de toda la multimedia que ofrezcan las aventuras de Visual SINTAC 2), así como desde la consola, en modo sólo texto... o, también, en modo sólo texto y audio.

- Mayor número de autores que nunca. Cuatro. Contando a los tres autores de las versiones anteriores de Visual SINTAC: JSJ, Uto y un servidor. Esperemos que esta situación cambie en el futuro.


Eso es todo, de momento. Me parece bastante factible, sobre todo si KBasic es realmente compatible con Visual BASIC. Si queréis que lo lleve a cabo, sabed que admito donaciones ;-) (a pesar del guiño, todo esto lo digo muy en serio).

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

30 de noviembre de 2008

Cómo usar fuentes TrueType en PDFLaTeX

El otro día estuve investigando el modo de poder utilizar fuentes tipográficas TrueType (con extensión de fichero .ttf) para los documentos PDF que genero desde LaTeX, mediante sus herramientas PDFLaTeX o PDFeLaTeX. Por cierto, mi distribución LaTeX es TeTeX, que está siendo sustituida hoy en día por TeX Live, puesto que su autor ha dejado de mantenerla.

La información que aparece al respecto en los primeros resultados de búsqueda de los buscadores web más conocidos está en gran parte obsoleta, puesto que fue redactada más de cinco años atrás y las herramientas que utilizaban en aquella época ya no funcionan del mismo modo (por ejemplo, aceptan distintos parámetros desde la línea de comandos).

Después de un buen rato probando distintos métodos antiguos en vano, al final encontré una página web que estaba más al día con respecto a las herramientas y versiones de LaTeX que existen actualmente (en inglés): http://tclab.kaist.ac.kr/ipe/pdftex.html

Gracias al tutorial 'Using a Truetype font in Pdflatex' sito en esa misma página, conseguí por fin utilizar fuentes TrueType desde LaTeX. Sin embardo, tuve que deducir a base de prueba y error el procedimiento preciso para conseguir esto, puesto que ese tutorial no muestra el suficiente detalle para poder reproducir la proeza. Por tanto, para que no se me olvide y por si a alguien más le resulta útil, redactaré aquí de un modo sencillo y paso por paso cómo hice para conseguir usar fuentes TTF con LaTeX.

El sistema con el que he trabajado es una Gentoo Linux, con la distribución (de LaTeX) TeTeX, versión 3.0 (versión del ebuild de Gentoo: 3.0_p1-r6). Sin lugar a duda, la metodología que voy a describir servirá para otras versiones de TeTeX, posiblemente también sirva para otras distribuciones de LaTeX (si os funciona en otra, hacédmelo saber) y, por supuesto, será independiente de la distribución de Linux.
  1. Crea un carpeta de trabajo temporal, copia en ella el fichero con el tipo de letra TrueType que quieras utilizar con LaTeX. Desde ahora supondremos que este fichero se llama fuente.ttf
  2. Comprueba si tu sistema dispone de la herramienta ttf2tfm. Por ejemplo, intenta ejecutarla desde la línea de comandos, con la orden ttf2tfm. Si ya dispones de ella, descarga el fichero T1-WGL4.enc desde esta URL hasta la carpeta de trabajo temporal y salta al paso 12.
  3. Comprueba que tienes la herramienta de control de versiones CVS instalada, así como un entorno de desarrollo GCC funcional. Esto es un requisito, por lo que será necesario que instales lo que le falte a tu sistema.
  4. Desde la consola, cambia a un directorio de tu elección donde tengas permisos de escritura.
  5. Descarga el código fuente de la versión 1 de la librería FreeType desde su repositorio CVS, con el siguiente comando: cvs -z3 -d:pserver:anonymous@cvs.savannah.nongnu.org:/sources/freetype co freetype
  6. Accede al nuevo directorio freetype con: cd freetype
  7. Descarga el código fuente de las herramientas adicionales para la versión 1 de la librería FreeType desde su repositorio CVS, con el siguiente comando: cvs -z3 -d:pserver:anonymous@cvs.savannah.nongnu.org:/sources/freetype co freetype1-contrib
  8. Dale permisos de ejecución a los dos ficheros configure que utilizaremos, con la orden: chmod +x configure freetype1-contrib/ttf2pk/configure
  9. Compila la librería FreeType 1, con: ./configure y a continuación: make
  10. Compila la herramienta ttf2tfm, cambiando primero al directorio donde se encuentra: cd freetype1-contrib/ttf2pk y ejecutando: ./configure y a continuación: make. Si todo ha ido bien, el ejecutable de la herramienta ttf2tfm estará en esta carpeta.
  11. Copia a la carpeta de trabajo temporal el fichero T1-WGL4.enc, que estará en el directorio .../freetype/freetype1-contrib/ttf2pk/data
  12. Accede a la carpeta de trabajo temporal y convierte el fichero de tipo de letra TrueType al formato tfm, ejecutando la orden: ttf2tfm fuente.ttf -p T1-WGL4.enc (debes añadir la ruta al ejecutable ttf2tfm en caso necesario).
  13. Crea un fichero de texto con nombre t1fuente.fd (cambia fuente según corresponda), con el siguiente contenido:
    \DeclareFontFamily{T1}{fuente}{}
    \DeclareFontShape{T1}{fuente}{m}{n}{
    <-> lhandw
    }{}
    \DeclareFontShape{T1}{fuente}{bx}{n}{<->ssub * fuente/m/n}{}
    \DeclareFontShape{T1}{fuente}{m}{it}{<->ssub * ptm/m/it}{}
    \DeclareFontShape{T1}{fuente}{m}{sl}{<->ssub * ptm/m/sl}{}
    \DeclareFontShape{T1}{fuente}{m}{sc}{<->ssub * ptm/m/sc}{}
    \DeclareFontShape{T1}{fuente}{bx}{it}{<->ssub * ptm/b/it}{}
    \DeclareFontShape{T1}{fuente}{bx}{sl}{<->ssub * ptm/b/sl}{}
    \DeclareFontShape{T1}{fuente}{bx}{sc}{<->ssub * ptm/b/sc}{}
    \pdfmapline{+fuente\space
  14. Copia desde la carpeta de trabajo los ficheros fuente.ttf, fuente.tfm, t1fuente.fd y T1-WGL4.enc a la carpeta donde se encuentre el código fuente de tu documento LaTeX. El resto ficheros en la carpeta de trabajo temporal ya pueden eliminarse, así como también el código fuente de FreeType, a menos que quieras aplicar el proceso a más fuentes TrueType.
Con esto, ya podrás utilizar esta fuente TrueType como cualquier otra fuente incluida en tu distribución LaTeX, teniendo en cuenta que su codificación es T1. Por ejemplo, puedes usar la fuente temporalmente en una sola frase usando el siguiente código LaTeX:
{{\fontencoding{T1}\fontfamily{fuente}\selectfont Esto es una prueba tipográfica.}}

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

23 de noviembre de 2008

MUnDoCAAD MUD Engine: pasado y presente

Se ha notado muchísimo que he sido el único desarrollador del motor del MUD para nuestro 'MUnDoCAAD' (el MUnDoCAAD MUD Engine), así como que no tenía mucha idea de cómo implementar un MUD... muestra de ello ha sido el largo tiempo que me ha llevado programar algo funcional, elegante y potente.

MUnDoCAAD MUD Engine nació en enero de 2003 (edito: aunque partes de él fueron programadas en 2002), escrito en C++ y usando tanto sockets POSIX como WinSocks (que eran un churro, puesto que se comían toda la CPU con madalenas al esperar en las llamadas select), según la plataforma de compilación usada (UNIX o Windows, respectivamente). Más tarde descubrí que la librería Qt proporcionaba manejo de sockets y otras abstracciones del sistema operativo que harían el código compatible no sólo en sistemas UNIX y Windows sino también para Mac OS, así que reescribí parte del código para hacerlo más portable utilizando la Qt.

La pega de la Qt - versión 3 en aquél entonces - era que requería enlazar con las librerías de interfaz gráfica, y ejecutarse desde X Window en sistemas UNIX, a pesar de que el motor del MUD no era más que una aplicación de consola.

Luego salió la versión 4 de la librería Qt, que permitía por fin independizarse de las librerías de interfaz gráfica. Mejoró mucho el código del motor del MUD por aquél entonces, pero sobre todo mejoró mi comprensión de qué debería tener el motor funcionalmente para manejar un MUD. Gracias a la Qt, ya me despreocupaba en gran medida del aspecto de comunicaciones en red, y mis ideas de diseño giraban en torno al almacenamiento de la base de datos del MUD y su cacheo en memoria (para evitar tener en memoria toda la base de datos se utilice o no, y no tener que estar guardando a disco constantemente las modificaciones realizadas).

Desde los inicios, pensé usar XML para almacenar las entidades (objetos, localidades, personajes y demás) del MUD en la base de datos. Creo recordar que llegué a implementar completamente la carga y almacenamiento de entidades con la librería libxml2, aunque revisando el historial del repositorio CVS de nuestro proyecto en SourceForge no encuentro dicha evidencia. En cuanto empecé a usar la librería Qt para el motor, me aproveché de las clases para el manejo de documentos XML que trae esta, de manera bastante similar a como se hacía con la libxml2.

Sin embargo, era relativamente lento cargar y escribir documentos XML para el poco contenido que tenía cada uno (los datos propios de cada entidad del MUD, pues pensé en almacenar cada una en un fichero aparte). No obstante, al tener el sistema de caché ya implementado (de nombre Archivero, en memoria de El Viejo Archivero), este amortiguaba un poco este impacto de coste temporal.

Llegué al punto en que tuve que plantearme cómo implementar la librería base, también llamada el modelo de mundo. No podía implementarla como el resto del motor, usando C++, puesto que cualquier cambio implicaría tener que recompilar y reiniciar el motor del MUD para que surtiera efecto. Debía utilizar algún lenguaje interpretado, que fuera ejecutado desde el motor del MUD. Pero yo no sabía ni quería embarcarme en la costosa tarea de inventar un lenguaje para el MUD.

Más tarde, descubría la librería QSA: Qt Scripting for Applications. Esta me proporcionaba un lenguaje interpretado y un intérprete para ejecutar su código desde aplicaciones que usaran la librería Qt. "Genial" - pensé, y me puse a implementar la librería base del MUD con este lenguaje, muy similar a C++ (el lenguaje era un subconjunto de ECMAScript, íntimamente relacionado con JavaScript).

Pronto descubrí limitaciones en esta forma de implementación del motor del MUD. Al parecer, QSA por aquella época tenía ciertos fallos al convertir variables y objetos del lenguaje QSA a variables Qt, y tuve que hacer apaños para solventar dichos problemas. Para colmo, QSA hacía que tuviera que volver a enlazar con librerías de interfaz gráfica, aunque esta vez no me obligaba a ejecutar el motor del MUD desde X Window en mi entorno de desarrollo Linux.

Por todo esto, y por la infactibilidad de la ejecución de código almacenado en las entidades de la base de datos (código relacionado con la reacción de las entidades ante acciones de los personajes o del modelo de mundo) de manera elegante y potente, abandoné por completo el desarrollo del MUD.

Por suerte, durante los dos siguientes años a este abandono, he descubierto el lenguaje Python y lo fácil y rápido que es programar en él. Era cuestión de tiempo que me planteara intentar reescribir MUnDoCAAD MUD Engine por completo en Python, así como usar Python mismo como el lenguaje interpretado embebido en las entidades del MUD.

Y así fue, hace unos pocos meses atrás ya estaba implementando una caché LRU para almacenar las entidades. Después vino la implementación del módulo Archivero (reutilicé el nombre de su predecesor en C++/Qt), utilizando mi flamante caché LRU en Python. Esta vez descarté usar XML como formato de los ficheros de entidad, a pesar de tener buen soporte en Python, porque no quería que fuera costosa la lectura y escritura de cada entidad de la base de datos, y utilicé en su lugar las ventajas del módulo cPickle de Python.

Los resultados eran más que satisfactorios: código sencillo, funcional y rápido de desarrollar. El mismo código que empezaba a escribir como prueba (en plan chapucilla) de la funcionalidad que quería, terminaba convirtiéndose en poco tiempo en código correcto y completo funcionalmente.

Hace unas pocas semanas, empecé a escribir lo que sería el nuevo módulo Servidor del mud, usando la implementación de sockets que trae Python. Tan sencillo empezó siendo este módulo, que sólo permitía una conexión simultánea al MUD, y durante bastante tiempo siguió así, como un motor para aventuras conversacionales tradicionales (de un sólo jugador) que requería conectarse por Telnet para jugar.

Se me ocurrió implementar la aventura conversacional del tutorial 'La Torre - Contruye tu propia aventura' creado por Uto para NMP y adaptado a InformATE! por Zak, porque quería comprobar si el nuevo motor en Python era capaz de dar vida a algo jugable. Inicié una base de datos de MUD con las entidades de la aventura de este tutorial, así como un parser (analizador sintáctico) muy sencillo de tipo VERBO + NOMBRE, y una librería modelo de mundo con vistas a que el juego eventualmente pudiera ser utilizado por varios jugadores a la vez.

Estaba tan contento de ver que todo funcionaba bien y que el motor Python era perfectamente capaz, que quería enseñárselo a mis colegas del CAAD, y les hablé de él en el canal de IRC y de su posible futura evolución. Esto ocurría ya hace menos de una semana. Para poder enseñar mi creación tenía que hacer que pudiera conectarse más de un jugador a la vez, así que implementé un módulo Servidor que atendiera las conexiones de red del MUD, para lo cual utilicé el módulo asyncore de Python en lugar de trabajar con los sockets directamente.

Aumenté la librería base y el parser para que los jugadores pudieran ver cómo los personajes cambiaban de localidad y añadí el comando decir, para que pudieran hablar entre ellos. Hice una invitación en el IRC, y se apuntaron unos cuantos a probar el nuevo MUD. Inmediatamente relució un fallo en el código de la librería base, ya que nombraba a los personajes así: "Aquí está un Juan, un Pepe y un Jacinto", en lugar de decir: "Aquí está Juan, Pepe y Jacinto". Corregí este fallo en un periquete, y descubrí que conforme estaba implementado el motor, para que la corrección surtiera efecto sólo podía reiniciar el MUD.

Estando el MUD con jugadores conectados, no es una opción factible echarlos a todos cada vez que se haga una corrección a la librería del modelo de mundo o a alguna otra parte del motor. Así que investigué un poco e implementé un módulo (Restaurador) que recarga a petición del administrador los módulos del motor del MUD que se deseen, incluido él mismo. Desde entonces el MUD puede mejorarse dinámicamente, sin necesidad de reinicios.

Algunos jugadores tenían problemas para leer y escribir tildes y eñes en el MUD, debido a que ellos usan la codificación de caracteres UTF-8 y el motor trabaja con ISO-8859-15. Así que también añadí a MUnDoCAAD MUD Engine la capacidad de realizar conversión de código de caracteres para aquellos jugadores que así lo deseen.

Básicamente, el motor del MUD en Python cuenta con toda la funcionalidad de su predecesor en C++/Qt, además de tener nuevas características que difícilmente habría podido implementar en aquél (ahora obsoleto) motor. Podría decir que este es el mejor MUD que he creado nunca :)

Por cierto, el código fuente del nuevo motor Python es GPL versión 2 (igual que el antiguo), y ya está disponible en el repositorio Subversion del proyecto en SourceForge: https://sourceforge.net/projects/mundocaad

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

31 de octubre de 2008

MiPDF 1.0 RC 2 liberado

Anoche mismo liberé una nueva versión de mi visor de documentos PDF para la consola portátil abierta GP2X, MiPDF versión 1.0 RC 2. La podéis encontrar en el siguiente enlace del magnífico repositorio de aplicaciones GP2X Archive: http://archive.gp2x.de/cgi-bin/cfiles.cgi?0,0,0,0,4,2593

Toda la documentación del programa sigue todavía en inglés (así como la descripción que hago de ella en el GP2X Archive), cosa que cambiaré seguramente con la próxima versión que libere, añadiendo un leeme.txt en castellano en el archivo ZIP.

Los cambios significativos en esta versión de MiPDF son los siguientes:
  • Reducido el consumo de las pilas cuando la aplicación está ociosa (cuando no está haciendo nada), porque ya no hace una espera activa de eventos.
  • Cambio de zoom ligeramente más rápido, ya que he quitado una carga de página redundante, que sólo era necesaria cuando se está cambiando de página.
  • El cambio de zoom ahora recuerda la posición de la página que estaba mostrando, por lo que ya no volverá a la esquina superior izquierda de la página con cada cambio de zoom.
Quedo a la espera de alguna donación en mi cuenta PayPal que me motive a seguir mejorando este visor de PDF, el más rápido que existe hasta el momento para la GP2X. Me desilusiona que la gente lo utilice y lo aprecie pero nadie haya donado ni un mísero céntimo :'(

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

15 de octubre de 2008

Google Chrome (experimental) para Linux y Mac OS X

Mientras Google informa que Google Chrome para sistemas GNU/Linux y Mac OS X se está retrasando porque quieren adaptarlo convenientemente a las características únicas de estos sistemas operativos, los usuarios se están impacientando e intentan hacer funcionar de todos modos este navegador en su sistema operativo favorito. Actualmente, se ha conseguido resultados positivos al respecto de tres maneras distintas:

Compilando el estado actual del código fuente de Chromium (proyecto de código fuente abierto que hay detrás de Chrome) en su repositorio Subversion. Google ofrece instrucciones detalladas (en inglés) para realizar esta operación tanto en sistemas Linux como en Mac OS X. El principal defecto de esta aproximación es que el código de Google Chromium es más inmaduro para sistemas Linux y Mac de lo que es para Windows.

Ejecutando la versión de Google Chrome para Windows con la ayuda de Wine (implementación libre de la API de Windows). El proyecto Wine ha incluido correcciones y mejoras últimamente para soportar mejor este navegador, como muestra explícitamente el registro de cambios de su versión 1.1.4. No obstante, el funcionamiento de Chrome bajo Wine deja bastante que desear.

La tercera opción consiste en utilizar una versión de Google Chrome que una lo mejor de las dos aproximaciones anteriores: CrossOver Chromium. CrossOver Chromium, desarrollado por CodeWeavers, es una versión del navegador de Google que utiliza el código fuente de Google Chromium para Windows (la plataforma soportada de forma más madura por Chrome a día de hoy), pero compilado con la API de Wine, con lo que queda una aplicación nativa de Linux o Mac OS X muy similar a la versión de Windows.

Esta última aproximación es la que considero la mejor para los impacientes, aunque reconozco que visualmente tiene ciertos defectos, como podréis comprobar en la captura que incluyo al final de la presente entrada. Si habéis probado Chrome en Windows, funcionalmente también notaréis alguna que otra deficiencia menor.

Yo, en cambio, tengo mucha paciencia; así que seguiré con mis navegadores habituales en Linux (Seamonkey y Konqueror) y esperaré a una versión oficial de Google Chrome para GNU/Linux. Mientras tanto, cuando ocasionalmente utilice Windows, utilizaré tanto Chrome como Firefox, con lo cual seguramente se cure mi alergia al Internet Explorer ;)


¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

5 de octubre de 2008

Reparando MLDonkey 2.9.5

Al final he conseguido volver a hacer funcionar mi MLDonkey. Fallaba con una violación de segmento a los pocos segundos de arrancarlo, desde que lo actualicé a la versión 2.9.5. Llevaba ya unos cuantos meses sin poder usarlo por estos motivos, limitando mi uso del Peer to Peer (P2P) a la red Torrent, gracias a mi siempre fiel (y funcional) cliente KTorrent.

El sistema operativo que utilizo es una Gentoo Linux de 64 bits (tengo un procesador AMD64). Lo digo por si alguien tiene el mismo problema, que pruebe a hacer lo que cuento aquí para evitarlo (si te funciona, me alegrará que me lo hagas saber ;).

Ayer se me ocurrió probar a cambiarle el nombre al directorio de configuración de MLDonkey (originalmente .mldonkey en mi directiorio personal), y probar a arrancar de nuevo el ejecutable mlnet (el que arranca MLDonkey desde la consola), para que se iniciara con la configuración por defecto. Cuál fue mi sorpresa al comprobar que ya no daba ninguna violación de segmento, ni aun esperando varios minutos.

A continuación, fuí cambiando una por una las opciones de configuración (desde la interfaz web de MLDonkey), restaurando manualmente los valores que tenía antiguamente. Todo fue perfecto, hasta que llegué a modificar la opción max_upload_slots, que indica el número máximo de subidas simultáneas que quieres permitir. Anteriormente, tenía puesto el valor 3, y el valor por defecto es 5, así que lo cambié por 3 y pulsé Enter (así es como adopta MLDonkey los valores de configuración que cambias desde la interfaz web).

Pero esta vez no apareció ningún mensaje de confirmación en mi navegador web. De hecho, la interfaz web dejó de funcionar completamente. Eché un vistazo a la consola desde la que había lanzado mlnet, y me encontré de nuevo el mensaje de la violación de segmento (segmentation fault en inglés). Mmm... curioso - pensé.

Volví a repetir la operación de intentar cambiar el valor de max_upload_slots a 3, y de nuevo ocurrió la violación de segmento (pobre segmento, jejeje). Y en seguida se me ocurrió probar qué ocurría si cambiaba dicho parámetro de configuración a su valor por defecto (cinco) en la configuración original de MLDonkey que durante meses no me había servido para nada. Borre el recién creado .mldonkey, cambié el nombre del viejo a .mldonkey otra vez, y modifiqué a mano en el fichero downloads.ini dicho parámetro max_upload_slots al valor 5.

Ejecuté de nuevo mlnet. Y... voilà: ¡MLDonkey completamente funcional de nuevo!

En resumen, que MLDonkey (en mi sistema y desde la versión 2.9.5) petaba por no admitir un valor 3 en su parámetro de configuración max_upload_slots. Ya he informado al equipo de desarrollo con un informe de error (donde comento todo esto en inglés), en su bugtracker (sistema de recopilación y manejo de informes de error).

Espero que lo corrijan para su próxima versión 2.9.7.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

Presentando mi blog

Hola a todos. Este es el comienzo de 'El blog de Morgul', un blog donde iré publicando cosas que me interesan a mí, y que seguramente interesen a muchas personas más ;) Probablemente, este blog sustituirá a mi caduca web 'La página web de Morgul', con más diversidad y contenido que nunca ha tenido esta.

Con esta breve introducción, un servidor se despide hasta la próxima entrada.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar

15 de septiembre de 2008

Adiós buen chico

Me encanta tener momentos de inspiración como este. Acabo de estar otra vez en la cama, tumbado boca arriba, los ojos abiertos, sin sueño... pero con una gran sonrisa dibujada en mi cara.

Me he regalado una visualización, la cual relataré a continuación. Podéis seguirla con vuestra imaginación, disfrutando como yo lo he hecho, y como vuelvo a hacer ahora, añadiendo todavía más detalles.

Estoy estudiando en la biblioteca, sentado en una buena posición: tengo a la vista a (y estoy a la vista de) una chica que me gustaba hace tiempo... cuando era tan buen chico y no sabía sino estropear las situaciones habidas y por haber, con mis enamoramientos inoportunos y mi afición de informar de dichos sentimientos precipitados.

Estoy disfrutando de mi estudio, me encanta aprender, no puedo evitar tener una medio sonrisa en mi cara. Levanto un rato la vista, observo a mi alrededor. Fantástico cruce de miradas entre los dos. Ella aparta la mirada primero. Yo sonrío para mí mismo.

En un pestañeo, una idea pasa por mi cabeza. No dudo de ella ni pienso nada más. La pongo en práctica al instante...

Me levanto, me dirijo hacia ella, ella me ve, sabe que me acerco, con paso firme, momento de tensión. Pero no me paro, paso junto a ella.

Sé lo que hago. Voy a los servicios, pero no para hacer un uso convencional de ellos. Me miro ante el espejo, a los ojos, luego sólo a mi ojo derecho. Me gusta lo que veo, no puedo sino sonreír a mi propia imagen. No existe nadie más en esos servicios, sólo yo y mi imagen del espejo. Me digo en voz alta: pero qué bueno que estoy.

Salgo de los servicios, me paso por la fuente y bebo un trago. Subo de nuevo a la zona de la biblioteca donde estaba estudiando. Paso por detrás de la chica que me gusta. Me paro a un escaso medio metro de ella, a su lado, sigo encarando al sitio donde voy: mi sitio de estudio.

Ella sabe que estoy ahí, ha dejado de estudiar, no sabe si mirarme o no. Giro la cabeza, no puedo evitar sonreír. La chica levanta la mirada, nuestros ojos se cruzan. El tiempo se para, nadie más existe, sólo ella y yo. Ambos nos maravillamos de la otra persona.

Le digo: "me gustaría decirte una cosa". Ella pone cara de curiosidad, abre los labios, está a punto de preguntar. No le doy tiempo. Vuelvo la mirada y continúo caminando hacia mi sitio.

Me siento, vuelvo a mis estudios. Otra idea pasa por mi cabeza. De nuevo, actúo. Cojo un trozo de papel, me dispongo a escribir algo en él. Arranco ese trozo de papel y lo pliego sobre sí mismo.

Camino de nuevo hacia ella. Sin pararme, le dejo el papel sobre sus apuntes. No espero su reacción. Me dirijo hacia las escaleras. Sonrío más que nunca, casi evitando reírme... no había escrito nada en el papel.

Esta vez me voy fuera, a tomar un poco el aire y descansar. Me tomo mi tiempo.

Al rato vuelvo a la biblioteca. Me aseguro de que ella sigue en su sitio, pero voy directo al mío. Me siento, y empiezo a recoger mis cosas. Sé que me está mirando. Termino de recogerlo todo. Levanto la mirada, y le pillo mirándome. Sonrío más. Voy hacia ella.

Le digo: "me voy". Ella me dice: "¿qué querías decirme?". Le digo, lo sabrás a su debido momento. Entonces, hago lo que acababa de decirle, me voy.

¿Continuará?

Sí, esto tiene muy buena pinta. Sé exactamente qué quería decirle, pero no os lo diré todavía ;)

Adiós buen chico. Siempre te recordaré. Me caías bien, igual que a casi todo el mundo. Te doy las gracias por el drama que has ido añadiendo a mi vida... sí, gracias de corazón. Me has ayudado a madurar. Unas lagrimillas se forman inevitablemente en mis ojos al releer esto.

Hola tío bueno. Me gustas. Me gusto. Me quiero.

¿Te ha gustado esta entrada? Vótala en Bitacoras.com: Votar