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 una función que es llamada por el juego.
Ahora, para que la cosa sea mantenible / modificable, me gustaría tener la clase para cada tarjeta como código fuente en la base de datos y esencialmente compilarla en el primer uso. Entonces, 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 implementar ningún ensamblaje (especialmente porque estaríamos hablando de 1 ensamblaje por tarjeta, lo que significa cientos de ensamblajes) .
¿Es eso posible? Registre una clase desde un archivo fuente y luego cree una instancia, etc.
ICard Cards[current] = new MyGame.CardLibrary.Card056();
Cards[current].OnEnterPlay(ref currentGameState);
El lenguaje es C # pero es una ventaja adicional si es posible escribir el script en cualquier lenguaje .NET.
fuente
Respuestas:
La solución de secuencia de comandos C # de Oleg Shilo (en The Code Project ) realmente es una excelente introducción para proporcionar capacidades de secuencia de comandos en su aplicación.
Un enfoque diferente sería considerar un lenguaje que esté específicamente diseñado para secuencias de comandos, como IronRuby , IronPython o Lua .
IronPython e IronRuby están disponibles hoy.
Para obtener una guía para incrustar IronPython, lea Cómo incrustar el soporte de scripts de IronPython en su aplicación existente en 10 sencillos pasos .
Lua es un lenguaje de secuencias de comandos que se usa comúnmente en los juegos. Hay un compilador Lua para .NET, disponible en CodePlex - http://www.codeplex.com/Nua
Ese código base es una excelente lectura si desea aprender a crear un compilador en .NET.
Un ángulo completamente diferente es probar PowerShell . Hay numerosos ejemplos de incrustación de PowerShell en una aplicación; aquí hay un proyecto completo sobre el tema: Powershell Tunnel
fuente
Es posible que pueda usar IronRuby para eso.
De lo contrario, le sugiero que tenga un directorio donde coloque los ensamblados precompilados. Luego, podría tener una referencia en la base de datos al ensamblado y la clase, y usar la reflexión para cargar los ensamblados adecuados en tiempo de ejecución.
Si realmente desea compilar en tiempo de ejecución, puede usar CodeDOM, entonces puede usar la reflexión para cargar el ensamblado dinámico. Artículo de documentación de Microsoft que podría ayudar .
fuente
Si no desea usar el DLR, puede usar Boo (que tiene un intérprete) o podría considerar el proyecto Script.NET (S #) en CodePlex . Con la solución Boo puede elegir entre scripts compilados o usar el intérprete, y Boo crea un lenguaje de scripting agradable, tiene una sintaxis flexible y un lenguaje extensible a través de su arquitectura de compilación abierta. Sin embargo, Script.NET también se ve bien, y podría extender fácilmente ese lenguaje, así como también es un proyecto de código abierto y utiliza un Generador de compiladores muy amigable ( Irony.net ).
fuente
Puede utilizar cualquiera de los lenguajes DLR, que proporcionan una forma de alojar fácilmente su propia plataforma de secuencias de comandos. Sin embargo, no es necesario que utilice un lenguaje de secuencias de comandos para esto. Puede usar C # y compilarlo con el proveedor de código C #. Siempre que lo cargue en su propio AppDomain, puede cargarlo y descargarlo al contenido de su corazón.
fuente
Sugeriría usar LuaInterface ya que ha implementado Lua por completo donde parece que Nua no está completo y probablemente no implemente alguna funcionalidad muy útil (corrutinas, etc.).
Si desea utilizar algunos de los módulos Lua preempaquetados externos, le sugiero que use algo similar a 1.5.x en lugar de la serie 2.x que crea código completamente administrado y no puede exponer la API C necesaria.
fuente
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 tenga pérdidas de memoria.
Lua, por otro lado, no hace eso, por lo que es 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, 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 me vinculé directamente a C # con DllImport. Las pérdidas 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 pérdidas de memoria desaparecieron y la aplicación era muy estable.
fuente
La aplicación principal que vende mi división hace algo muy similar para proporcionar personalizaciones al cliente (lo que significa que no puedo publicar ninguna fuente). Tenemos una aplicación C # que carga scripts dinámicos de VB.NET (aunque cualquier lenguaje .NET podría ser fácilmente compatible; se eligió VB porque el equipo de personalización provenía de ASP).
Usando CodeDom de .NET compilamos los scripts de la base de datos, usando el VB
CodeDomProvider
(molestamente por defecto es .NET 2, si desea admitir características 3.5, debe pasar un diccionario con "CompilerVersion" = "v3.5" a su constructor ). Use elCodeDomProvider.CompileAssemblyFromSource
método para compilarlo (puede pasar configuraciones para forzarlo a compilar solo en memoria.Esto daría como resultado cientos de ensamblados en la memoria, pero podría juntar todo el código de las clases dinámicas en un solo ensamblado y volver a compilar todo el lote cuando haya algún cambio. Esto tiene la ventaja de que puede agregar una marca para compilar en disco con un PDB para cuando esté probando, lo que le permite depurar a través del código dinámico.
fuente
Sí, pensé en eso, pero pronto me di cuenta de que otro lenguaje específico de dominio (DSL) sería demasiado.
Esencialmente, necesitan interactuar con mi estado de juego de formas posiblemente impredecibles. Por ejemplo, una carta podría tener una regla: "Cuando estas cartas entran en juego, todos tus esbirros no muertos ganan +3 de ataque contra enemigos voladores, excepto cuando el enemigo está bendecido". Como los juegos de cartas coleccionables se basan en turnos, GameState Manager activará eventos OnStageX y permitirá que las cartas modifiquen otras cartas o GameState de la forma que necesite la carta.
Si intento crear un DSL, tengo que implementar un conjunto de funciones bastante grande y posiblemente actualizarlo constantemente, lo que traslada el trabajo de mantenimiento a otra parte sin eliminarlo.
Es por eso que quería quedarme con un lenguaje .NET "real" para poder básicamente 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).
fuente
La próxima versión de .NET (¿5.0?) Se ha hablado mucho sobre la apertura del "compilador como servicio", lo que haría posible cosas como la evaluación directa de scripts.
fuente