Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

Решение C# Script Олега Шило (в The Code Project) действительно является отличным введением в предоставление возможностей сценариев в вашем приложении.

Другой подход — рассмотреть язык, специально созданный для написания сценариев, например ЖелезоРубин, ЖелезоПитон, или Луа.

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

Руководство по внедрению IronPython читайтеКак встроить поддержку сценариев IronPython в существующее приложение за 10 простых шагов.

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

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

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

Другие советы

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

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

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

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

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

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

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

Я использую 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.

Луа 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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top