Ajout de fonctionnalités de script aux applications .NET

J'ai un petit jeu écrit en C #. Il utilise une base de données comme back-end. Ses un jeu de cartes à collectionner , et je voulais implémenter la fonction des cartes comme un script.

Ce que je veux dire c'est que j'ai essentiellement une interface, ICard , qu'une classe de cartes implémente ( public class Card056: ICard ) et qui contient des fonctions appelées par le jeu.

Maintenant, pour rendre la chose maintenable / moddable, je voudrais avoir la classe pour chaque carte comme code source dans la base de données et la compiler essentiellement lors de la première utilisation. Donc quand je dois ajouter / changer une carte, je vais l'ajouter à la base de données et dire à mon application de se rafraîchir, sans avoir besoin de déployer l'ensemble (d'autant plus que nous parlerions de 1 assemblage par carte ce qui signifie des centaines d'assemblages) .

Est-ce possible? Enregistrez une classe à partir d'un fichier source, puis instanciez-la, etc.

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

La langue est C# mais bonus supplémentaire s'il est possible d'écrire le script dans n'importe quel langage .NET.

0
ajouté édité
Vues: 2
@mattytommo Non, il ne reste plus rien, c'était à un stade très précoce et fonctionnait essentiellement comme je l'ai indiqué plus haut. De nos jours, je voudrais regarder dans Roslyn pour faire la compilation C #: blogs.msdn.com/b/csharpfaq/archive/2011/10/19/… - Alternativement, JavaScript en utilisant Jint - jint.codeplex.com
ajouté l'auteur Michael Stum, source
C'est drôle, moi et un ami pensais à écrire un jeu de cartes à collectionner en C# il y a quelque temps, ne supposez pas que vous avez toujours la source pour cela? Intéressé par la façon dont vous aviez abordé cela.
ajouté l'auteur mattytommo, source
ah merci, mais je cherchais plutôt la mise en place du jeu de cartes à collectionner lui-même et la structure que vous utiliseriez, par opposition au moteur de script. Merci quand même :)
ajouté l'auteur mattytommo, source

9 Réponses

Oui, j'ai pensé à cela, mais j'ai vite compris qu'un autre langage spécifique au domaine (DSL) serait un peu trop.

Essentiellement, ils doivent interagir avec mon joueur d'une manière peut-être imprévisible. Par exemple, une carte pourrait avoir une règle "Quand ces cartes entrent en jeu, tous vos serviteurs morts-vivants gagnent +3 attaques contre des ennemis volants, sauf quand l'ennemi est béni". Comme les jeux de cartes à échanger sont basés sur le tour, GameState Manager déclenche les événements OnStageX et laisse les cartes modifier d'autres cartes ou le GameState de la manière dont la carte a besoin.

Si j'essaie de créer un DSL, je dois implémenter un ensemble de fonctionnalités assez volumineux et le mettre constamment à jour, ce qui déplace le travail de maintenance vers une autre partie sans pour autant le supprimer.

C'est pourquoi je voulais rester avec un langage "réel" .NET pour essentiellement pouvoir simplement déclencher l'événement et laisser la carte manipuler le gamestate de quelque manière que ce soit (dans les limites de la sécurité d'accès au code).

0
ajouté
(Pas besoin de signaler ceci, alors que ceci devrait être une mise à jour de commentaire / réponse, mais est acquis depuis avant que ces options ne soient disponibles)
ajouté l'auteur Will, source

Oleg Shilo's C# Script solution (at The Code Project) really is a great introduction to providing script abilities in your application.

Une approche différente consisterait à considérer un langage spécialement conçu pour les scripts, tel que IronRuby , < un href = "http://en.wikipedia.org/wiki/IronPython" rel = "noreferrer"> IronPython , ou Lua .

IronPython et IronRuby sont tous deux disponibles aujourd'hui.

Pour un guide d'intégration IronPython lire Comment intégrer le support de script IronPython dans votre application existante en 10 étapes faciles .

Lua is a scripting language commonly used in games. There is a Lua compiler for .NET, available from CodePlex -- http://www.codeplex.com/Nua

Cette base de code est une excellente lecture si vous voulez apprendre à construire un compilateur dans .NET.

A different angle altogether is to try PowerShell. There are numerous examples of embedding PowerShell into an application -- here's a thorough project on the topic: Powershell Tunnel

0
ajouté
En passant, j'ai choisi cette réponse comme étant acceptée parce que je voulais de toute façon m'occuper de Python et IronPython, donc l'approche IronPython fonctionne le mieux pour moi .
ajouté l'auteur Michael Stum, source
LuaInterface est un interprète Lua qui fonctionne aussi bien.
ajouté l'auteur RCIX, source
J'ai implémenté C# Script dans un système de workflow en novembre 09. Il a très bien fonctionné pour nous.
ajouté l'auteur David Robbins, source

Vous pourriez être en mesure d'utiliser IronRuby pour cela.

Sinon, je vous suggère d'avoir un répertoire où vous placez des assemblages précompilés. Vous pouvez ensuite avoir une référence dans le DB vers l'assembly et la classe, et utiliser la réflexion pour charger les assemblys appropriés lors de l'exécution.

Si vous voulez vraiment compiler au moment de l'exécution, vous pouvez utiliser CodeDOM, alors vous pouvez utiliser la réflexion pour charger l'assemblage dynamique. article MSDN qui pourrait aider .

0
ajouté

L'application principale que ma division vend fait quelque chose de très similaire à fournir des personnalisations client (ce qui signifie que je ne peux pas publier de source). Nous avons une application C# qui charge les scripts VB.NET dynamiques (bien que n'importe quel langage .NET puisse être facilement supporté - VB a été choisi parce que l'équipe de personnalisation provenait d'un arrière-plan ASP).

En utilisant CodeDom de .NET, nous compilons les scripts à partir de la base de données en utilisant le code source CodeDomProvider (par défaut, .NET 2, si vous voulez supporter les fonctionnalités 3.5, vous devez passer un dictionnaire avec "CompilerVersion" = "v3.5" à son constructeur). Utilisez la méthode CodeDomProvider.CompileAssemblyFromSource pour le compiler (vous pouvez passer des paramètres pour le forcer à compiler en mémoire uniquement.

Cela se traduirait par des centaines d'assemblages en mémoire, mais vous pourriez regrouper tout le code des classes dynamiques en un seul assemblage, et recompiler le tout en cas de changement. Cela a l'avantage que vous pourriez ajouter un drapeau à compiler sur le disque avec un PDB pour quand vous testons, vous permettant de déboguer à travers le code dynamique.

0
ajouté

La prochaine version de .NET (5.0?) A beaucoup parlé de l'ouverture du "compilateur en tant que service" qui rendrait possible l'évaluation directe des scripts.

0
ajouté
Oui. Bien que Roslyn soit encore à l'horizon, Mono.CSharp (disponible sur NuGet) contient toutes les mêmes fonctionnalités.
ajouté l'auteur Eric Falsken, source
Ajout d'une mise à jour pour garder les options pertinentes: La plate-forme de compilateur .NET ("Roslyn") est disponible. Donc, c'est une alternative viable à tous les autres mentionnés. github.com/dotnet/roslyn .
ajouté l'auteur Riv, source
Je crois que cela fait référence à Roslyn? en.wikipedia.org/wiki/Microsoft_Roslyn
ajouté l'auteur Stephen Kennedy, source

Si vous ne voulez pas utiliser le DLR, vous pouvez utiliser Boo (qui a un interprète) ou vous pouvez considérer le projet Script.NET (S #) sur CodePlex . Avec la solution Boo, vous pouvez choisir entre des scripts compilés ou en utilisant l'interpréteur, et Boo fait un langage de script agréable, a une syntaxe flexible et un langage extensible via son architecture de compilateur ouverte. Script.NET semble bien aussi, et vous pouvez facilement étendre ce langage ainsi que son projet open source et utilise un générateur de compilateur très convivial ( Irony.net ).

0
ajouté

Vous pouvez utiliser n'importe lequel des langages DLR, ce qui vous permet d'héberger votre propre plateforme de script. Cependant, vous n'avez pas besoin d'utiliser un langage de script pour cela. Vous pouvez utiliser C# et le compiler avec le fournisseur de code C #. Tant que vous le chargez dans son propre AppDomain, vous pouvez le charger et le décharger au contenu de votre coeur.

0
ajouté

Je suggère d'utiliser LuaInterface car il a complètement implémenté Lua où il apparaît que Nua n'est pas complet et probable n'implémente pas certaines fonctionnalités très utiles (coroutines, etc).

Si vous voulez utiliser certains des modules Lua préemballés à l'extérieur, je vous suggérerais d'utiliser quelque chose dans le sens de 1.5.x par opposition à la série 2.x qui construit du code entièrement géré et ne peut pas exposer l'API C nécessaire.

0
ajouté

I'm using LuaInterface1.3 + Lua 5.0 for a NET 1.1 application.

Le problème avec Boo est que chaque fois que vous parser / compiler / évaluer votre code à la volée, il crée un ensemble de classes boo afin que vous puissiez avoir des fuites de mémoire.

Lua en revanche, ne fait pas ça, donc c'est très très stable et fonctionne très bien (je peux passer des objets de C# à Lua et inversement).

Jusqu'à présent, je ne l'ai pas encore mis dans PROD, mais semble très prometteur.

I did have memory leaks issues in PROD using LuaInterface + Lua 5.0, therefore I used Lua 5.2 and linked directly into C# with DllImport. The memory leaks were inside the LuaInterface library.

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

Une fois que j'ai fait cela, toutes mes fuites de mémoire ont disparu et l'application était très stable.

0
ajouté