Estoy pensando en escribir un pequeño juego de aventuras basado en texto, pero no estoy particularmente seguro de cómo debería diseñar el mundo desde un punto de vista técnico.
Mi primer pensamiento es hacerlo en XML, diseñado algo como lo siguiente. Disculpas por la gran cantidad de XML, pero me pareció importante explicar completamente lo que estoy haciendo.
<level>
<start>
<!-- start in kitchen with empty inventory -->
<room>Kitchen</room>
<inventory></inventory>
</start>
<rooms>
<room>
<name>Kitchen</name>
<description>A small kitchen that looks like it hasn't been used in a while. It has a table in the middle, and there are some cupboards. There is a door to the north, which leads to the garden.</description>
<!-- IDs of the objects the room contains -->
<objects>
<object>Cupboards</object>
<object>Knife</object>
<object>Batteries</object>
</objects>
</room>
<room>
<name>Garden</name>
<description>The garden is wild and full of prickly bushes. To the north there is a path, which leads into the trees. To the south there is a house.</description>
<objects>
</objects>
</room>
<room>
<name>Woods</name>
<description>The woods are quite dark, with little light bleeding in from the garden. It is eerily quiet.</description>
<objects>
<object>Trees01</object>
</objects>
</room>
</rooms>
<doors>
<!--
a door isn't necessarily a door.
each door has a type, i.e. "There is a <type> leading to..."
from and to are references the rooms that this door joins.
direction specifies the direction (N,S,E,W,Up,Down) from <from> to <to>
-->
<door>
<type>door</type>
<direction>N</direction>
<from>Kitchen</from>
<to>Garden</to>
</door>
<door>
<type>path</type>
<direction>N</direction>
<from>Garden</type>
<to>Woods</type>
</door>
</doors>
<variables>
<!-- variables set by actions -->
<variable name="cupboard_open">0</variable>
</variables>
<objects>
<!-- definitions for objects -->
<object>
<name>Trees01</name>
<displayName>Trees</displayName>
<actions>
<!-- any actions not defined will show the default failure message -->
<action>
<command>EXAMINE</command>
<message>The trees are tall and thick. There aren't any low branches, so it'd be difficult to climb them.</message>
</action>
</actions>
</object>
<object>
<name>Cupboards</name>
<displayName>Cupboards</displayName>
<actions>
<action>
<!-- requirements make the command only work when they are met -->
<requirements>
<!-- equivilent of "if(cupboard_open == 1)" -->
<require operation="equal" value="1">cupboard_open</require>
</requirements>
<command>EXAMINE</command>
<!-- fail message is the message displayed when the requirements aren't met -->
<failMessage>The cupboard is closed.</failMessage>
<message>The cupboard contains some batteires.</message>
</action>
<action>
<requirements>
<require operation="equal" value="0">cupboard_open</require>
</requirements>
<command>OPEN</command>
<failMessage>The cupboard is already open.</failMessage>
<message>You open the cupboard. It contains some batteries.</message>
<!-- assigns is a list of operations performed on variables when the action succeeds -->
<assigns>
<assign operation="set" value="1">cupboard_open</assign>
</assigns>
</action>
<action>
<requirements>
<require operation="equal" value="1">cupboard_open</require>
</requirements>
<command>CLOSE</command>
<failMessage>The cupboard is already closed.</failMessage>
<message>You closed the cupboard./message>
<assigns>
<assign operation="set" value="0">cupboard_open</assign>
</assigns>
</action>
</actions>
</object>
<object>
<name>Batteries</name>
<displayName>Batteries</displayName>
<!-- by setting inventory to non-zero, we can put it in our bag -->
<inventory>1</inventory>
<actions>
<action>
<requirements>
<require operation="equal" value="1">cupboard_open</require>
</requirements>
<command>GET</command>
<!-- failMessage isn't required here, it'll just show the usual "You can't see any <blank>." message -->
<message>You picked up the batteries.</message>
</action>
</actions>
</object>
</objects>
</level>
Obviamente, tendría que haber más que esto. La interacción con personas y enemigos, así como la muerte y la finalización son adiciones necesarias. Como el XML es bastante difícil de trabajar, probablemente crearía algún tipo de editor mundial.
Me gustaría saber si este método tiene alguna desventaja, y si hay una forma "mejor" o más estándar de hacerlo.
c#
xml
text-based
adventure-games
Polinomio
fuente
fuente
Respuestas:
Si no estás completamente casado con C #, entonces la forma "más estándar" de hacerlo es utilizar una de las muchas herramientas de creación de aventuras de texto que ya existen para ayudar a las personas a hacer exactamente este tipo de juego. Estas herramientas le brindan un analizador que ya funciona, manejo para la muerte, guardar / restaurar / deshacer, interacción de personajes y otras funcionalidades de aventura de texto estándar similares. En este momento, los sistemas de autor más populares son Inform y TADS (aunque también hay media docena de otros disponibles)
Inform puede compilarse en la mayoría de los conjuntos de instrucciones de máquina virtual de Z Machine utilizados por los juegos de Infocom, o en los conjuntos de instrucciones de máquina virtual glulx más recientes. TADS, por otro lado, compila en su propio código de máquina virtual.
Los intérpretes de ficción interactivos más modernos pueden ejecutar cualquier tipo de binario (en los viejos tiempos, a menudo se necesitaban intérpretes separados para los juegos de TADS de los juegos de ZMachine de los juegos de glulx. Pero afortunadamente, esos días ya han terminado). Los intérpretes están disponibles por solo sobre cualquier plataforma que quieras; Mac / PC / Linux / BSD / iOS / Android / Kindle / browser / etc. Así que ya tienes una plataforma multiplataforma bien cuidada.
Para la mayoría de las plataformas, el intérprete recomendado actualmente es Gargoyle , pero hay muchas otras, así que no dude en experimentar.
La codificación en Inform (especialmente la última versión) lleva un poco de tiempo acostumbrarse, ya que se está promocionando más a los autores que a los ingenieros, por lo que su sintaxis parece extraña y casi conversacional. En la sintaxis de Inform 7, su ejemplo se vería así:
Mientras que TADS se parece más a un lenguaje de programación tradicional, y el mismo juego en TADS se ve así:
Ambos sistemas están disponibles gratuitamente, se usan con mucha frecuencia y tienen una gran cantidad de documentación tutorial (disponible en los enlaces que proporcioné anteriormente), por lo que vale la pena echarles un vistazo y elegir el que prefiera.
Tenga en cuenta que los dos sistemas tienen comportamientos estándar sutilmente diferentes (aunque ambos pueden modificarse). Aquí hay una captura de pantalla del juego que se está jugando, tal como se compiló de la fuente Inform:
Y aquí hay uno del juego que se está jugando (dentro de un terminal; la tipografía puede ser mucho mejor que esto), tal como se compiló de la fuente de Tads:
Puntos interesantes a tener en cuenta: TADS le ofrece una pantalla de 'puntaje' en la parte superior derecha de forma predeterminada (pero puede desactivarla), mientras que Inform no (pero puede activarla). Informar le informará por defecto los estados abiertos / cerrados de los elementos en la descripción de la habitación, Tads no. Tads tiende a tomar acciones automáticamente por ti para ejecutar los comandos del jugador (a menos que le digas que no lo haga), donde Inform tiende a no hacerlo (a menos que se lo digas).
Cualquiera de los dos se puede usar para hacer cualquier tipo de juego (ya que ambos son altamente configurables), pero Inform está más estructurado para producir ficción interactiva de estilo moderno (a menudo con rompecabezas mínimos y más estilo narrativo), donde TADS está más estructurado hacia la producción de aventuras de texto a la antigua (a menudo fuertemente centradas en acertijos y definiendo rigurosamente la mecánica del modelo mundial del juego).
fuente