|
Um dos recursos mais importantes e mais comuns para a IA em jogos é o uso de scripts. Eles se fazem presentes desde jogos antigos, como Day of the Tentacle ou Quake, até os mais modernos, como Dragon Age e em praticamente todos os gêneros de jogos.
Nesse artigo, vamos ver uma introdução sobre o que são scripts, e como integrá-los na linguagem Java.
Sobre scripts
Scripts são linguagens de programação projetadas com o intuito de serem simples de se codificar. Geralmente, são embarcáveis, ou seja, seu compilador ou interpretador pode ser acoplado ao jogo, o que nos permite compila-los em tempo de execução. A grande vantagem é que com scripts é possível extrair a lógica para fora do código.
Scripts também podem ser usados para criar aplicações extensíveis, criando mods que podem ser plugáveis mesmo após o release do game bons exemplos disso são os jogos: Neverwinter Nights e Oblivion.
Casos comuns e uteis que se usam scripts
Controle de diálogos: Scripts são ótimas opções para controlar o diálogo entre personagens. Muitos diálogos exigirão que o jogador tenha tomado determinadas ações, ou exigirão testes, muitas vezes complexos, para que a opção apareça. Nessas horas, os scripts caem como uma luva, dando ao game designer muita flexibilidade.
Direção de cena: Um dos principais usos de scripts é fazer a direção de “cutscenes”, onde os NPCs guiam os jogadores. Damos à equipe de produção uma ferramenta poderosa, onde ele pode controlar a câmera, mover personagens, mudar parâmetros do ambiente, de maneira a fazer aquela tomada de tirar o fôlego. Em jogos como Dragon Age, scripts foram usados para fazer, por exemplo, a seqüência final de certos golpes que, quando acontecem, arrancam um sorriso de felicidade na cara do jogador;
Lógica da IA: Boa parte do trabalho de IA consiste em ajustar parâmetros. Scripts permitem mover esses parâmetros para fora do código compilado, tornando mais simples essa configuração e manutenção da IA.
Vantagens no uso scripts
Como as linguagens de script são feitas para serem simples, elas oferecem varias facilidades para programação. A maioria delas tem suporte à sobrecarga de operadores, iteradores simplificados, closures ou tipagem fraca.
Uma outra vantagem é que é possível distribuir a criatividade pelo time de desenvolvimento. Como são linguagens mais simplificadas e legíveis, game designers, produtores e até os jogadores podem escrever e modificar nosso jogo. Para os programadores, isso também representa um grande alívio, já que não terão mais que codificar coisas relacionadas à produção do jogo. Honestamente, quem é que gostaria do game designer no pé, impedindo de fazer aquela rotina complexa de IA, porque a opção de diálogo 2 da personagem X precisa trocar de lugar com a opção 3?
Finalmente, scripts também poupam tempo. É possível mudar facilmente o script em qualquer programa de edição de texto sem precisar recompilar sua aplicação, o que pode ser significativo se você estiver desenvolvendo em C++. Sem falar que isso também evita que o programador perca o “fio da meada”, uma vez que o tempo entre fazer um novo ajuste da IA e ver o seu resultado reduz a quase 0.
Desvantagens
Infelizmente usar scripts não é também um mar de rosas. Existem duas grandes desvantagens:
A primeira é que dificilmente você irá contar com os recursos modernos das IDEs na escrita dos seus scripts. Nada de depuradores, ou verificação imediata de sintaxe. A segunda desvantagem é que o código quase sempre será aberto. Portanto, é importante pensar bem sobre quais rotinas realmente irão se tornar scripts modificáveis.
Como funciona
Linguagens de script são executadas dentro dos programas e devem seguir algum protocolo definido pelo programador.
Imaginem um jogo onde o usuário precisa apenas correr e desviar das armadilhas, no script de uma armadilha seria como o seguinte.
- Programa envia para o script o estado atual do jogo (A posição do nosso personagem distraído).
- Programa pede para o script calcular o novo estado.
Dentro do script como podemos fazer o seguinte:
- Verificar se o jogador esta perto, se estiver muda o estado da armadilha para ativá-la;
- O programa verifica o estado atual da armadilha após o script processar e muda o estado no jogo com esse novo valor;
- Se o jogador caso estiver perto ele é apenas mais um infeliz viajante morto por sua armadilha escondida (Sacana você, hein?).
Scripts e Java
Antes de começar
Como exemplo para esse artigo vou usar o Groovy. Os binários podem ser baixados em http://groovy.codehaus.org/ . Para facilitar apenas adicione o groovy-all-(version).jar no classpath da sua aplicação.
Let’s code
O mais interessante é carregar os scripts dentro do nosso programa, então vamos escrever e carregar um.
Salve em um arquivo nomeado Script.groovy com o seguinte conteúdo (Usar um editor de texto simples mesmo).
class Hello {
void salute(){
System.out.println(“Hello World!”);
}
}
Repare que usamos código java dentro do script, que no caso mostra a mensagem ‘Hello World!’ na saída padrão.
Agora criemos uma classe no Java (pode usar sua IDE favorita pra isso) e vamos carregar o script que fizemos.
import java.io.*;
import javax.script.*;
public class ScriptTest {
public static void main(String[] args) throws FileNotFoundException, ScriptException {
//Arquivo com nosso script
File scriptFile = new File("C:/Script.groovy");
//Contém todas ScriptEngines disponiveis
ScriptEngineManager engines = new ScriptEngineManager();
//Pega a ScriptEngine do groovy.
ScriptEngine engine = engines.getEngineByName("groovy");
Class> clazz = (Class>) engine.eval(new FileReader(scriptFile));
System.out.println(clazz);//imprime "class Hello"
}
}
Repare que ScriptEngineManager e ScriptEngine faz parte do pacote padrão do java: javax.script, sendo assim é fácil mudar de uma engine para outra apenas sendo necessário mudar o parâmetro do getEngineByName. Esse suporte existe desde o Java 6.
O método eval(evaluate) que faz a mágica de carregar o script para nós e transformá-lo em um objeto Class. Ou seja, a partir desse momento, nosso script tornou-se uma classe padrão do Java, e poderemos instanciar objetos dela como faríamos com qualquer classe, usando reflexão.
Para facilitar os exemplos criaremos um método que faz essa rotina para nós e retorna o objeto Class, o resultado é o seguinte:
public static Class> getScript(String file) throws FileNotFoundException,
ScriptException {
File scriptFile = new File(file);
ScriptEngineManager engines = new ScriptEngineManager();
ScriptEngine engine = engines.getEngineByName("groovy");
return (Class>) engine.eval(new FileReader(scriptFile));
}
PS: Essa não é uma boa maneira de tratar as exceções, utilize try/catch.
Agora um exemplo de como criar um objeto e invocar o método da nossa classe.
public static void main(String[] args) throws Exception {
Class> clazz = (Class>) getScript("C:/Script.groovy");
Method salute = clazz.getMethod("salute");// Metodo salute() da classe
Object obj = clazz.newInstance();// Um objeto instanciado de Hello
salute.invoke(obj);
}
Usando Reflection acessamos o método salute() da classe Hello. Repare que não é possível fazer:
Hello obj = (Hello) clazz.newInstance();
Pois até o momento seu programa nem sabia que existia essa classe, essa é a mágica do Script. Reflection é interessante, mas podemos fazer algo que facilite muito mais nosso processo, primeiro vamos escrever uma interface no nosso programa java.
package test;
public interface Saluter {
public void salute();
}
E vamos alterar nosso script para o seguinte.
import test.Saluter
class Hello implements Salute {
void salute(){
System.out.println(“Hello World!”)
}
}
Repare que importamos a interface do nosso pacote e mandamos esse código implementa-la, e o método salute() pertence a interface.
E agora nós podemos fazer um cast do nosso objeto para essa interface no Java.
public static void main(String[] args) throws Exception {
Class> clazz = (Class>) getScript("D:/Script.groovy");
Saluter obj = (Saluter) clazz.newInstance();
obj.salute();
}
Mais simples não? E é claro, é possível fazer essa interface com métodos que recebam parâmetros ou retornem algum valor.
E é isso que permite que façamos scripts para jogos.
Jogo da velha
Como exemplo, vamos pensar em como seria um script para jogar (de maneira bem burra) o jogo da velha. Bem a proposta do jogo é bem simples, marcar 3 sinais iguais em linha, coluna ou diagonal em um tabuleiro de 3x3 lugares.
Para nosso tabuleiro vamos criar uma classe chamada Matrix, ela simplesmente guarda em um array[3][3] os valores correspondentes as jogadas, sendo 0=vazio, 1 =jogador1, 2=jogador2.
Para o jogador humano, simplesmente utilizaremos um MouseListener que percebe onde o jogador pressionou o mouse e verificaremos se é possível marcar naquele lugar. Após isso nosso programa pedirá pede ao jogador da IA a posição da próxima jogada. Nossa IA precisa retornar a próxima jogada levando em consideração os lugares marcados na Matrix.
Utilizaremos para isso um script. Vamos convencionar como nosso protocolo, que o programa chamará um método chamado getJogada, passará a ele a situação atual do tabuleiro, e esperará um retorno retorno, que deve ser um array de duas posições onde na posição 0 temos o índice da coluna e na posição 1 o índice da linha.
Podemos codificar esse protocolo na forma de uma interface java:
package player;
import game.Matrix;
public interface Player {
public int[] getJogada(Matrix matrix);
}
Então escrevemos um script que respeita essa interface.
Vamos criar uma lógica simples, que simplesmente faz uma jogada num ponto aleatório (até mesmo IAs randômicas são IA). Caso o ponto esteja ocupado, ele tentará novamente em outra posição, até que seja possível marcar.
import game.Matrix
import player.Player
import java.util.Random
class ScriptPlayer implements Player{
def rdm = new Random()
int[] getJogada(Matrix m){
int i = -1 ,j = -1;
while(!m.isEmpty(i,j)){
i = rdm.nextInt(3)
j = rdm.nextInt(3)
}
return [i,j]
}
}
Voltando ao nosso jogo devemos carregar esse script como vimos antes como uma instancia de Player e utilizar seus métodos para verificar qual a jogada do nosso player AI.
Concluindo
Vimos nesse artigo o quão importante é o uso dos scripts em jogos e um exemplo prático, em Java. Você pode baixar os exemplos de código aqui. Lembre-se que para rodá-lo, também será necessário baixar o groovy.
Você também poderá se interessar por outras linguagens de script. Como o javascript ou o ruby, no caso do Java, as linguagens Lua, TCL ou Python, para o C++, ou ainda as linguagens Boo e a VBScript, para o C#.
-
03/03/2011 10:51:10 |200.149.187.xxx| 123 - habbo

alguem sabe fazer java scripts para criar mobis no habbo ? , Não sou Mod só queria saber msm
-
13/03/2011 09:49:34 | Vinícius Godoy de Mendonça

Não. Pelo que li o jogo nem oferece essa possibilidade
-
13/03/2011 00:03:35 |200.152.64.xxx| Anônimo - Habbo

Preciso tambem saber como fazer um script para o Habbo
-
13/03/2011 09:49:01 | Vinícius Godoy de Mendonça

Não. Pelo que li o jogo nem oferece essa possibilidade.
-
21/07/2011 19:01:35 |186.207.153.xxx| bruno afonso - mobs bots

alguem sabe como fazer mobs ou bots , com esses scrips , para mmorpg tipo wod prefefect word , cabal para ser uzado no unity engine ?
-
22/07/2011 09:33:53 | Vinícius Godoy de Mendonça

Nós sabemos. Mas não iremos ensinar. Esse site é de desenvolvedores de jogos, por isso, estimulamos o gameplay justo, e não tentativas de burlar regras.
-
14/11/2011 20:23:59 |187.107.107.xxx| Junior - anti script

Oi
Sabe me dizer se é possível usar um script que impeça o xiter no jogo, e sobre a linguagem empregada depende do jogo ou pode se usar o java para qualquer um, no meu caso é o América Armys.
att
-
26/08/2011 11:59:16 |201.19.112.xxx| Diogo - TW

gostaria de saber se tem programas para criação de Scripts pois quero aprender a usar ! Para por para autorização no TRIBAL WARS !
Abçs
-
27/08/2011 09:34:21 | Bruno Crivelari Sanches

Programa para criação de scripts? Tipo bloco de notas?

-
10/03/2012 01:59:47 |201.95.16.xxx| Miller - duvida

é possivel usar scripts em jogos de blowser tipo batllestar galatica para que nocaso sua nave realize algumastarefas automaticamente?
-
10/03/2012 11:34:47 | Vinícius Godoy de Mendonça

Se o desenvolvedor do jogo incluir essa funcionalidade, será possível sim.
-
24/03/2012 17:42:42 |189.27.53.xxx| gabriel - e possivel?

quero saber se e possivel fazer isso : no jogo ddtank que eu jogo , eu ganho uma certa quantidade de 400 cupons cada vez que eu faço uam coisa, tem como eu almentar este valor atravez de script?
-
24/03/2012 18:51:48 | Bruno Crivelari Sanches

Nosso objetivo aqui não é ensinar trapacear em jogos e se o tal jogo é online, duvido que o desenvolvedores tenham sido ingênuos (ou burros se alguém preferir) de deixar esse controle de premiação no lado do cliente ou algo que possa ser burlado com alterações no cliente.
Isso tudo é controlado no servidor.
-
12/04/2012 14:49:25 |200.19.254.xxx| Mauro Barbat - Troca de dados entre Lua e Java

Olá Pessoal, vocês sabem como pode se trocar informações entre o lua e o java? tipo quando eu chamo um script lua dentro do Java ele recalcula e gera novos parametros, porém como eu mando parametros para o Lua trabalhar e como devolvo os resultados para o Java?
-
12/04/2012 19:14:05 | Vinícius Godoy de Mendonça

Depende, qual binding de lua você está usando?
Muitos usam a maneira tradicional do LUA, que é através de uma pilha, implementada no LuaState.
-
02/05/2012 14:52:53 |150.162.102.xxx| Paulo Ribeiro

Estou gostando muito do site, aprendendo um bocado, quero começar a desenvolver pequenos jogos em java (só para passar o tempo mesmo), e vou usar estes artigos como base para minha ascendência nesta grande jornada (rs.). Mas daí eu me deparo logo com um negócio destes:
Class clazz = (Class) engine.eval(new FileReader(scriptFile));
O que acabou de acontecer? Gostaria de saber tudo de cabo a rabo para não ficar sombra de dúvidas. Eu imagino que esse trecho de código está pegando o conteúdo do script, que está dentro do arquivo .groovy, e está transformando numa classe (tipagem (Class)), chamando-a de "clazz". Agora por quê esse negócio "feio" aí de ? rs.
Agradeço desde já!
Um Abraço!
-
02/05/2012 14:54:47 |150.162.102.xxx| Paulo Ribeiro

opa, talvez seja comentários que a página barrou aguardando um "script injection"?
o "negócio feio" qual eu me referi anteriormente foi o "< ! - - ? - - >" (sem os espaços, claro)
-
04/05/2012 00:01:10 | Marcos Vasconcelos

Isso são erro do script de highlight do Ponto V, o correto é apenas que é o wildcard generics.
-
04/05/2012 00:02:23 | Marcos Vasconcelos

Class clazz = (Class) engine.eval(new FileReader(scriptFile));
O Groovy script cria um Class baseado no script.
-
02/05/2012 15:06:56 |150.162.102.xxx| Paulo Ribeiro

Nossa, nisso que dá perguntar alguma coisa antes de terminar de ler o artigo! Você pode ficar com mais dúvidas e querer perguntar de novo! rs.
Como eu "instalo" o groovy? Que classe é essa que é importada game.Matrix? Já é implementada no java? preciso baixar alguma coisa ou foi uma classe criada por você? O método isEmpty recebendo os índices i e j?
Assim, sei que minhas dúvidas podem estar enchendo o saco rs. ainda estou começando e não sei muitas coisas. Quando encontro essas partes "desamarradas" eu me pergunto porquê foi deixada assim. É intencional? É importante saber disso, ou eu posso "passar direto" (eu já deveria saber isso?)?
Acho que por enquanto é só, pessoal! rs.
Abraço!
-
04/05/2012 00:03:08 | Marcos Vasconcelos

"Antes de começar
Como exemplo para esse artigo vou usar o Groovy. Os binários podem ser baixados em http://groovy.codehaus.org/ . Para facilitar apenas adicione o groovy-all-(version).jar no classpath da sua aplicação."
-
04/05/2012 00:05:10 |186.222.48.xxx| Paulo Ribeiro

Ih, caramba, acho que passei voando por isso aí rs. Desculpa a falta de atenção e obrigado!
Abraço!
-
04/05/2012 22:16:05 |201.67.52.xxx| edudohabbo - mobis como criar usando script?

vcs sabem algum bug de script no habbo hotel? ja vi varios videos , ja fui hackeado varias vezes e nunca dei conta de usar script nesse jogo!
-
15/05/2012 11:44:08 |200.144.12.xxx| Janil - KKK

kkkkk
Como tem babaquinha querendo trapacear... Velho... Leiam pelo menos o post...O objetivo de criar scripts é ajudar o desenvolvimento DO SEU PRÓPRIO JOGO.
Anyway, muito bom os posts e o site em si... Pretendo usar bastante daqui para frente

Gostei bastante dos roadmaps, já estou seguindos o livros.
Programo a uns 3 anos em C++, nada profissional, hobbie.
Estou no último ano do ensino médio, tenho 17 anos e pretendo fazer física, o que vocês acham que eu deveria estudar Java para desenvolver jogos por hobbie?
E mais uma pergunta, este ano tenho que escolher meu curso de graduação, gostaria de saber se existe alguma área que misture física (moderna, não a clássica, quantum, física de plasmas, de particulas elementares) e gamedev?Ah sim, podem fazer um roadmap para gamedev? Matemática nescessária, design patterns e esses detalhes mais técnicos de antes da programação? E um de Java/C++ para gamedev? *--*
-
15/05/2012 12:04:18 | Vinícius Godoy de Mendonça

Olá.
Não acho uma boa estudar Java para gamedev. Se você já sabe C++, siga em frente na linguagem. Até porque, sua inclinação é de coisas mais hardcore (como engines de física).
Um curso que se aproxima do que você quer é o de matemática industrial. Outra boa opção pode ser a engenharia mecatrônica ou engenharia eletrônica. Agora, você tem que pensar se sua inclinação é mais programar, ou fazer contas. Nada impede você de cursar Ciência da Computação, e depois estudar física e matemática em especializações ou mesmo numa segunda faculdade. O curso de ciência vai te dar uma boa base da computação científica, ideal para o tipo de aplicação que você gostaria. Também vai te dar uma visão bastante geral da área, e você verá outros locais onde a matemática e física são usadas na computação (como na Computação Gráfica, por exemplo).
Só não recomendo mesmo cursos de mais alto nível, focados em processos, como Análise de Sistemas ou Sistemas de Informação. Esses cursos são bem longe de programação, e das contas também.
Por fim, seria muito difícil escrever um roadmap de gamedev. O campo é muito vasto. Entretanto, há vários livros em nossa livraria virtual. Todos são livros recomendados por nós, e colocamos uma breve descrição sobre o que você encontrará neles: http://www.pontov.com.br/site/livrosv
Lá você encontra recomendação de livros de física, matemática e computação gráfica também.
-
15/05/2012 18:40:39 |189.47.28.xxx| Janil - Obrigado

Cara, muito obrigado...
Vou continuar estudando C++...E muito obrigado... Estou pensando em cursar as duas graduações, Física e Ciência da Computação. São duas áreas que muito me interessam, só falta escolher agora qual farei primeiro.
E me desculpe, não tinha percebido as categorias de livros na livraria virtual, pensei que só existiam os livros de programação de jogos.
Muito obrigado mesmo. Até mais.











Olhar velhinho...gostei muito da sua sacada para usar scripts em jogos, sua explicação foi muito proveitosa. Estou usando começando a mexer em Lua, vou ver se consigo usa ela com Java, vc tem alguma dica?