example - Game Logic en archivos XML
xml example (5)
Estoy tratando con archivos de diálogo del juego (conversación entre jugadores y personajes no jugables) donde las elecciones de diálogo y su resultado dependen de ciertas condiciones y dan como resultado ciertas acciones. Ahora, podría escribir un analizador simple para manejar algún tipo de lenguaje para especificar las condiciones previas y posteriores, pero un amigo mío sugirió usar XML. Las condiciones se pueden almacenar como atributos de un elemento de diálogo y las elecciones y acciones son elementos internos. Luego usaría una función eval para analizar estas condiciones y afirmaciones (estoy usando Ruby para hacer este juego). Para simplificar dicho enfoque, podría escribir una GUI simple para manipular estos archivos sin preocuparme por XML feo.
Pero me parece una elección extraña manejar la lógica en archivos XML. Tengo entendido que los archivos XML son para el almacenamiento y el intercambio de datos, y siempre leo discursos acerca de cómo la gente usa en exceso XML para todo tipo de cosas para las que no fue diseñado. Mis amigos responden señalando cómo se usa XML para todo, incluido XHTML y este lenguaje de descripción de viñetas (que también ilustra cierta lógica).
Para ser sincero, usar XML me simplificaría muchas cosas. Escribir un analizador puede ser doloroso y lento, y mis requisitos son generalmente simples. Pero, ¿está realmente bien o lamentaría tal elección más adelante?
Para las personas interesadas en los detalles, esto es lo que podría ser un intercambio de diálogo básico en un archivo XML:
<dialogue id="101" condition="!npc.carsFixed">
<message>Man, fix my car!</message>
<choices>
<choice condition="hero.carFixingSkill > 5" priority="7" id="Sure!">
<command>hero.carFixingSkills += 1</command>
<command>npc.carFixed = true</command>
<command>hero.playSmokeAnimation()</command>
<command>nextDialogue = 104</command>
</choice>
<choice condition="hero.carFixingSkill <= 5" id="I can''t...">
<command>nextDialogue = 105</command>
</choice>
<choice id="Fix it yourself">
<command>npc.likesHero -= 1</command>
</choice>
</choices>
</dialogue>
El código correspondiente si está escrito en Ruby sería:
def dialogue101
if !npc.carsFixed
showMessage("Man, fix my car!")
choices = []
if hero.carFixingSkill > 5
choices.push(Choice.new("Sure!", 7))
else
choices.push(Choice.new("I can''t"))
end
choices.push(Choice.new("Fix it yourself"))
choices = selectTopPriority(choices) if choices.size > 4
result = showChoices(choices)
case result
when "Sure"
hero.carFixingSkills += 1
npc.carFixed = true
hero.playSmokeAnimation
dialogue104
when "I can''t"
dialogue105
when "Fix it yourself"
npc.likesHero -= 1
end
end
end
Cosas como likesHero y carFixingSkills son piezas de conocimiento que los jugadores y los NPC pueden tener, que probablemente se almacenarán en hash en la implementación real. Encuentro que el enfoque del archivo de diálogo es más flexible porque podría hacer un editor para editar fácilmente el diálogo y las condiciones / acciones, y debido a la naturaleza compleja de los árboles de conversación de juegos. Un lenguaje de guiones como Ruby o Lua ayuda, pero requerirá estructuras complejas para manejar la lógica de tales árboles.
Volviendo a la pregunta original, ¿XML es la herramienta adecuada para el trabajo o me falta algo?
Como estás escribiendo esto en Ruby, creo que hacerlo en XML debería ser suficiente. De esta forma, podría crear una aplicación web que le permita trabajar en el diálogo y la lógica del juego desde cualquier lugar. Y otras personas pueden colaborar contigo, o posiblemente crear mods de usuario, lo que siempre es un plus.
Siempre y cuando mantenga sus archivos XML bien organizados (los diagramas de flujo en papel ayudarán) no debería encontrarse con ningún problema, e incluso podría agradecerse a sí mismo por soportar el dolor de analizarlo :)
Para obtener inspiración, o tal vez incluso adopción, eche un vistazo a AIML y BuddyScript. AIML es XML para chatbots, BuddyScript es otra variante, ahora propiedad de Microsoft.
La siguiente es una muestra de AIML de http://www.alicebot.org/aiml.html
<category>
<pattern>WHAT ARE YOU</pattern>
<template>
<think><set name="topic">Me</set></think>
I am the latest result in artificial intelligence,
which can reproduce the capabilities of the human brain
with greater speed and accuracy.
</template>
Si integraras la tecnología AIML (que creo que es gratis) en tu juego, tus NPC tendrían IA con la que tus jugadores podrían hablar. ¿No sería interesante?
AIML es modular, por lo que todos sus NPC podrían tener un archivo común que describa todos los conocimientos estándar sobre su mundo. Luego, podría agregar archivos específicos para las cosas que serían típicas para cada raza, clase, lugar, individuo o tarea. Hay muchos ejemplos interesantes de archivos AIML, por ejemplo, Eliza.
La información de situación se puede agregar al inicio de una conversación, y es posible que tenga algún software fuera del motor de AIML escuchando palabras "mágicas" del NPC que indiquen que el NPC quiere que algo suceda en el mundo del juego "real". como "*** DAR JUGADOR 20 ALAS DE BÚFALO".
Si no has oído hablar de YAML, échale un vistazo. Es como XML, pero XML no está hecho para ser escrito a mano, es una interfaz máquina-máquina que resulta legible para el ser humano (por lo que se supone que debes crear un editor para él). YAML es una interfaz hombre-máquina, mucho más grabable.
No me molestaría con un DSL, YAML mapas perfectamente.
Un DSL sería una implementación de Mercedes-Benz para esto y sería divertido escribir en Ruby. Tienes razón, tomaría mucho trabajo, pero podría valer la pena si estaba bien escrito y este juego realmente despegó.
Una cosa a considerar si va a la ruta XML es el analizador / motor que usará para representarlo. La última vez que revisé, REXML fue el único programa de la ciudad para Rubyists. Si te gusta REXML, XML parece un buen camino a seguir, pero si no lo has probado, te sugiero que lo hagas antes de tomar esta decisión. No estoy eligiendo REXML, solo aconsejo un poco de precaución ya que dependerá completamente de esta biblioteca, sea lo que sea que use.
A menos que su juego tenga menos de media docena de diálogos únicos, definitivamente debe poner esta información en algún tipo de archivo de datos. XML es un fuerte contendiente para el formato. No hablo Ruby, por lo que puede no funcionar en este caso, pero otra opción sería definir el diálogo como datos directamente en el código de Ruby. (Sé que esto funcionaría bastante bien en Lua, Python y Javascript ... Supongo que definir estructuras de datos anidados también es fácil en Ruby).
Usamos archivos XML para definir todos los datos estáticos en Pirates of the Burning Sea, y fue una gran manera de hacerlo. Tener un formato de datos como este permite a los no programadores controlar los datos y libera a los programadores para trabajar en las características en lugar de la entrada de datos. Tener esos archivos de datos como texto significa que puede mantenerlos bajo el control de la fuente para que pueda saber cuándo cambian.