В настоящее время я работаю на текстовом игровом движке в Ruby, с приложением, разделенным на код Ruby в / lib и данные YAML в / data, которые загружаются по мере необходимости в игре. Я хочу, чтобы файлы данных содержали базовые сценарии, в основном в событие / наблюдатель вер модель. Однако я также хочу, чтобы пользователи могли создавать собственные сценарии и обмениваться ими, не беспокоясь о вредоносном коде, встроенном в сценарий.
Приложение: Мой первоначальный план состоял в том, чтобы пользовательский контент был разделен на два типа: «модули», предназначенные только для данных (и, следовательно, безопасные), и плагины, которые добавляли дополнительные функции (но, очевидно, были небезопасными).Если провести аналогию с настольными играми, модули будут похожи на опубликованные сценарии приключений и контент, а плагины будут на книги правил, содержащие дополнительные правила и системы.
Пример сценария (синтаксис, конечно, может быть изменен в зависимости от решения):
---
Location:
observers:
on_door_open: |
monster = spawn_monster(:goblin);
monster.add_item(random_item());
monster.hostile = true;
С точки зрения безопасности было бы идеально, если бы сценарии были строго разрешены, возможно, через включенный миксин с небольшим 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
Я рассмотрел три четыре варианта, но я не уверен, какой из них лучше всего:
Использовать скрипты Ruby, но в какой-то песочнице.
Плюсы: Очень хорошо знаком с Ruby, нет необходимости в "связующем" коде или проблемах интеграции объектов между языками.
Минусы: Не очень знаком с проблемами безопасности или песочницей, не нашел никаких готовых решений, которые кажутся подходящими.
Реализовать Встроить другой язык сценариев, например Lua.
Плюсы: Ruby и Lua основаны на C, поэтому связывание должно быть достаточно простым. Lua - довольно популярный язык, поэтому помощь доступна, если у меня возникнут проблемы позже. Безопасно, поскольку любые функции, которые я специально не привязываю, будут недоступны из сценариев.
Минусы: Существующие привязки Ruby-Lua кажутся односторонними, старыми и плохо обслуживаемыми, или и тем, и другим. Внедрение языка сценариев в другой язык сценариев кажется изворотливой.
Реализуйте собственный язык сценариев с интерпретатором Ruby. Я экспериментировал с Treetop , и сделать простую грамматику, подходящую для сценариев, не должно быть слишком сложно.
Плюсы: Нет необходимости встраивать другой язык.Для скриптов будут доступны только специально реализованные мной функции.
Минусы: Overkill. Синдром «здесь не построено». Наверное, жуткое гнездо ошибок ждет своего часа.
Реализуйте файлы данных полностью на Ruby, используя предметно-ориентированный язык.
Плюсы: Просто и легко.
Минусы: Никакие пользовательские данные не заслуживают доверия.
Я также открыт для других предложений, не вошедших в этот список, о которых я, возможно, не подумал. Какое наилучшее решение для безопасной реализации скриптов, встроенных в файлы данных?
Edit 2011, 12, 23,: Добавлен четвертый вариант с DSL, добавлено «дополнение» вверху с дополнительными мыслями / контекстом.