Я имею дело с файлами игровых диалогов (диалог между игроком и неигровыми персонажами), где выбор диалога и его результат зависят от определенных условий и приводят к определенным действиям. Теперь я мог бы написать простой синтаксический анализатор для обработки какого-то языка для определения предварительных и постусловий, но мой друг предложил использовать XML. Условия могут быть сохранены как атрибуты элемента диалога, а варианты выбора и действия являются внутренними элементами. Затем я бы использовал функцию eval для анализа этих условий и операторов (я использую Ruby для создания этой игры). Чтобы упростить такой подход, я мог бы написать простой графический интерфейс для управления этими файлами, не беспокоясь об уродливом XML.
Но это кажется мне странным выбором для обработки логики в файлах XML. Насколько я понимаю, файлы XML предназначены для хранения и обмена данными, и я всегда читаю разглагольствования о том, как люди злоупотребляют XML для всех видов вещей, для которых он не предназначен. Мои друзья в ответ отмечают, как XML IS используется для всего, включая XHTML и этот язык описания пули (что также иллюстрирует некоторую логику).
Честно говоря, использование XML упростило бы для меня многое. Написание парсера может быть болезненным и трудоемким, а мои требования в целом просты. Но так ли это нормально или я потом пожалею о таком выборе?
Для людей, интересующихся подробностями, вот как может выглядеть базовый диалог обмена в 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>
Соответствующий код, если бы он был написан на Ruby, был бы таким:
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
Такие вещи, как likeHero и carFixingSkills - это элементы знаний, которые могут быть у игрока и NPC, которые, вероятно, будут храниться в хэше в реальной реализации. Я считаю, что файловый диалог более гибок, потому что я мог бы сделать редактор, чтобы легко редактировать диалоги и условия / действия, а также из-за сложной природы игровых деревьев разговоров. Язык сценариев, такой как Ruby или Lua, помогает, но для обработки логики таких деревьев потребуются сложные структуры.
Вернемся к исходному вопросу: является ли XML правильным инструментом для работы или я чего-то упускаю?





DSL был бы реализацией Mercedes-Benz для этого, и было бы интересно написать на Ruby. Вы правы, это потребует много работы, но может окупиться, если была хорошо написана, и эта игра действительно стала популярной.
При переходе по XML-маршруту следует учитывать, какой парсер / движок вы будете использовать для его рендеринга. По данным последней проверки, REXML был единственное шоу в городе для рубистов. Если вам нравится REXML, то XML звучит как хороший способ, но если вы еще не пробовали его, я бы посоветовал сделать это. прежде чем принять это решение. Я не выбираю REXML, просто советую немного осторожно, поскольку вы будете полностью зависеть от этой библиотеки, что бы вы ни использовали.
Поскольку вы пишете это на Ruby, я думаю, что достаточно сделать это в XML. Таким образом, вы можете создать веб-приложение, которое позволит вам работать с диалогами и логикой игры из любого места. И другие люди могут сотрудничать с вами или, возможно, создавать пользовательские моды - что всегда является плюсом.
Пока вы держите свои XML-файлы хорошо организованными (вам помогут блок-схемы на бумаге), вы не должны столкнуться с какими-либо проблемами и можете даже поблагодарить себя за то, что прошли через боль при его синтаксическом анализе :)
Чтобы получить вдохновение или, возможно, даже принять его, взгляните на AIML и BuddyScript. AIML - это XML для чат-ботов, BuddyScript - еще один вариант, теперь принадлежащий Microsoft.
Ниже приведен образец AIML из 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>
Если бы вы интегрировали технологию AIML (которая, я думаю, бесплатна) в свою игру, у ваших NPC был бы ИИ, с которым ваши игроки могли бы общаться. Разве это не было бы интересно?
AIML имеет модульную структуру, поэтому все ваши NPC могут иметь общий файл, описывающий все стандартные знания об их мире. Затем вы можете добавить определенные файлы для вещей, которые будут типичными для каждой расы, класса, места, человека или задачи. Есть много интересных примеров файлов AIML, например Eliza.
Ситуационная информация может быть добавлена в начале разговора, и у вас может быть какое-то программное обеспечение за пределами движка AIML, которое прослушивает «волшебные» слова от NPC, указывающие, что NPC хочет, чтобы что-то произошло в «реальном» игровом мире. как "*** ДАЙТЕ ИГРОКУ 20 КРЫЛ БУФФАЛО".
Посмотрев на AIML, я думаю, что это довольно крутая идея, хотя, вероятно, излишек для моей игры. Я не поклонник общих знаний (Oblivion), и настройка выполняется индивидуально, поэтому с такой системой потребовалось бы слишком много работы.
Если вы не слышали о YAML, взгляните на него. Это похоже на XML, но XML на самом деле не предназначен для написания вручную - это машинно-машинный интерфейс, который оказывается читаемым человеком (так что вы действительно должны создать для него редактор). YAML - это человеко-машинный интерфейс, гораздо более доступный для записи.
Я бы не стал возиться с DSL, YAML отлично отображает.
Я использовал YAML и согласен с вами по поводу удобочитаемости. Я уже использую XML для других файлов данных, и я планирую создать простой редактор диалогов для чтения и редактирования диалогов в формате XML, так что я не думаю, что это будет проблемой.
Если в вашей игре не будет меньше полдюжины уникальных диалогов, вам обязательно следует поместить эту информацию в какой-то файл данных. XML - сильный соперник этого формата. Я не говорю на Ruby, поэтому в этом случае он может не работать, но другой вариант - определить диалог как данные непосредственно в коде Ruby. (Я знаю, что это будет хорошо работать в Lua, Python и Javascript ... Я предполагаю, что определение вложенных структур данных также легко в Ruby.)
Мы использовали файлы XML для определения всех статических данных в Pirates of the Burning Sea, и это был отличный способ. Наличие такого формата данных позволяет непрограммистам контролировать данные и позволяет программистам работать над функциями вместо ввода данных. Наличие текстовых файлов данных означает, что вы можете держать их под контролем источника, чтобы вы могли знать, когда они меняются.
В этом проекте я использую REXML, он мне подходит. libxml (libxml.rubyforge.org) - более эффективная альтернатива, которую я мог бы рассмотреть.