Pregunta

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

Lo que quiero decir es que esencialmente tengo una interfaz, ICard, que implementa una clase de tarjeta (public class Card056: ICard) y que contiene la función llamada por el juego.

Ahora, para que esto 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 indicaré a mi aplicación que se actualice, sin necesidad de ninguna implementación de 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 una ventaja adicional es que es posible escribir el script en cualquier lenguaje .NET.

¿Fue útil?

Solución

La solución C# Script de Oleg Shilo (en The Code Project) realmente es una excelente introducción para proporcionar capacidades de secuencias de comandos en su aplicación.

Un enfoque diferente sería considerar un lenguaje diseñado específicamente para secuencias de comandos, como hierrorubí, HierroPython, o lua.

IronPython y IronRuby están disponibles hoy.

Para obtener una guía para incorporar IronPython, leaCómo incorporar compatibilidad con scripts IronPython en su aplicación existente en 10 sencillos pasos.

Lua es un lenguaje de programación comúnmente utilizado en juegos.Hay un compilador Lua para .NET, disponible en CodePlex. http://www.codeplex.com/Nua

Ese código base es una lectura excelente si desea aprender a crear un compilador en .NET.

Un ángulo completamente diferente es intentar Potencia Shell.Hay numerosos ejemplos de cómo incorporar PowerShell en una aplicación; aquí hay un proyecto detallado sobre el tema:Túnel Powershell

Otros consejos

Es posible que puedas utilizar IronRuby para eso.

De lo contrario, le sugiero que tenga un directorio donde coloque los ensamblados precompilados.Entonces 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 y luego puede usar la reflexión para cargar el ensamblaje dinámico. Artículo de documentación de Microsoft que podría ayudar.

Si no desea utilizar el DLR, puede use Boo (que tiene un intérprete) o podrías considerar el proyecto Script.NET (S#) en CodePlex.Con la solución Boo puedes 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 abierta.Sin embargo, Script.NET también se ve bien y puedes extender fácilmente ese lenguaje, además de que es un proyecto de código abierto y utiliza un generador de compiladores muy amigable (Ironía.net).

Puede utilizar cualquiera de los lenguajes DLR, que proporcionan una manera de alojar fácilmente su propia plataforma de secuencias de comandos.Sin embargo, no es necesario utilizar un lenguaje de programación para ello.Podrías usar C# y compilarlo con el proveedor de código C#.Siempre que lo cargue en su propio AppDomain, puede cargarlo y descargarlo como desee.

Yo sugeriría usar Interfaz Lua ya que ha implementado Lua por completo, donde parece que Nua no está completo y probablemente no implementa algunas funciones muy útiles (corrutinas, etc.).

Si desea utilizar algunos de los módulos Lua preempaquetados externos, le sugeriría usar 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.

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

El problema con Boo es que cada vez que analizas/compilas/evalúas tu código sobre la marcha, crea un conjunto de clases boo por lo que tendrás 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 viceversa).

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

Tuve problemas de pérdida de memoria en PROD usando LuaInterface + Lua 5.0, Por lo tanto, utilicé Lua 5.2 y lo vinculé directamente a C# con DllImport. Las pérdidas de memoria estaban dentro de la biblioteca LuaInterface.

Lúa 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 quedó muy estable.

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 VB.NET (aunque cualquier lenguaje .NET podría ser fácilmente compatible; se eligió VB porque el equipo de personalización tenía experiencia en ASP).

Usando CodeDom de .NET compilamos los scripts de la base de datos, usando el VB CodeDomProvider (Es molesto que el valor predeterminado sea .NET 2; si desea admitir funciones 3.5, debe pasar un diccionario con "CompilerVersion" = "v3.5" a su constructor).Utilizar el CodeDomProvider.CompileAssemblyFromSource método para compilarlo (puede pasar configuraciones para forzar que se compile solo en la 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 recompilarlo todo cuando haya algún cambio.Esto tiene la ventaja de que se puede agregar un indicador para compilar en el disco con un PDB para cuando estés probando, permitiéndote depurar a través del código dinámico.

Sí, pensé en eso, pero pronto descubrí que otro lenguaje específico de dominio (DSL) sería 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 secuaces no-muertos obtienen +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 la tarjeta necesite.

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 realmente.

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

Se ha hablado mucho de la próxima versión de .NET (¿5.0?) sobre la apertura del "compilador como servicio" que haría posible cosas como la evaluación directa de scripts.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top