miércoles, 29 de abril de 2009

Gráficos con Inkscape

Llevo cosa de un mes usando Inkscape, a la par que Urbatain (lo cual habrán notado por su serie de pruebas de concepto de El Anillo).

Haciendo los gráficos para "La venganza de Yan", empecé con un estilo sencillo para poder ir rápido. El caso es que cuando vas cogiendo destreza, puedes hacerlo menos sencillo sin perder velocidad.
He usado mucho del reciclaje de siluetas para abarcar las diferentes localidades de una misma zona.
Por ejemplo, para dibujar un bosque pinto unos pocos modelos de follaje, ramas y troncos, y lo que sigue es un copy-paste a lo bestia. Una vez compuesta la escena, se copia y se reordena todo para hacer otra localidad.

Y no todo es Inkscape. Aunque es ideal para dibujar las siluetas y calcar de imágenes... para los retoques finales o para dibujar las sombras de los personajes es preferible usar un programa de retoque fotográfico, a base de máscaras.
Así lo estoy haciendo finalmente, tras una fase incial de intentar obtener el acabado definitivo con el propio Inkscape.

El nivel de calidad ha ido in-cresccendo, y eso se nota comparando los primeros dibujos con los últimos. Las primeras localidades voy a tener que redibujarlas porque se han quedado muy atrás.






El tamaño de los gráficos es de 720 x 195 px

lunes, 6 de abril de 2009

La Venganza de Yan

Estos días estoy programando una historia que se me ocurrió el jueves. La programación va a buen ritmo, sólo que me falta por planear las secuencias finales (que no el final). Realmente ha ido saliendo todo improvisado a partir de la idea general.
La ambientación está inspirada en un antiguo largometraje animado chino llamado "Taro el niño Dragón (Tatsunoko Taro)"... aunque de la inspiración a la expiración hay un trecho ;D

Por fín voy a implementar para algo más que para juegos de palabras lo que aprendí del código de "Ad Verbum": para conversaciones con PSIS y como apoyo a otros objetos del juego, para poder especificar detalles sin necesidad de crear nuevos objetos ligados.

Se trata de un parseado en paralelo, que no suplanta sino que complementa, un parseado de reconocimiento de cadenas o de trozos de texto.
Inform funciona igual que siempre, sólo que cuando quiero le consulto al otro parseado qué ha encontrado, y así puedo dar mejores respuestas a las cosas que me interesen.

He dispuesto 5 variables que recolectan los valores coincidentes del parseado en paralelo, y son estas variables las que se consultan luego desde el código de los objetos y las funciones.

Es un sistema a la vieja usanza. Te tienes que haces una tabla y apuntar qué número está representando a qué concepto (uso "concepto" para describir un grupo de palabras o cadenas que vienen a ser sinónimas en el contexto del juego). Y a la vez escoger bien cómo haces las listas, en qué orden pones las cadenas en el código y cuál de las 5 variables será la encargada de almacenar cada tipo de concepto. En principio una variable cazará conceptos referidos a pronombres, otra cazará partículas interrogativas, otra acciones, otra nombres y otra adjetivos, en principio, porque en la práctica se mezcla todo un poco para aprovechar donde no se necesita y no se prevee que haya conflicto.

La detección de cadenas se realiza por barrido secuencial, no por el orden en que ha sido escrito, sino por el orden en el que cada cadena está escrita en el código. Cada variable adquiere el valor del último concepto coincidente de su lista personal. De modo que si dos cadenas vitales están en la misma lista, la variable sólo almacenará la que esté más abajo en el código.

Así he empezado a programar y ya es tarde para cambiarlo, pero explicaré un sistema mejor:
En lugar de unas pocas variables para muchos conceptos...
Una variable para cada concepto, y claro, no usaremos variables sino Flags (banderas), que apenas usan memoria. Puedes crear 5000 flag y el parser ni pestañea.

De esta forma, antes de cada input ponemos todos los Flags encargados de pescar conceptos en false, y procedemos a hacer el barrido.

En nuestro código del PSI, tendremos cosas como éstas:
react_before[;
hablar:
print "Pepito dice:^";
if(FlagOn(100) && FlagOn(156)) "Me llamo Jhames.";
if(FlagOn(101) && FlagOn(157)) "El pescador se llama Josema.";
if(FlagOn(111) && FlagOn(157)) "¡¿Cómo que quieres matar al pescador?!.";
],


Como decía, hay que tener la chuleta al lado, y veremos las cadenas que activan cada flag:
Flag 100: llama*, nombre
Flag 111: mata*, asesina*, liquid*
Flag 156: tu, usted, te
Flag 157: pesc*d*r



(*) Como esto va por fragmentos, los asteriscos los he puesto a modo representativo para que se vean las partes que se pueden omitir sin problemas. Para palabras largas, para preveer varias flexiones... simplemente detectas las letras de la palabra que son fijas y que son imprescindibles para distinguirla de otra similar.
También se puede fijar la longitud.
Podemos detectar de un plumazo "amigo" y "amiga", programando la detección de "a"+"m"+"i"+"g+"+longitud=5.
Aunque para este ejemplo, lo dejaríamos en "a"+"m"+"i"+"g". Ya que la secuencia "amig" no presenta demasiado riesgo de confundirsem (o estar fundida dentro) con otra palabra. Sin determinar la longitud, el Flag saltaría a la que el jugador escribiera "amigo", "amiga", "amigos", "amigas", "amigable", "amigablemente"... etc

Y así funciona. Que el parser detecte que quieres que "Fulano te acompañe hasta el rio cantando una canción, con las manos en la cabeza y dando saltitos" es posible técnicamente, aunque aviso que no pienso implementar chorradas de ese estilo XD.

La máxima utilidad es distinguir intenciones y preguntas respecto a sujetos.
Puedes decir "Fulano"... ¿Fulano qué?
Dónde vive Fulano.
Quién es Fulano el de la derecha.
Quién es Fulano el de la izquierda.
...
La espada de Fulano... ¿qué pasa con la espada de fulano?
Dame la espada de Fulano
Encuentra la espada de Fulano
Fulano no tiene espada
...
Quiero matar a Fulano.

Hoygan nesesito un krak para Fulano es urjente.

Fuera de las conversaciones, esto sigue siendo muy útil. Por ejemplo, para un combate:
Tenemos un objeto "troll" y queremos poder elegir a dónde le atizamos con la espada.
Normalmente habría que crear un objeto "mano", un objeto "brazo", un objeto "pestaña"...

Con este sistema simplemente creamos el objeto "troll", así:
object Troll "Troll" limbo
with name 'troll' 'planseldon',
adjectives 'mano' 'manos' 'brazo' 'brazos' 'pierna' 'piernas' 'derecha' 'izquierda' 'pestaña',
before[;
Attack: print "Golpeas al troll en ";
if(FlagOn (50))"una mano.";
if(FlagOn (51))"un brazo.";
if(FlagOn (52))"una pierna";
!etc
"una parte al azar de su cuerpo.";

],
has animate scenery talkable;


Nuevamente tendríamos que mirar la lista para ver qué activa cada flag. Pero en este caso, del propio código se deduce:
Flag 50: mano*, dedo*
Flag 51: brazo*, codo*
Flag 52: pie/, pies/, pierna*
!etc

Resúmen de lo que hemos hecho:
  1. Un único objeto
  2. Introducimos los nombres de todos los blancos o subelementos en la propiedad 'adjectives' para que el parser trague con ellos (recordemos cómo funciona Inform, el parseado en paralelo "detectacascajos" actúa de apoyo, pero no sustituye) (*** ver NOTA1 al final)
  3. En el código del objeto consultamos las pesquisas que ha realizado el parseado en paralelo de detección de cadenas, a ver si "ha pescado algo". De ser así, podemos programar fácimente una respuesta personalizada, y si no, dejamos que salte la respuesta estandar.

*** NOTA1:
El código del Troll arriba expuesto sólo es viable-razonable en un modo de parseado tal que la propiedad adjectives no tenga la misma jerarquía que la propiedad 'name' sino que sea dependiente. ('adjectives' sólo se consulta si antes ha habido coincidencia en la propiedad 'name')
En caso contrario, el código expuesto es inviable, pues estaría abierto a disparates tales como escribir "ex pestaña" y recibir la descripción del troll".

***NOTA2:
El código para realizar este parseado "bruto" tipo PAWS en paralelo está expuesto AQUÍ, aunque en la versión "poco óptima", usando unas pocas variables en lugar de millones y millones de Flags.

jueves, 2 de abril de 2009

Nearco 3

Nearco 3 me ha gustado por su sentido del humor, consigue unos puntos muy buenos sobre todo con el uso de sonidos.
El problema de esta aventura es la rigidez de su parseado. Peor que algo programado en BASIC por reconocimiento de cadenas, ya que aquí, además de reconocer unas pocas cadenas, tu comando se va al traste si introduces algo de más que el parser no entiende o intentas expresarte de otra forma. La lista de acciones es muy pobre.
Si bien esto al principio no es gran impedimento para la jugabilidad. Tomas consciencia de las limitaciones y te atienes a ellas.
El problema gordo vino casi al final del juego, con un puzzle para el que había con interaccionar con algo que ni si quiera aparecía mencionado en la descripción de la localidad.
Eso por un lado. Por otro, el objetivo de ese puzzle era conseguir un material que estaba presente en otros puntos del juego.
Entonces, por un lado te encuentras con que no puedes obtener ese material de las otras fuentes lógicas porque el autor no ha programado esa posibilidad. Y el lugar de donde lo tienes que obtener es invisible, tienes que suponer que existe eso en esa localidad o recordar un texto de transición de una escena que no vuelve a repetirse y donde se menciona que eso existe.

Posteriormente, Jhames, el autor, defiende la interactividad de su aventura poniendo unos ejemplos que ya hacen caer rayos al nubarrón que tenía en la cabeza a raíz de lo citado anteriormente.

La interactividad no es poder examinar una gaviota, ni tener prevista una respuesta por defecto para "cantar" o para intentar coger el sol.
La interactividad implica que el jugador tiene información suficiente para interactuar y los objetos responden a los intentos de interactuación en base a sus posibilidades y cualidades.

Una red no es interactiva aunque se pueda examinar, máxime cuando necesitas un trozo de cuerda y ni se ha contemplado la posibilidad de obtenerla de ese objeto. ¿Y eso por qué? Porque el autor ha previsto que la cuerda se obtiene de otro sitio, porque sí.
También podrías necesitar un palo y, pese a estar rodeado de árboles, ramas y palos, la única solución posible sea darle un objeto a alguien para que éste te dé el palo. Perfectamente comprensible...

Tampoco es muy interactivo al día de hoy que el parser no entienda formas alternativas (nada rebuscadas) de expresar una orden, o no entienda nada en absoluto si te da por añadir un adjetivo, un complemento genitivo de más, una palabra de más (de más para la estrechez del parser).

Eso sí, reconozco que me he pasado un pelo...

jueves, 26 de marzo de 2009

ranking de mejores aventuras en la wiki

Planseldon anuncia en el foro del CAAD su intención de abrir un ranking de "las mejores aventuras de todos los tiempos"...
... y aparece hasta Jhames para quejarse de que nadie juega sus aventuras.

lunes, 23 de marzo de 2009

adaptaciones conversacionales de otros géneros

En un foro del CAAD sobre la Retrocomp-09, salió el tema de la adaptación al formato conversacional de otro tipo de juegos, aventuras gráficas, videoaventuras...
Cualquier juego podría adaptarse... pero no todos los juegos ofrecerían un resultado interesante. Unos pocos quizá podrían ganar con el cambio.

Estaba pensando en "The Trap Door", un viejo juego de 8 bits que cuenta con dos partes, aunque me atendré a la primera.

El juego está basado en una serie de dibujos animados con muñecos de plastilina... horrible y cataléptica. El juego en cambio estaba bastante bien.
El protagonista se llama Berk, un bicho azul, fofo y achuchable, que habita en un lóbrego sótano trabajando como sirviente de "La cosa de arriba". La Cosa se comunica a gritos con Berk, desde las dependencias de lo alto del castillo: "¡¡ Berk tráeme el desayuno!!" "¡¡Qué demonios esperas!!".
Junto con Berk, viven en el sótano del castillo Boni la calavera sabionda -que da consejos- y Drutt, un arácnido saltarín -que da saltos y se zampa cuanto gusano pilla. También hay una trampilla "The Trap Door", que en teoría Berk no debe abrir, ya que a través de ella pueden escapar todo tipo de monstruos de las mazmorras más profundas.

En cualquier caso, en el juego tendremos que abrirla pues algunos de esos seres de la oscuridad no ayudarán o servirán para preparar los menús que La Cosa de Arriba solicita a Berk.

Berk puede moverse a dercha, izquierda, alante y atrás, subir y bajar escaleras, coger y soltar cosas, meter cosas en contenedores, volcar contenedores para desparramar su contenido, empujar objetos, y accionar palancas.

La misión del juego es preparar a La Cosa de Arriba todos los deliciosos platos que nos encargue antes de que su paciencia se agote. Esto son: un bote de gusanos, zumo de ojos, unos huevos fritos, y una olla de babosas hervidas.



El problema del juego es que era terriblemente lento de movimiento, con sus grandes sprites. En modo conversacional ganaría velocidad y ampliaría el rango de acciones posibles.

lunes, 16 de febrero de 2009

portadas estilo años 80

En este post del foro del CAAD se habla de las portadas, y sale el tema de las pechugas como reclamo publicitario en numerosos juegos de los 80.
Y me he permitido la licencia de hacer este pequeño fake para un juego actual de Jhames:


La portada original es del Barbarian.

Falta de jugadores

Esta serie es la secuela de este artículo de Planseldon sobre el déficit de jugadores: