Estou pensando em escrever um pequeno jogo de aventura baseado em texto, mas não tenho muita certeza de como devo projetar o mundo do ponto de vista técnico.
Meu primeiro pensamento é fazê-lo em XML, projetado algo como o seguinte. Desculpas pela enorme pilha de XML, mas achei importante explicar completamente o que estou fazendo.
<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, haveria mais do que isso. A interação com pessoas e inimigos, bem como a morte e a conclusão são adições necessárias. Como o XML é bastante difícil de trabalhar, eu provavelmente criaria algum tipo de editor mundial.
Gostaria de saber se esse método tem alguma queda e se existe uma maneira "melhor" ou mais padrão de fazê-lo.
c#
xml
text-based
adventure-games
Polinomial
fonte
fonte
Respostas:
Se você não está completamente apegado ao C #, a maneira "mais padrão" de fazer isso é usar uma das muitas ferramentas de criação de aventura de texto que já existem para ajudar as pessoas a fazer exatamente esse tipo de jogo. Essas ferramentas oferecem a você um analisador que já funciona, manipulação para morte, salvar / restaurar / desfazer, interação de caracteres e outros bits padrão semelhantes de funcionalidade de aventura de texto. No momento, os sistemas de criação mais populares são o Inform e o TADS (embora existam meia dúzia de outros disponíveis também)
O Inform pode compilar na maioria dos conjuntos de instruções da máquina virtual Z Machine usados pelos jogos da Infocom ou nos conjuntos de instruções da máquina virtual glulx mais recentes. O TADS, por outro lado, compila em seu próprio código de máquina virtual.
Qualquer um dos tipos de binários pode ser executado pela maioria dos intérpretes de ficção interativa modernos (antigamente, você costumava precisar de intérpretes separados para jogos TADS dos jogos ZMachine e glulx. Mas, felizmente, esses dias estão basicamente terminados agora.) Os intérpretes estão disponíveis por apenas sobre qualquer plataforma que você deseja; Mac / PC / Linux / BSD / iOS / Android / Kindle / navegador / etc. Portanto, você já tem uma boa plataforma cruzada e realmente se importa.
Para a maioria das plataformas, o intérprete atualmente recomendado é Gargoyle , mas há muitos outros. Portanto, à vontade para experimentar.
A codificação no Inform (especialmente a versão mais recente) leva um pouco de tempo para se acostumar, já que é mais voltada para os autores do que para os engenheiros e, portanto, sua sintaxe parece estranha e quase conversacional. Na sintaxe do Inform 7, seu exemplo seria assim:
Enquanto o TADS se parece mais com uma linguagem de programação tradicional, e o mesmo jogo no TADS se parece com o seguinte:
Ambos os sistemas estão disponíveis gratuitamente, são usados com muita frequência e possuem uma grande quantidade de documentação tutorial (disponível nos links que forneci acima); portanto, vale a pena conferir os dois e escolher o que você preferir.
Observe que os dois sistemas têm comportamentos padrão sutilmente diferentes (embora ambos possam ser modificados). Aqui está uma captura de tela do jogo em execução, compilada na fonte Inform:
E aqui está um do jogo que está sendo jogado (dentro de um terminal - a tipografia pode ser muito melhor do que isso), conforme compilado da fonte do Tads:
Pontos interessantes a serem observados: o TADS fornece uma exibição de 'pontuação' no canto superior direito por padrão (mas você pode desativá-lo), enquanto o Inform não (mas você pode ativá-lo). O Inform informará por padrão os estados de itens abertos / fechados na descrição do quarto, o Tads não. Tads tende a executar ações automaticamente para você, a fim de executar comandos do jogador (a menos que você diga para não), onde o Inform tende a não fazer (a menos que você diga).
Qualquer um pode ser usado para criar qualquer tipo de jogo (pois ambos são altamente configuráveis), mas o Inform é mais estruturado para produzir ficção interativa no estilo moderno (geralmente com quebra-cabeças mínimos e mais narrativa no estilo), onde o TADS é mais estruturado para produzir aventuras de texto à moda antiga (muitas vezes fortemente focadas em quebra-cabeças e definir rigorosamente a mecânica do modelo mundial do jogo).
fonte