next up previous contents
Next: Apéndices Up: Esquema general de Minë Previous: Construcción de un área   Contents

Subsections

3 Contribuir con código

El código fuente de Minë

Ésta es la otra forma de ayudar al proyecto Minë. Puedes incorporarte al equipo de programadores y escribir código fuente del programa. Tenemos una lista de correo especialmente dedicada a tratar este tipo de temas (que a los usuarios normales no les importan en absoluto) ambar-dev@mail.freesoftware.fsf.org.

El código fuente de Minë es 100% python. Utilizamos python como lenguaje de programación por motivos históricos (el fundador del proyecto, Pablo Ruiz Múzquiz comenzó a programar 'ambar' -precursor de Minë- en python) y por motivos prácticos (python resuelve con elegancia muchos de los problemas que aparecen en el diseño de un juego de estas características, es multiplataforma y la curva de aprendizaje es muy suave, lo que facilita nuevos colaboradores).

También utilizamos XML para los ficheros fuente de las salas, PNJs y objetos ya que apostamos por estándares asentados y versátiles.

El mapa del código

Para no perdernos en el proceloso mar de líneas de código (actualmente los ficheros fuente de Minë ocupan cerca de 10.000 líneas), mantenemos a modo de mapa un diagrama de clases, hecho con UML. La última versión está disponible en la página electrónica de Minë, http://eutherpe.org/desarrollo.html.

Los diagramas muestran el diseño de alto nivel del programa, y son imprescindibles para conocer su estructura, antes de empezar a leer las clases de una en una. Hay tres grandes bloques:

Image mine.png

Modelo de datos

Éste es el bloque más significativo, que contiene el diseño conceptual. Cada clase de aquí representa una entidad del juego tal como lo ven los usuarios (personajes, salas, objetos...).

Image mine-modelo.png

El diagrama se lee mejor de arriba a abajo. Al principio parece un poco confuso, pero todos los elementos tienen un sentido intuitivo.

El Mundo es único y representa eso, todo el mundo de Minë y lo que hay en él. Contiene una lista de Salas (el rombo en UML significa contener), y cada Sala, a su vez, contiene personajes: los personajes que se encuentran dentro de esa sala. Los Objetos ahora no están modelados del todo, pero en principio podrán estar dentro de una Sala o de un Personaje.

Un Personaje, a su vez, puede ser PersonajeJugador o PersonajeNoJugador (la línea de puntos con un triángulo, en UML, significa subclasificación). Todos los personajes conocen de 1 a 5 idiomas, y los jugadores tienen además una Raza y una Profesión.

Finalmente, todo Personaje es manejado por un objeto Controlador, que es quien le da las ordenes de lo que debe hacer, y a quien informa de las cosas que le ocurren. Controlador no es una clase, sino un interfaz, lo que significa que no contiene código, sino sólo la declaración de qué métodos debe tener una clase que pueda controlar Personajes. Las clases que implementan ese interfaz pertenecen al siguiente bloque del diagrama.

Hay algunas asociaciones más entre clases, que se pueden entender observando el código fuente. Las clases que tienen un único rectángulo (por ejemplo ConnectionHandler) no pertenecen a este diagrama, se muestran aquí sólo para poder ver las asociaciones.

Control.

Este bloque es un poco más abstracto. Contiene las clases que llevan el control del programa y la interacción con el jugador.

Image mine-control.png

La clase Mine es el programa en sí. Es el fichero que se ejecuta al inicio y contiene el bucle principal. Inicializa el Mundo y los InterfacesPJ (las flechas punteadas en UML representan una asociación no permanente).

Un InterfazPJ es el objeto que controla a un PersonajeJugador. Acepta conexiones telnet para recibir comandos de un jugador y enviarle sus respuestas, y también da órdenes al personaje y recibe los "sucesos" o "eventos" que éste genera.

La funcionalidad de un InterfazPJ, al ser bastante complicada, está repartida en diferentes Diálogos. Cada Dialogo es una "máquina de estados" que representa una situación de diálogo con el jugador (por ejemplo, creación de un personaje nuevo, juego normal, modo combate, etc.).

Una máquina de estados es un objeto que tiene un "estado" en cada momento, y responde a "sucesos" que le ocurren bien cambiando a otro estado o realizando una acción. Por ejemplo, en el dialogo "crear un pj", al entrar en estado 1 pregunta el nombre del pj, y espera que ocurra algo. Si el jugador teclea un nombre correcto, lo registra y pasa al estado 2. Si teclea un nombre incorrecto (que ya existe, por ejemplo), devuelve un mensaje de error y continúa en estado 1.

Un InterfazPNJ tiene la misma misión, pero esta vez sobre un PersonajeNoJugador. La diferencia es que no tiene ningún socket telnet, sino que las órdenes a ejecutar las decide un programa de inteligencia artificial (más o menos "inteligente").

Infraestructura

En este bloque tenemos clases que representan conceptos genéricos que tienen más relación con el sistema operativo que con un juego MUD.

Image mine-infraestructura.png

ConnectionHandler y Connection representan "sockets" TCP/IP, es decir, los canales de comunicación que implementan el protocolo telnet, usado para hablar con los jugadores.

TimerHandler y Timer son temporizadores, o cronómetros, útiles para medir tiempos. Utils es un módulo "cajón de sastre" para meter funciones sencillitas y variadas.

Entendiendo el código

Hemos seguido unas reglas básicas de codificación, para mantener un estilo coherente en distintos ficheros hechos por diferentes programadores. En primer lugar, tenemos un fichero fuente por cada clase, con el mismo nombre de la clase en minúsculas (p. ej. la clase DialogoCrear está en dialogocrear.py). Todos los ficheros tienen al principio la nota de "CopyLeft", el comentario que indica su contenido, los import, y la clase. Todas las clases tienen un bloque de comentarios explicando la clase con detalle. Al final se incluye un trozo de código para pruebas unitarias del módulo.

Al escribir el código se siguen unas normas de diseño, que se pueden consultar en el apéndice titulado Normas de diseño de código fuente de Minë.

Al leer el código es fundamental leer las clases siguiendo el diagrama, de arriba a abajo, y leer y entender en primer lugar la cabecera donde se explica qué representa, y cuales son sus atributos.

El bucle principal del programa está en mine.py, pero casi no hace falta ni que lo mires. El programa se comporta como si todos los objetos del sistema estuvieran "vivos" y funcionando al mismo tiempo. Cuando ocurre cualquier cosa, el objeto correspondiente recibe un mensaje de "evento", es decir, "alguien" llama a un método de un objeto diciéndole que ha ocurrido algo (al principio no es necesario que sepas quién es ese alguien). Por ejemplo, si un jugador escribe algo desde su terminal, el objeto de tipo InterfazPJ correspondiente a ese jugador recibe una llamada al método comando_recibido().


next up previous contents
Next: Apéndices Up: Esquema general de Minë Previous: Construcción de un área   Contents
Pablo Ruiz 2002-08-25