Criando comunidades
A estrutura básica dos simuladores online

Se você é fã de futebol e de computadores, deve conhecer um jogo que fez muito sucesso há algum tempo atrás (e ainda faz), chamado Elifoot. Nele você faz o papel de um técnico de futebol, que gerencia um time. Compra jogadores, vende, participa de campeonatos, etc. Não é um jogo de animação, não é um jogo 3D e nem exige matemática quântica para executar suas tarefas: é um jogo de estratégia, um simulador de realidade.

O que chama a atenção neste tipo de jogo é que com o advento da internet eles se tornaram bem mais atraentes do que eram antigamente e sua construção não exige um trabalho extenuante, nem conhecimentos profundos de programação. Qualquer pessoa com um mínimo de conhecimento pode montar um modelo de simulador. E não precisamos ficar só na simulação de futebol, basquete, tênis, ou outro esporte qualquer, mas ir para campos ainda pouco explorados dentro deste modelo de jogo, como batalhas navais, conquistas espaciais, impérios financeiros, comerciais, etc, etc, etc...

Como se isso não bastasse, esse tipo de jogo está abrindo novos negócios em termos de entretenimento digital, via internet. Simuladores de futebol, só no Brasil já existem mais de 3, inclusive em regime de acesso pago com privilégios. Um negócio que só tende a crescer com o tempo.

Como se isso não bastasse e contrariando o senso desenvolvimentista atual, que prega a produção feita por grandes equipes, construções sofisticadas em 3D, investimentos astronômicos em motion capture e marqueting, este tipo de jogo pertence a uma categoria onde o grande diferencial é a idéia central do mesmo. Não seus recursos gráfico/visuais, mas o que ele nos permite fazer, dentro da comunidade que se cria à sua volta. O caso típico de jogo que nasce de uma mente criativa, praticamente sem recursos financeiros e invariavelmente como uma criação solitária. Este talvez seja um dos únicos segmentos no setor de games onde uma boa idéia pode dar melhores resultados que uma gigantesca produção.

A base técnica para qualquer um desses jogos de simulação é uma estrutura de cliente/servidor (no club TILT tem um e-Book só sobre isso), um pequeno e simples sistema de banco de dados e a programação da função específica do jogo, ou simulação (aquilo que os hardgammers adoram chamar de IA, cujas potencialidades são cantadas em verso e prosa, mas que ainda está muito longe de ser uma inteligência).

No que diz respeito a banco de dados, não vamos exagerar e usar tudo o que o Delphi tem sobre isso, mas vamos aproveitar uma de suas estruturas de programação mais práticas: o record. Um record (ou registro) nada mais é do que uma estrutura pré definida de dados.

Por exemplo: digamos que o propósito seja criar um simulador de campeonato de futebol, à lá Elifoot e assemelhados. Toda a estrutura do jogo gira em torno de um cadastro de jogadores, então o primeiro passo é criar esse modelo de dado:

implementation
{$R *.DFM}
type
Jogador = record
Nome: string[30];
Nick: string[15];
Nasc: TDateTime;
Passe: currency;
Clube: byte;
Titular: boolean;
end;

Note que essa estrutura apenas define um tipo de registro, chamado Jogador. Podemos dizer que as variáveis serão suas propriedades, tais como nome completo, apelido, valor do passe, data do nascimento, etc. O record não é uma variável em si mesma, mas uma definição de formato. Para usá-la teremos que declarar as variáveis efetivas, ou melhor, uma matriz de variáveis (um array de Jogadores):

var
Jogs: array of Jogador;

Portanto, quando quisermos fazer referência a um jogador em especial, usamos o índice da matriz e a “propriedade” desejada. Por exemplo, para saber o nome do jogador 5: Jogs[5].Nome. O apelido dele: Jogs[5].Nick; o valor do passe: Jogs[5].Passe e assim por diante.

A declaração acima é de um array dinâmico, ou seja, não tem um número predeterminado de entradas e cada vez que um jogador for incluído na estrutura será preciso aumentar a quantidade de itens na matriz (que começa invariavelmente com zero). Para isso usamos a função SetLength(array,quantidade) e uma variável para controlar a quantidade de jogadores (var TotJogs: integer;).

Imagine que está montando um utilitário para “criar e editar jogadores” e ao clicar um botão, cria-se um determinado jogador:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
TotJogs:= TotJogs + 1;
SetLength(Jogs,TotJogs);
Jogs[TotJogs-1].Nome:= ‘Nome do jogador’;
Jogs[TotJogs-1].Nick:=’Apelido dele’;
Jogs[TotJogs-1].Nasc:= StrToDate(‘10/10/80’);
Jogs[TotJogs-1].Passe:= StrToCurr(‘100000,00’);
Jogs[TotJogs-1].Clube:= índice da lista de nomes dos times;
Jogs[TotJogs-1].Titular:= true;
end;

O ideal seria apontar para TEdits que permitissem a digitação/alteração dessas características ou propriedades. Para completar esse pequeno utilitário, é preciso gravar o cadastro em um arquivo, para que outro programa tenha acesso a essa informação:

procedure TForm1.SpeedButton2Click(Sender: TObject);
var
ArqJog: file of Jogador;
Tm: integer;
begin
AssignFile(ArqJog,'jogadores.dat');
Rewrite(ArqJog);
for Tm:= 0 to TotJogs-1 do Write(ArqJog,Jogs[Tm]);
CloseFile(ArqJog);
end;

Sabemos quantos jogadores existem no cadastro e portanto basta fazer um looping e gravar um a um. A operação inversa usa um conceito diferente para o looping, uma vez que não se sabe o número exato de jogadores que serão carregados:

procedure TForm1.SpeedButton3Click(Sender: TObject);
var
ArqJog: file of Jogador;
begin
TotJogs:= 0;
AssignFile(ArqJog,'jogadores.dat');
Reset(ArqJog);
while not eof(ArqJog) do begin
TotJogs:= TotJogs + 1;
SetLength(Jogs,TotJogs);
Read(ArqJog,Jogs[TotJogs-1]);
end;
CloseFile(ArqJog);
end;

O arquivo é aberto e lido até que seu final seja encontrado (eof – End Of File). Esta é portando a base do cadastro de jogadores, sobre a qual iremos montar o simulador dos nossos sonhos. Claro, não precisa ser necessariamente um simulador de campeonato de futebol, como já falei.

O terceiro aspecto característico deste tipo de jogo é a mecânica funcional da partida. Obviamente estamos considerando que essas operações ocorrerão dentro do servidor, com acesso total aos cadastros específicos do jogo. As questões relevantes aqui irão aparecer numa análise mais detalhada do que se pretende fazer do jogo.

Por exemplo, no caso do simulador de campeonato de futebol, a base dos dados é o cadastro dos jogadores e de um segundo cadastro, que é de times. Cada usuário é na verdade um time e como os jogadores podem ser referenciados pelo seu índice na matriz, podemos considerar que cada jogador tem um ID próprio e portanto, um time nada mais é do que um array com 22 Ids de jogadores (e mais alguns dados, como nome do técnico, nome do time, etc, etc).

O servidor dá conta de duas tarefas distintas: transacionar as operações dos usuários (lembre-se, na estrutura cliente servidor, o programa cliente solicita uma ação e o servidor a executa, se possível) e proceder ao processamento dos “turnos”. Se está em dúvida de como montar a estrutura cliente/servidor, dê uma revisada em nosso e-Book sobre jogos multiplayer..

Transacionar as operações dos usuários significa promover (se possível) todas as solicitações efetuadas. Por exemplo uma troca (por empréstimo) de dois jogadores, entre dois times ou uma compra e venda, etc. Esse tipo de processamento é bem simples.

Já o processamento de um turno é mais complicado e necessita de algumas avaliações. A pergunta que o desenvolvedor deve responder aqui é: o que vai acontecer ou o que caracteriza um turno do jogo? Pode ser por exemplo uma partida disputada entre dois times. Como efetuar isso, ou seja, como decidir uma partida/disputa sem arrancar os cabelos e sem perder noites de sono com programação em sânscrito?

Simples: use o sistema de pesos. Todo tipo de disputa, ocorra ela entre times de futebol, navios de guerra, naves espaciais, negócios na bolsa de valores ou seja lá o que você inventar, está baseada no potencial de cada um e mais um tiquinho de sorte, que chamaremos de "o imponderável", apenas para usar uma palavra mais bonita. É isso mesmo: o bom e velho randomize (gerador de números aleatórios).

Não é apenas randomizar um resultado, correto? Usamos pesos, para orientar a forma como o número aleatório será gerado. Um cálculo de probabilidades bem simples: quanto mais potencial um time tem (jogadores mais habilidosos, melhores condições físicas, jogando em casa, histórico das partidas com o adversário, etc), mais chances ele terá de vencer a partida. Mas, como diria um jogador famoso: o jogo só termina quando acaba, ou seja, ter maiores chances não significa necessariamente que irá ganhar e é aí que entra o imponderável. As vezes, contra tudo e contra todos, o mais fraco e menos cotado ganha.

No final do processamento de um turno, apuram-se os ganhos e perdas de cada usuário e passa-se à preparação da próxima rodada. Simples e sem maiores sofisticações.

Portanto, deixe de lado por algum tempo aquela sua insistente idéia de que vai parir a novissima geração de jogos 3D, mais sofisticada do que as produzidas à lá roliúde e que será reverenciado pelas próximas gerações como o maior criador de jogos de todos os tempos e concentre-se numa idéia simples e que esteja afinada com o gosto das pessoas.

Se precisar de ajuda para descascar alguns pepinos da programação ou de design do jogo, estamos aqui para isso mesmo.


Download...
Clique no link para fazer o download dos arquivos. Se sua assinatura do club TILT está para vencer, clique aqui e saiba como renová-la.

edtjog.zip  O editor/criador de jogadores para você implementar com novas funções e recursos.
 
online