Como posso implementar scripts inteligentes no meu jogo?

18

Estou desenvolvendo um mecanismo de jogo. Supõe-se que seja uma entidade / componente baseada. Para desenvolver meu próprio jogo, pensei em usar alguma linguagem de script para realmente criar as entidades.

Por exemplo, se eu quiser adicionar um tipo de monstro agressivo ao jogador, será uma entidade com vários componentes; esses componentes mudarão com o tipo de monstro; portanto, se eu tiver cem tipos diferentes de monstros, no meu jogo, não precisarei criar um novo método para cada um deles diretamente no código do meu jogo.

Devo usar uma linguagem de script para descrever essa entidade, em termos de componentes ou há algo mais que funcione melhor? De maneira mais geral, como devo usar o script no meu jogo?

nathan
fonte
Para apenas a descrição da entidade, você pode usar apenas xml ou algo semelhante, sem necessidade de script. Para scripting i usaria C #, mas apenas se o motor está em .NET ...
Kikaimaru
@Kikaimaru C # Não é uma linguagem de script. Usar lua seria uma idéia melhor ou algum outro idioma que possa ser incorporado ao seu mecanismo.
JDweetBeat
@DJMethaneMan "C # não é linguagem de script" não significa nada. Não há absolutamente nenhum problema em escrever scripts em C # em um jogo escrito em C # e usar algo como Roselyn para compilação ... Mas depois de 4 anos, eu usaria json a javascript em vez de xml e C # :)
Kikaimaru

Respostas:

17

Meu jogo usa uma estrutura de componente de entidade e usa scripts para definir entidades (isso não define diretamente o comportamento, falarei mais sobre isso no final). Os scripts definem os componentes reais a serem usados ​​para criar cada entidade. Ele usa uma linguagem de script simples que eu criei. Aqui está uma versão simplificada de um dos meus scripts:

ENTITY:"Goblin"
{
    description="It's currently their age."
    commonname="goblin"
    pluralCommonName="goblins"
    childname="gob'in"
    pluralChildName="gob'ins"
    active=Nocturnal
    tags=Mobile
    baseAttributes="OrganicMobileCreature"

    [Model]{
            meshname="Goblin"
            texturename="GoblinTexture"
    }

    [Motion]{
            maxvelocity=0.01:0.015
            locomotion=Walk,Swim
    }

    [Skills]{
            ALL=0.01:0.05,Mine=8.3:8.8,PlaceCube=8.3:8.8
    }

    [Inventory]{
            maxItems=2
            Allow=ALL
            Disallow=NONE
    }
}

Muito disso é auto-descritivo, mas aqui estão alguns destaques:

  • A primeira seção descreve as informações comuns para a entidade. Isso inclui uma descrição e nomes de exibição para vários aspectos da entidade.
  • A baseAttributestag faz referência a outro arquivo de script que define componentes comuns que não quero redefinir várias vezes. Ele contém componentes como position, liferequirementse assim por diante. Se qualquer componente for definido aqui novamente, esse componente substituirá o comum.
  • Cada [NAME] { }conjunto define um novo componente que será adicionado a essas entidades.
  • Esta descrição não é apenas para uma única entidade , é para todos os goblins criados. Você verá que alguns dos valores têm intervalos (ou seja 0.01:0.015), quando um novo duende é criado, ele é criado com um componente que possui um valor aleatório nesse intervalo. Portanto, cada duende terá habilidades ligeiramente diferentes e velocidades ligeiramente diferentes. Essa configuração define que todos os goblins começarão com habilidades realmente boas na colocação de cubos e mineração, o que é realmente apenas para meus próprios fins de teste. Mas como tenho certeza de que você pode adivinhar, é muito fácil alterar os valores para o que eu quiser.

Essa coisa toda envolve a criação de um analisador personalizado, algum tipo de estrutura para conter as definições de entidade (eu chamo de Lexicon!) E uma fábrica para obter essas definições de entidade e gerar novas entidades. Para mim, esse sistema ainda está em seus estágios iniciais, mas está saindo muito, muito bem. É um sistema bastante poderoso para definir rapidamente entidades e permite que você crie qualquer entidade desejada usando os componentes que você criou. Se você não estiver confortável em criar seu próprio analisador, acho que o XML funcionará bem. Eu converti o meu de um analisador recursivo de pushback que escrevi para uma linguagem de programação um pouco inventada.

Como você pode ver, isso define a entidade. Mencionei que ele não define diretamente o comportamento. No entanto, pode facilmente definir coisas como inimigos odiados e quão agressivamente reagir a esses inimigos. Isso seria tão simples quanto definir qualquer componente que você usa para controlar esse comportamento. Minhas entidades também possuem um componente de inteligência (não mostrado) que define coisas como:

  • Como o caminho encontra (movimento simples da linha de visão, A * simples, A * preditivo, etc.)
  • Quão agressivos / defensivos eles são. As entidades podem ter zonas domésticas que serão defendidas, mas talvez não sejam agressivas fora dessas zonas.
  • Sensibilização tecnológica (portas abertas, uso de gadgets, evitar armadilhas, etc.)
  • E mais...

Por mais que o seu seja definido, é o seu sistema que direcionará os dados nesse componente, o que, por sua vez, afeta o comportamento de suas entidades.

MichaelHouse
fonte
Obrigado por compartilhar. Na verdade, acho que vou tentar fazer isso usando o formato XML. Eu tenho pensado muito sobre isso (graças ao AbstractChaos btw) e deve atender às minhas necessidades (pelo menos para descrições de entidades).
Nathan2
11
@nathan Concordo que você deve ir com XML. O motivo da minha postagem foi mais quais dados incluir no seu XML e como usá-lo. O formato dos dados pode ser o que você quiser. Os dados que você escolhe incluir e como implementa seu uso são muito mais importantes.
MichaelHouse
@ Byte56 Eu sei que este post é antigo, mas como você pode lidar com os relacionamentos entre pais e filhos? Digamos que temos uma árvore de Habilidades e você precisa de 10 pontos na habilidade A [0] para ativar A [1] e 10 pontos nessa para habilitar A [2], etc. ParentId? Obviamente, eles são logicamente equivalentes, mas eu esperava que você tivesse alguma ideia do mundo real.
28615 Superstringcheese
@Superstringcheese if player.hasPoints(10) then i++ end skillTree[i]seria um pseudocódigo. Não tenho idéia de como essa pergunta é relevante para o post, no entanto.
JDSweetBeat
4

Se tudo o que você realmente precisa é de uma maneira de definir os componentes de um Monster, o XML funcionará bem, tanto o C # quanto o Java terão uma implementação extremamente rápida.

Seu xml pode ser

<?xml version="1.0" encoding="UTF-8"?>
<mobs>
  <mob>
    <personality>Aggressive</personality>
    <intelligence>20</intelligence>
  </mob>
</mobs>

Então sua classe Mob pode parecer. (Java)

public class Mob {
  private IPersonality personality;
  private Integer intelligence

  //**  Getters & Setters **//
}

Onde IPersonality é uma interface.

Você pode carregar seu xml e analisar cada valor através de uma fábrica.

por exemplo, Analise o valor da personalidade no PersonalityFactory, que é simplesmente:

public IPersonality getPersonality(String personalityName) {
  if(personalityName.equals("Aggressive")) {
    return new AggressivePersonality();
  }
  else if(personalityName.equals("Passive")) {
    return new PassivePersonality();
  }
  else {
     //Maybe allow for no personality (We all know monster like that ;) )
     return null; 
  }
}

Então você pode montar uma multidão assim

Mob mob = new Mob();
mob.setPersonality(getPersonality(xmlValue));
mobList.add(mob);

A chave é que seu mecanismo conhece o formato do xml e tem uma fábrica para tudo o que precisa.

Uma vantagem do xml é que você pode definir seu próprio esquema para garantir que o formato esteja sempre correto, veja aqui .

Espero que isto ajude

AbstractChaos
fonte
Na verdade, eu preciso encontrar uma maneira de criar facilmente nova entidade ao longo do jogo no processo de desenvolvimento do jogo. O xml será flexível o suficiente? Precisarei adicionar scripts de qualquer maneira para a lógica interna do jogo.
Nathan2
Se você ler a classe Mob como Entidade, estará criando uma nova Enitity (Mob) usando XML com componentes diferentes (IPersonality, Intelligence [exemplo de dados para essa mob]). E, infelizmente, não posso responder se será flexível o suficiente, pois não sei o que mais você deseja fazer além do que especificou. No entanto, XML é um formato em que os únicos limites são como você interpreta cada seção. Atualize sua pergunta com um exemplo detalhado e mostrarei um xml que pode lidar com isso. Parece que a lógica interna do jogo deve ser interna?
AbstractChaos
0

Python está bem, eu acho. Geralmente, o LUA também é uma boa alternativa se você deseja adicionar recursos de script aos seus programas.

Você pode usar XML para descrever o comportamento de seus monstros, isso envolveria alguma codificação no código do jogo, porque você salvará apenas o "nome" ou alguns atributos de acordo com o comportamento (velocidade, tipo de arma que o monstro usa, etc.) do comportamento a ser usado no código do jogo.

Se você usar um Scriptengine (por exemplo, LUA), poderá transferir esse código do seu programa pré-compilado para arquivos de script que são carregados durante o tempo de execução. Para fazer isso, você deve expor a API dos seus "monstros" ao mecanismo de scripts. Isso permite que você chame os métodos do código do jogo de monstros de fora.

Aron_dc
fonte
A API do meu monstro? Quero dizer, terei que ser capaz de criar novos componentes a partir do script (instanciação). É possível?
Nathan2
Afaik isso deve ser possível. Você também pode usar uma abordagem mista de armazenamento externo (como mencionado por abstractchaos ou byte56) e linguagem de script (LUA, Python ...). A principal vantagem de, por exemplo LUA é que você pode alterar o código em tempo de execução e é instantaneamente disponível na sua correr jogo / motor
Aron_dc
Ho a sério? É uma vantagem enorme mesmo. Também tenho embora LUA (ou outra linguagem de script) para "linha do tempo do jogo". Quero dizer, para criar algumas cenas em que o jogador precisa ser bloqueado, esse sprite precisa se mover aqui, iluminar aqui e ali ... Então, talvez eu também possa usar uma linguagem de script para carregar entidades? Também vou postar outra pergunta para expor minha maneira atual de gerenciar entidades / componentes sobre o que chamo de "gerente" para ver se estou indo bem.
Nathan3 de