В настоящее время я работаю над текстовым движком игры в Ruby, при этом приложение разделяется на Ruby-код в /lib и данные YAML в /data, который загружается, когда это требуется в игре. Я хочу, чтобы файлы данных содержали базовые сценарии, в основном в модели event/observer. Тем не менее, я также хочу, чтобы пользователи могли создавать и совместно использовать пользовательские сценарии, не беспокоясь о вредоносном коде, встроенном в script.
Приложение: Мой первоначальный план состоял в том, чтобы разделить содержимое пользователя на два типа, "модули", которые были только для данных (и, следовательно, безопасны) и плагины, которые добавили дополнительные функции (но, очевидно, были небезопасными). Чтобы сделать аналогию с настольными играми, модули будут похожи на опубликованные сценарии приключения и контент, а плагины - это правила, содержащие дополнительные правила и системы.
Пример script (синтаксис, конечно, может быть изменен на основе решения):
---
Location:
observers:
on_door_open: |
monster = spawn_monster(:goblin);
monster.add_item(random_item());
monster.hostile = true;
С точки зрения безопасности было бы идеально, если бы скриптинг был строго выбран, возможно, через включенный mixin с небольшим DSL, например:
class Frog
include Scriptable
def jump; ... ; end # this can be called from a script
allow_scripting :jump
def ribbit; ... ; end # this cannot be called from a script
end
Я рассмотрел четыре параметра three, но я не уверен, какой из них лучше всего подходит:
-
Используйте Ruby-скрипты, но в виде песочницы.
Плюсы: Очень знакомы с Ruby, нет необходимости в коде "клей" или проблемах интеграции объектов между языками.
Минусы: Не очень знакомы с проблемами безопасности или песочницей, не нашли никаких готовых решений, которые кажутся подходящими.
-
ВнедритьВставить другой язык сценариев, например. Lua.Плюсы: Ruby и Lua основаны на C, поэтому привязки должны быть достаточно простыми. Lua - достаточно популярный язык, поэтому помощь доступна, если я буду сталкиваться с проблемами позже. Безопасно, поскольку любая функциональность, которую я не связываю напрямую, будет недоступна из сценариев.
Минусы: Существующие привязки Ruby-Lua кажутся односторонними, старыми и плохо поддерживаемыми, или и тем, и другим. Кажется, это хитрость, чтобы внедрить язык сценариев в другой язык сценариев.
-
Внедрение пользовательского языка сценариев с помощью Ruby-интерпретатора. Я экспериментировал с Treetop, и не должно быть слишком сложно сделать простую грамматику, достаточную для скриптов.
Плюсы: Не нужно внедрять другой язык. Только функциональность, которую я специально реализовал, будет доступна для скриптов.
Минусы: Overkill. "Не построен здесь" синдром. Вероятно, ужасное гнездо жуков, ожидающих того, что произойдет.
-
Реализовать файлы данных полностью в Ruby, используя язык, специфичный для домена.
Плюсы: Простой и легкий.
Минусы:. Пользовательские данные не являются надежными.
Я также открыт для других предложений, не включенных в этот список, о которых я, возможно, и не подумал. Какое лучшее решение для безопасного внедрения скриптов, встроенных в файлы данных?
Изменить 2011 年 12 月 23 日: Добавлен четвертый вариант с DSL, добавлен "добавление" наверх с дополнительными мыслями/контекстом.