2008-08-01 6 views
61

У меня есть небольшая игра, написанная на C#. Он использует базу данных как фоновый. Это a trading card game, и я хотел реализовать функцию карт как скрипт.Добавление функций сценариев в приложения .NET

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

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

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

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

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

+1

Это смешно, я и друг думали писать карточную игру в C# некоторое время назад, не думаю, что у вас все еще есть источник для этого? Интересуетесь тем, как вы к этому подошли. – mattytommo 2012-05-04 09:34:41

+0

@mattytommo Нет, ничего не осталось, это было на самом раннем этапе и, по сути, просто работало, как описано выше. В настоящее время я хотел бы изучить Roslyn для компиляции C#: http://blogs.msdn.com/b/csharpfaq/archive/2011/10/19/introducing-the-microsoft-roslyn-ctp.aspx - альтернативно, использование JavaScript Jint - http://jint.codeplex.com/ – 2012-05-04 14:32:41

+0

ах спасибо, но я больше искал реализацию самой торговой карточной игры и структуры, которую вы использовали, в отличие от механизма сценариев. Спасибо в любом случае :) – mattytommo 2012-05-04 14:44:15

ответ

36

Oleg Shilo's C# Script solution (at The Code Project) действительно является отличным введением для обеспечения возможностей скриптов в вашем приложении.

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

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

руководство пользователя по внедрению IronPython How to embed IronPython script support in your existing app in 10 easy steps.

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

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

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

4

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

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

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

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

+0

(Не нужно указывать это, в то время как это должно быть обновлением комментариев/ответов, но с тех пор, пока они не были опциями, они были grandfathered) – Will 2010-11-26 18:00:00

7

Возможно, вы сможете использовать IronRuby для этого.

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

Если вы действительно хотите скомпилировать во время выполнения, вы можете использовать CodeDOM, тогда вы можете использовать отражение для загрузки динамической сборки. MSDN article which might help.

5

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

6

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

4

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

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

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

5

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

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

3

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

5

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

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

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

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

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

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

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