Я думаю о написании небольшой текстовой приключенческой игры, но я не совсем уверен, как я должен проектировать мир с технической точки зрения.
Моя первая мысль - сделать это в XML, разработав что-то вроде следующего. Извиняюсь за огромную кучу XML, но я чувствовал, что важно полностью объяснить, что я делаю.
<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>
Очевидно, должно быть что-то большее, чем это. Взаимодействие с людьми и врагами, а также смерть и завершение являются необходимыми дополнениями. Поскольку с XML довольно сложно работать, я бы, вероятно, создал какой-то мировой редактор.
Я хотел бы знать, есть ли у этого метода какие-либо недостатки, и есть ли «лучший» или более стандартный способ сделать это.
c#
xml
text-based
adventure-games
многочлен
источник
источник
Ответы:
Если вы не полностью привязаны к C #, то «более стандартный» способ сделать это - использовать один из множества существующих инструментов для создания текстовых приключений, чтобы помочь людям создать именно такую игру. Эти инструменты дают вам уже функционирующий парсер, обрабатывающий на предмет смерти, сохранения / восстановления / отмены, взаимодействия с персонажами и других аналогичных стандартных функций текстового приключения. В настоящее время наиболее популярными системами авторинга являются Inform и TADS (хотя есть и полдюжины других доступных)
Inform может компилироваться в большинство наборов инструкций виртуальной машины Z Machine, используемых в играх Infocom, или в более поздние наборы инструкций виртуальной машины glulx. С другой стороны, TADS компилируется в собственный код виртуальной машины.
Любой тип двоичного кода может быть запущен большинством современных интерактивных игровых интерпретаторов (в старые времена вам часто требовались отдельные переводчики для игр TADS от игр ZMachine от игр glulx. Но, к счастью, те дни в основном закончились.) Переводчики доступны только для о любой платформе, которую вы хотите; Mac / PC / Linux / BSD / IOS / Android / Kindle / браузер / и т.д.. Итак, вы уже хорошо кроссплатформенны и по-настоящему заботитесь о них.
Для большинства платформ в настоящее время рекомендуется использовать интерпретатор Gargoyle , но есть множество других, поэтому не стесняйтесь экспериментировать.
К кодированию в Inform (особенно в последней версии) требуется немного времени, чтобы привыкнуть, так как он больше ориентирован на авторов, чем на инженеров, и поэтому его синтаксис выглядит странно и почти разговорно. В синтаксисе Inform 7 ваш пример будет выглядеть так:
Принимая во внимание, что TADS больше похож на традиционный язык программирования, и та же самая игра в TADS выглядит так:
Обе системы находятся в свободном доступе, очень часто используются и имеют большое количество учебной документации (доступно по ссылкам, которые я дал выше), поэтому стоит проверить обе из них и выбрать ту, которая вам больше нравится.
Обратите внимание, что две системы имеют слегка различающиеся стандартные поведения (хотя обе могут быть изменены). Вот снимок экрана с игрой, собранной из источника Inform:
И вот одна из игр, в которые играют (внутри терминала - типографика может быть намного лучше, чем эта), собранная из источника Tads:
Интересные моменты, на которые следует обратить внимание: TADS по умолчанию отображает «счет» в правом верхнем углу (но вы можете отключить его), а Inform - нет (но вы можете включить его). По умолчанию Inform сообщит вам открытые / закрытые состояния предметов в описании комнаты, а Tads - нет. Тэдс склонен автоматически предпринимать действия для вас, чтобы выполнять команды игрока (если вы не говорите, что нет), в то время как Информ не склонен (если вы не говорите это).
Любой из них может быть использован для создания игр любого типа (поскольку они оба легко настраиваются), но Inform более ориентирован на создание интерактивной художественной литературы в современном стиле (часто с минимальными головоломками и большим количеством повествовательных стилей), где TADS более структурирован. к созданию текстовых приключений в старом стиле (часто сильно сосредоточенных на головоломках и строгом определении механики модели мира игры).
источник