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

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

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

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

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

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

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

Забавно, я и мой друг некоторое время назад думали написать коллекционную карточную игру на C#, неужели у вас все еще есть исходный код для этого? Интересно, как вы к этому подошли.

mattytommo 04.05.2012 13:34

@mattytommo Нет, ничего не осталось, это было на очень ранних стадиях и, по сути, просто работало, как я обрисовал выше. В настоящее время я бы заглянул в Roslyn, чтобы выполнить компиляцию C#: blogs.msdn.com/b/csharpfaq/archive/2011/10/19/… - В качестве альтернативы, JavaScript с использованием Jint - jint.codeplex.com

Michael Stum 04.05.2012 18:32

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

mattytommo 04.05.2012 18:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
76
3
19 705
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

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

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

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

(Нет необходимости отмечать это; хотя это должно быть обновление комментария / ответа, но оно унаследовано от того, что было раньше, чем были варианты)

user1228 26.11.2010 21:00
Ответ принят как подходящий

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

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

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

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

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

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

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

Кстати, я выбрал это как принятый ответ, потому что в любом случае хотел изучить Python и IronPython, поэтому подход IronPython лучше всего подходит для мне.

Michael Stum 25.10.2008 19:08

LuaInterface - это интерпретатор lua, который также отлично работает.

RCIX 27.10.2009 03:49

Я внедрил C# Script в систему рабочего процесса в ноябре 2009 года. Он отлично зарекомендовал себя.

David Robbins 10.01.2010 16:37

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

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

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

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

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

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

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

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

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

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

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

Да. Хотя Roslyn все еще на горизонте, Mono.CSharp (доступно в NuGet) содержит все те же функции.

Eric Falsken 31.05.2013 20:00

Добавление обновления для сохранения актуальности параметров: Доступна платформа компилятора .NET (Roslyn). Так что это жизнеспособная альтернатива всем остальным, упомянутым. github.com/dotnet/roslyn.

Riv 18.03.2017 10:33

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

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

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