Agregar funcionalidad de scripting to.NET aplicaciones


Tengo un pequeño juego escrito en C#. Utiliza una base de datos como back-end. Es un juego de cartas coleccionables, y quería implementar la función de las cartas como un script.

Lo que quiero decir es que esencialmente tengo una interfaz, ICard, que implementa una clase de tarjeta (public class Card056 : ICard) y que contiene funciones que son llamadas por el juego.

Ahora, para hacer la cosa mantenible/modificable, me gustaría tener la clase para cada tarjeta como código fuente en la base de datos y esencialmente compilar en el primer uso. Así que cuando tenga que agregar / cambiar una tarjeta, simplemente la agregaré a la base de datos y le diré a mi aplicación que se actualice, sin necesidad de ningún despliegue de ensamblado (especialmente porque estaríamos hablando de 1 ensamblado por tarjeta, lo que significa cientos de ensamblados).

¿Es eso posible? Registrar una clase desde un archivo fuente y luego instanciarla, etc.

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

El lenguaje es C# pero extra bonus si es posible escribir el script en cualquier idioma.NET.

Author: Peter Featherstone, 2008-08-02

9 answers

La solución de script en C# de Oleg Shilo (en El Proyecto de Código) realmente es una gran introducción para proporcionar habilidades de script en su aplicación.

Un enfoque diferente sería considerar un lenguaje que está construido específicamente para scripting, como IronRuby, IronPython , o Lua.

IronPython y IronRuby están disponibles hoy.

Para una guía para incrustar IronPython lea Cómo incrustar el soporte de script de IronPython en su aplicación existente en 10 sencillos pasos.

Lua es un lenguaje de scripting comúnmente usado en juegos. Hay un compilador Lua para. NET, disponible en CodePlex { http://www.codeplex.com/Nua

Esa base de código es una gran lectura si desea aprender sobre la construcción de un compilador en .NET.

Un ángulo completamente diferente es intentar PowerShell. Hay numerosos ejemplos de incrustación de PowerShell en una aplicación -- aquí hay un proyecto completo sobre el tema: Túnel de Powershell

 38
Author: Leon Bambrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-16 21:47:03

Tal vez puedas usar IronRuby para eso.

De lo contrario, sugiero que tenga un directorio donde coloque ensamblados precompilados. Entonces podría tener una referencia en la base de datos al ensamblado y la clase, y usar reflexión para cargar los ensamblados adecuados en tiempo de ejecución.

Si realmente desea compilar en tiempo de ejecución, podría usar el código, entonces podría usar reflexión para cargar el ensamblaje dinámico. Artículo de MSDN que podría ayudar.

 8
Author: Eric Haskins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-02 04:23:02

Puede usar cualquiera de los lenguajes DLR, que proporcionan una forma de alojar fácilmente su propia plataforma de scripting. Sin embargo, no tiene que usar un lenguaje de scripting para esto. Podría usar C# y compilarlo con el proveedor de código C#. Mientras lo cargues en su propio AppDomain, puedes cargarlo y descargarlo al contenido de tu corazón.

 6
Author: Jesse Ezell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-02 06:16:23

Si no quieres usar el DLR puedes usar Boo (que tiene un intérprete) o podrías considerar el Script.NET (S#) proyecto en CodePlex . Con la solución Boo puede elegir entre scripts compilados o usar el intérprete, y Boo es un buen lenguaje de scripting, tiene una sintaxis flexible y un lenguaje extensible a través de su arquitectura de compilador abierto. Script.NET sin embargo, también se ve bien, y podría extender fácilmente ese lenguaje, así como su proyecto de código abierto y utiliza un Generador de Compiladores muy amigable ( Irony.net).

 6
Author: Nathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-08 20:00:22

Sugeriría usar LuaInterface ya que ha implementado completamente Lua donde parece que Nua no está completa y probablemente no implementa alguna funcionalidad muy útil (corrutinas, etc.).

Si desea utilizar algunos de los módulos Lua preenvasados externos, le sugiero que use algo similar a la 1.5.x en lugar de la 2.serie x que construye código completamente administrado y no puede exponer la API C necesaria.

 5
Author: harningt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-17 01:41:29

Sí, pensé en eso, pero pronto me di cuenta de que otro Lenguaje Específico de Dominio (DSL) sería un poco demasiado.

Esencialmente, necesitan interactuar con mi estado de juego de maneras posiblemente impredecibles. Por ejemplo, una carta podría tener una regla "Cuando estas cartas entran en juego, todos tus esbirros no muertos ganan + 3 ataque contra enemigos voladores, excepto cuando el enemigo es bendecido". Como los juegos de cartas coleccionables se basan en turnos, el Administrador de GameState activará eventos OnStageX y permitirá que las cartas se modifiquen otras tarjetas o el GameState en cualquier manera que la tarjeta necesita.

Si intento crear un DSL, tengo que implementar un conjunto de características bastante grande y posiblemente actualizarlo constantemente, lo que cambia el trabajo de mantenimiento a otra parte sin eliminarlo realmente.

Es por eso que quería quedarme con un lenguaje.NET "real" para esencialmente poder disparar el evento y dejar que la tarjeta manipule el estado del juego de cualquier manera (dentro de los límites de la seguridad de acceso al código).

 5
Author: Michael Stum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-26 15:39:08

Estoy usando LuaInterface1.3 + Lua 5.0 para una aplicación NET 1.1.

El problema con Boo es que cada vez que analiza/compila/evalúa su código sobre la marcha, crea un conjunto de clases boo para que obtenga fugas de memoria.

Lua por otro lado, no hace eso, por lo que es muy, muy estable y funciona de maravilla (puedo pasar objetos de C# a Lua y hacia atrás).

Hasta ahora no lo he puesto en PROD todavía, pero parece muy prometedor.

Tuve problemas de fugas de memoria en PROD usando LuaInterface + Lua 5.0 , por lo tanto usé Lua 5.2 y enlazé directamente a C# con DllImport. Las fugas de memoria estaban dentro de la biblioteca LuaInterface.

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

Una vez que hice esto, todas mis fugas de memoria se habían ido y la aplicación era muy estable.

 5
Author: Kat Lim Ruiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-31 23:08:07

La aplicación principal que vende mi división hace algo muy similar para proporcionar personalizaciones de clientes (lo que significa que no puedo publicar ninguna fuente). Tenemos una aplicación C# que carga dinámica VB.NET scripts(aunque cualquier lenguaje. NET podría ser fácilmente soportado-VB fue elegido porque el equipo de personalización provenía de un fondo ASP).

Usando CodeDom de. NET compilamos los scripts de la base de datos, usando el VB CodeDomProvider (molestamente, el valor predeterminado es. NET 2, si desea soportar 3.5 características necesita pasar un diccionario con "CompilerVersion" = "v3.5" a su constructor). Use el método CodeDomProvider.CompileAssemblyFromSource para compilarlo (puede pasar la configuración para forzarlo a compilar solo en memoria.

Esto daría lugar a cientos de ensamblados en memoria, pero se podría poner todo el código de las clases dinámicas en un solo ensamblado, y recompilar todo el lote cuando haya algún cambio. Esto tiene la ventaja de que puede agregar un indicador para compilar en disco con un PDB para cuando esté probando, lo que le permite depurar a través del código dinámico.

 4
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-09 22:58:08

La próxima versión de. NET (5.0?) ha hablado mucho de abrir el "compilador como servicio", lo que haría posible cosas como la evaluación directa del script.

 3
Author: Eric Falsken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-27 09:33:16