Добавление функций сценариев в приложения .NET

У меня есть небольшая игра, написанная на С#. Он использует базу данных в качестве бэк-энда. Это торговая карточная игра, и я хотел реализовать функцию карт в виде скрипта.

Я имею в виду, что у меня по сути есть интерфейс ICard, который реализует класс карты (public class Card056: ICard) и который содержит функцию, вызываемую игрой.

Теперь, чтобы сделать объект обслуживаемым/модифицируемым, я хотел бы иметь класс для каждой карты в качестве исходного кода в базе данных и по существу скомпилировать его при первом использовании. Поэтому, когда мне нужно добавить/изменить карту, я просто добавлю ее в базу данных и скажу, чтобы мое приложение обновлялось, без необходимости какого-либо развертывания сборки (тем более, что речь идет об одной сборке на карту, что означает сотни сборок).,

Это возможно? Зарегистрировать класс из исходного файла, а затем создать его экземпляр и т.д.

ICard Cards[current] = new MyGame.CardLibrary.Card056();
Cards[current].OnEnterPlay(ref currentGameState);

Язык С#, но дополнительный бонус, если есть возможность написать скрипт на любом языке .NET.

Ответ 1

Решение от Oleg Shilo С# Script (в проекте Code) действительно представляет собой отличное введение в возможности Script в вашем приложении.

Другой подход - рассмотреть язык, специально созданный для сценариев, например IronRuby, IronPython, или Lua.

IronPython и IronRuby доступны сегодня.

Для руководства по внедрению чтения IronPython Как встроить поддержку IronPython Script в существующем приложении в 10 простых шаги.

Lua - это язык сценариев, обычно используемый в играх. Существует компилятор Lua для .NET, доступный из CodePlex - http://www.codeplex.com/Nua

Эта кодовая база отлично читается, если вы хотите узнать о создании компилятора в .NET.

Другим углом зрения является попытка PowerShell. Существует множество примеров внедрения PowerShell в приложение - вот подробный проект по теме: Туннель Powershell

Ответ 2

Вы могли бы использовать IronRuby для этого.

В противном случае я бы посоветовал вам иметь каталог, куда вы помещаете предварительно скомпилированные сборки. Тогда вы можете иметь ссылку в БД на сборку и класс и использовать отражение для загрузки соответствующих сборок во время выполнения.

Если вы действительно хотите компилировать во время выполнения, вы можете использовать CodeDOM, тогда вы можете использовать отражение для загрузки динамической сборки. Статья о документации Microsoft, которая может помочь.

Ответ 3

Если вы не хотите использовать DLR, вы можете использовать Boo (у которого есть интерпретатор) или вы могли бы рассмотреть проект Script.NET(S #) в CodePlex. С помощью решения Boo вы можете выбирать между скомпилированными скриптами или с помощью интерпретатора, а Boo - хороший язык сценариев, имеет гибкий синтаксис и расширяемый язык через свою открытую архитектуру компилятора. Script.NET тоже выглядит хорошо, и вы можете легко расширить этот язык, а также его проект с открытым исходным кодом и использовать очень дружелюбный генератор компилятора (Irony.net).

Ответ 4

Вы можете использовать любой из языков DLR, которые предоставляют возможность действительно легко разместить вашу собственную платформу сценариев. Однако для этого вам не нужно использовать язык сценариев. Вы можете использовать С# и скомпилировать его с поставщиком кода С#. Пока вы загружаете его в свой собственный AppDomain, вы можете загружать и выгружать его в свой сердечный контент.

Ответ 5

Я бы предложил использовать LuaInterface, поскольку он полностью реализовал Lua, где, как представляется, Nua не является полным и, вероятно, не реализует некоторые очень полезная функциональность (сопрограммы и т.д.).

Если вы хотите использовать некоторые внешние модули Lua, предлагаемые мной, я бы предложил использовать что-то по строкам 1.5.x в отличие от серии 2.x, которая строит полностью управляемый код и не может выставить необходимый C API.

Ответ 6

Я использую LuaInterface1.3 + Lua 5.0 для приложения NET 1.1.

Проблема с Boo заключается в том, что каждый раз, когда вы анализируете/компилируете/оцениваете свой код на лету, он создает набор классов boo, поэтому вы получите утечки памяти.

Lua с другой стороны, не делает этого, поэтому он очень стабилен и отлично работает (я могу передавать объекты с С# на Lua и назад).

Пока я еще не поставил его в PROD, но кажется очень перспективным.

У меня были проблемы с утечкой памяти в PROD с использованием LuaInterface + Lua 5.0, поэтому я использовал Lua 5.2 и напрямую связан с С# с DllImport. Утечки памяти были внутри библиотеки LuaInterface.

Lua 5.2: from http://luabinaries.sourceforge.net и http://sourceforge.net/projects/luabinaries/files/5.2/Windows%20Libraries/Dynamic/lua-5.2_Win32_dll7_lib.zip/download

Как только я это сделал, все утечки памяти исчезли, и приложение было очень стабильным.

Ответ 7

Да, я подумал об этом, но вскоре выяснил, что другой домен-специфический язык (DSL) будет слишком большим.

По сути, они должны взаимодействовать с моим gamestate, возможно, непредсказуемыми способами. Например, у карты может быть правило "Когда эти карты войдут в игру, все ваши нежити-миньоны получают +3 атаку против летающих врагов, кроме случаев, когда противник благословлен". В то время как игры с карточными играми основаны на поворотах, GameState Manager запускает события OnStageX и позволяет картам изменять другие карты или GameState любым способом, который нужна карте.

Если я попытаюсь создать DSL, мне придется реализовать довольно большой набор функций и, возможно, постоянно обновлять его, что переносит работу по обслуживанию на другую часть, не удаляя ее.

Вот почему я хотел остаться с "реальным" языком .NET, чтобы по существу иметь возможность просто запустить событие и позволить карточке манипулировать игрой игры любым способом (в пределах безопасности доступа к коду).

Ответ 8

Основное приложение, которое продается моим подразделением, делает что-то очень похожее на предоставление клиентских настроек (что означает, что я не могу опубликовать какой-либо источник). У нас есть приложение С#, которое загружает динамические скрипты VB.NET(хотя любой язык .NET может быть легко поддержан - VB был выбран, потому что команда настройки появилась из фона ASP).

Используя .NET CodeDom, мы скомпилируем скрипты из базы данных, используя VB CodeDomProvider (досадно, что он по умолчанию используется для .NET 2, если вы хотите поддерживать функции 3.5, вам необходимо передать словарь с помощью "CompilerVersion" = "v3.5" к его конструктору). Используйте метод CodeDomProvider.CompileAssemblyFromSource для его компиляции (вы можете передать настройки, чтобы заставить его компилироваться только в памяти.

Это приведет к сотням сборок в памяти, но вы можете объединить все коды динамических классов в единую сборку и перекомпилировать всю партию при любых изменениях. Это имеет то преимущество, что вы можете добавить флаг для компиляции на диск с PDB для тестирования, позволяя вам отлаживать динамический код.

Ответ 9

В следующей версии .NET(5.0?) было много разговоров об открытии "компилятора в качестве сервиса", что сделало бы возможной оценку по прямой script.