Pergunta

Eu tenho um joguinho escrito em C#.Ele usa um banco de dados como back-end.É um jogo de cartas colecionáveis, e queria implementar a função dos cartões como um script.

O que quero dizer é que essencialmente tenho uma interface, ICard, que uma classe de cartão implementa (public class Card056: ICard) e que contém a função chamada pelo jogo.

Agora, para tornar a coisa sustentável/modificável, eu gostaria de ter a classe de cada cartão como código-fonte no banco de dados e essencialmente compilá-la no primeiro uso.Então, quando eu tiver que adicionar/alterar um cartão, vou apenas adicioná-lo ao banco de dados e dizer ao meu aplicativo para atualizar, sem precisar de nenhuma implantação de assembly (especialmente porque estaríamos falando de 1 assembly por cartão, o que significa centenas de assemblies) .

Isso é possível?Registre uma classe de um arquivo de origem e instancie-a, etc.

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

A linguagem é C#, mas com bônus extra se for possível escrever o script em qualquer linguagem .NET.

Foi útil?

Solução

Solução C# Script de Oleg Shilo (no The Code Project) é realmente uma ótima introdução para fornecer habilidades de script em seu aplicativo.

Uma abordagem diferente seria considerar uma linguagem construída especificamente para scripts, como FerroRubi, FerroPython, ou Lua.

IronPython e IronRuby estão disponíveis hoje.

Para obter um guia para incorporar o IronPython, leiaComo incorporar suporte a script IronPython em seu aplicativo existente em 10 etapas fáceis.

Lua é uma linguagem de script comumente usada em jogos.Existe um compilador Lua para .NET, disponível no CodePlex - http://www.codeplex.com/Nua

Essa base de código é uma ótima leitura se você quiser aprender como construir um compilador em .NET.

Um ângulo completamente diferente é tentar PowerShell.Existem vários exemplos de incorporação do PowerShell em um aplicativo – aqui está um projeto completo sobre o assunto:Túnel Powershell

Outras dicas

Você pode usar o IronRuby para isso.

Caso contrário, sugiro que você tenha um diretório onde coloque assemblies pré-compilados.Então você poderia ter uma referência no banco de dados para o assembly e a classe e usar a reflexão para carregar os assemblies apropriados em tempo de execução.

Se você realmente deseja compilar em tempo de execução, você pode usar o CodeDOM e, em seguida, usar a reflexão para carregar o assembly dinâmico. Artigo de documentação da Microsoft que pode ajudar.

Se você não quiser usar o DLR, você pode use Boo (que tem um intérprete) ou você pode considerar o projeto Script.NET (S#) no CodePlex.Com a solução Boo você pode escolher entre scripts compilados ou usar o interpretador, e Boo é uma ótima linguagem de script, possui uma sintaxe flexível e uma linguagem extensível por meio de sua arquitetura de compilador aberta.O Script.NET também parece bom, e você pode facilmente estender essa linguagem, além de ser um projeto de código aberto e usar um gerador de compilador muito amigável (Ironia.net).

Você pode usar qualquer uma das linguagens DLR, que fornecem uma maneira de hospedar facilmente sua própria plataforma de script.No entanto, você não precisa usar uma linguagem de script para isso.Você poderia usar C# e compilá-lo com o provedor de código C#.Contanto que você o carregue em seu próprio AppDomain, você pode carregá-lo e descarregá-lo como desejar.

Eu sugeriria usar LuaInterface já que implementou Lua totalmente, onde parece que Nua não está completo e provavelmente não implementa algumas funcionalidades muito úteis (corrotinas, etc.).

Se você quiser usar alguns dos módulos Lua pré-empacotados externos, sugiro usar algo parecido com 1.5.x em oposição à série 2.x que cria código totalmente gerenciado e não pode expor a API C necessária.

Estou usando LuaInterface1.3 + Lua 5.0 para um aplicativo NET 1.1.

O problema com o Boo é que toda vez que você analisa/compila/avalia seu código dinamicamente, ele cria um conjunto de classes boo para que você obtenha vazamentos de memória.

Lua, por outro lado, não faz isso, então é muito estável e funciona muito bem (posso passar objetos de C# para Lua e vice-versa).

Até agora ainda não coloquei no PROD, mas parece muito promissor.

Eu tive problemas de vazamento de memória no PROD usando LuaInterface + Lua 5.0, portanto usei Lua 5.2 e vinculei diretamente em C# com DllImport. Os vazamentos de memória estavam dentro da biblioteca LuaInterface.

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

Depois de fazer isso, todos os meus vazamentos de memória desapareceram e o aplicativo ficou muito estável.

O aplicativo principal que minha divisão vende faz algo muito semelhante para fornecer personalizações de clientes (o que significa que não posso postar nenhuma fonte).Temos um aplicativo C# que carrega scripts VB.NET dinâmicos (embora qualquer linguagem .NET possa ser facilmente suportada - o VB foi escolhido porque a equipe de customização veio de experiência em ASP).

Utilizando o CodeDom do .NET compilamos os scripts do banco de dados, utilizando o VB CodeDomProvider (irritantemente, o padrão é .NET 2, se você deseja oferecer suporte aos recursos 3.5, você precisa passar um dicionário com "CompilerVersion" = "v3.5" para seu construtor).Use o CodeDomProvider.CompileAssemblyFromSource método para compilá-lo (você pode passar configurações para forçá-lo a compilar apenas na memória.

Isso resultaria em centenas de assemblies na memória, mas você poderia reunir todo o código das classes dinâmicas em um único assembly e recompilar tudo quando houvesse alguma alteração.Isso tem a vantagem de poder adicionar um sinalizador para compilar no disco com um APO para quando você estiver testando, permitindo depurar por meio do código dinâmico.

Sim, pensei nisso, mas logo descobri que outra linguagem específica de domínio (DSL) seria um pouco demais.

Essencialmente, eles precisam interagir com meu gamestate de maneiras possivelmente imprevisíveis.Por exemplo, uma carta pode ter uma regra "Quando esta carta entra em jogo, todos os seus lacaios mortos-vivos ganham +3 de ataque contra inimigos voadores, exceto quando o inimigo é abençoado".Como os jogos de cartas colecionáveis ​​são baseados em turnos, o GameState Manager dispara eventos OnStageX e permite que as cartas modifiquem outras cartas ou o GameState da maneira que a carta precisar.

Se eu tentar criar uma DSL, terei que implementar um conjunto bastante grande de recursos e possivelmente atualizá-lo constantemente, o que transfere o trabalho de manutenção para outra parte sem realmente removê-lo.

É por isso que eu queria ficar com uma linguagem .NET "real" para essencialmente poder disparar o evento e deixar a placa manipular o estado do jogo de qualquer maneira (dentro dos limites da segurança de acesso ao código).

A próxima versão do .NET (5.0?) Falou muito sobre a abertura do "compilador como serviço", o que tornaria possíveis coisas como avaliação direta de scripts.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top