quarta-feira, 25 de abril de 2012

Banco de Dados em Jogos Digitais Ver 1.0


Banco de Dados em Jogos Digitais

Helder Henrique do Nascimento Peres*

Abstract:
In this work, it’s listed some tips of Data Base fundaments and how they are applied in digital games, the importance of having a data base in recent games and which are the fundamentals things to develop it. This article also implies in the feature specific to games that is the interface in the data base of games. This article has as its goal, to reunite information about data base and how they are applies in games, and how the relational model helps a lot the developer’s life when giving manutence.
Resumo:
Neste trabalho, está reunidas dicas de fundamentos para Bancos de Dados e como os mesmos são aplicados em jogos digitais, à importância de se ter um banco de dados nos jogos digitais recentes e quais são as coisas fundamentais para desenvolver do mesmo. Confere-se também neste artigo, uma característica especifica dos jogos em relação à interface do banco de dados em jogos. Este artigo tem como objetivo reunir informações sobre bancos de dados e como eles são aplicados nos jogos eletrônicos, como o modelo de relacionamento ajuda muito a vida do desenvolvedor ao dar manutenção em jogos de muitos jogadores.
*Instituto Federal do Paraná-Campus Londrina
Rua João XXIII, 600 – Praça Horace Well – Jardim Dom Bosco CEP 86060-370 – Londrina-PR



1)   Introdução

Jogos digitais nada mais são do que outro software de prateleira. E como todo o software é muito importante guardar seus dados e por isso que se deve programar um banco de dados na maioria dos jogos digitais dos dias de hoje.
Nos primórdios dos jogos digitais, não era necessário à criação de um banco de dados, por que os jogos eram simples e precisavam apenas de algumas horas para serem completados e não eram muito difíceis.  Quais querem pontuações que o jogador fazia era apenas armazenada na memória virtual do console, que, quando se desligava o mesmo a memória era apagada levando consigo todas as pontuações e demais informações do jogo.
Conforme a tecnologia e a complexidade dos jogos foram evoluindo, surgiu a necessidade de criar sistemas para que o jogador continuasse de uma faze que ele morreu o teve que desligar o console. Esse sistema, ainda não tinha nada a ver com banco de dados, era apenas um sistema de senhas onde o jogador digitava a senha correspondente a aquela faze. Esse sistema, na grande maioria dos jogos só era relativo á faze e nunca recuperava os itens e demais extras que o jogador tinha.
Com o passar do tempo, sistemas de salvar informações nos próprios cartuchos foram criados, fazendo assim possível um banco de dados nos jogos. Esses arquivos eram armazenados em memórias RAM a base de bateria sendo assim armazenáveis. 
Mas á frente, o banco de dados dos jogos foram ficando mais complexos e quando se chegou á era dos CDS, os jogos precisando de um dispositivo externo de armazenamento com maior tamanho de armazenamento e maior complexidade dos bancos de dados.



2)   O Banco de Dados e o jogo

Um banco de dados nada mais é do que aquilo que o jogo deverá salvar para o jogador.
Segundo Luke Hutscal, especialista de longa data na área de criação de jogos em browser,
O banco de dados do jogo é muito mais importante e deve ser feito primeiro do que a lógica.
Afinal, de nada vale uma boa lógica se você não tem nada sobre o que trabalhar nela, e as coisas que você coloca no banco de dados serão as coisas armazenadas em seu jogo.
Também segundo o mesmo autor, é importantíssimo fazer o modelo de entidade e relacionamento. Fato este, devido á necessidade de correção de algum item ou elemento salvo no banco de dados.
Em um jogo de navegador, ou de MMORPG um jogador deve ter nome de usuário e senha e um ID único. Em alguns casos, o ID pode ser u nome de usuário, mas isso fará com que seja necessário verificar constantemente se aquele nome se encontra disponível.

Esse ID será a chave primária do jogador, ou seja, nenhum jogador terá o mesmo ID sendo ele unicamente identificável no banco de dados. O Comando de auto_incremento significa que ele será incrementado sozinho toda a vez que um jogador for salvo dando a certeza que não terá dois jogadores com o mesmo ID.
A maioria dos jogos, o jogador tem um iventório de itens,  então a seguir será demonstrado como se cria uma segunda tabela que será a de itens e ao menos tempo ligá-la á tabela do jogador:
REATE TABLE items (
id int NOT NULL AUTO_INCREMENT,
name varchar(200),
description text,
PRIMARY KEY(id)
);
CREATE TABLE user_inventory (
id int NOT NULL AUTO_INCREMENT,
item_id int,
user_id int,
quantity int,
PRIMARY KEY(id)
);
A primeira tabela é a tabela de itens de jogo, e a segunda é o iventório de itens do jogador.
O item do jogo se relaciona com o jogador através da tabela de inventorio de itens daquele jogador. Para identificar aquele único jogador se existe o ID que é a chave primária do jogador e o ID do item é a chave primária do mesmo. Este é um exemplo clássico de entidade relacionamento que deve ser mantido sempre em jogos, pois se precisar mudar um item de seu jogo ou renomear basta fazer uma vez na tabela onde tem todos os itens, que vai estar ligada a todos os jogadores.
 Então, para melhorar ilustrar, suponha-se que o jogador pegue um item: “A Espada Vorpal de Existência Hipotética". Para adicioná-la ao inventário do jogador, deve-se descobrir qual ID a Espada Vorpal possui e adicioná-la á coluna da tabela vazia ou atualizar uma existente. 
Também por atribuí-la a um ID único poderá atualize-la uma vez só, caso haja algum bug. É possível até renome-la para outro nome, como "Espada Nefasta de Existência Hipotética" ou algo assim. 
Quando o item está armazenado em uma única tabela, fica fácil editá-lo. Mas já pensou se a Espada Vorpal estivesse armazenada na tabela de itens do jogador? E fosse necessário mudar o nome dela?
Seria necessário atualizar a o item de cada jogador que tivesse a Espada Vorpal.
Obviamente, fazendo um modelo de relacionamento bem feito, economiza-se tempo ao se atualizar dados na tabela. Será necessário fazer apenas uma alteração ao invés de atualizar os campos de cada jogador. 


3)   O que é usado nos jogos

Como sugerido anteriormente, não existe um modelo padrão para se modelar o banco de dados dos jogos. Na verdade, não existe um único modelo padrão para todos os softwares. Cada caso deve-se ser estudado para se aplicar a melhor ferramenta e metodologia para aquele caso. Pode-se ser modelado no modelo relacional ou não relacional (como  MongoDB ,Redis ,CouchDB) ou até arquivos simples sem muita segurança. Não há regras que dizem o que se deve fazer no software de jogo. Um exemplo disso, é que em jogos onde se salva os dados na própria mídia (cartuchos e fitas) não é necessária tanta segurança e podem-se criar arquivos de jogo salvo usando apenas arquivos binários contendo informações ou de texto mesmo. Já em jogos que salvam em uma mídia externa (HD, Memory Card, Memory Stick) seria recomendável um arquivo protegido e não facilmente alterável, e obviamente, melhor compatível com aquela mídia.  Há também a questão visual, pois em jogos a principal característica é a interface e até o banco de dados não se safa dela.
4)   Importância Visual
Desde que se criou o sistema de salvar e manipular arquivos de jogos, até os arquivos salvos tinham uma imagem ou ícone do jogo ou personagem para que fossem facilmente identificáveis. Uma interface bem decorada e com os personagens do jogo era o meio que se manipulava os dados na época dos jogos de cartucho, onde o jogador podia escolher qual arquivo queria continuar jogando e qual queria deletar.


Figura 1. Tela de seleção de dados do jogo Sonic 3 & Knukcles


Nos consoles de vídeo games atuais, além de ter-se uma interface intuitiva como a mostrada acima para manipular o banco de dados do jogo, também se tem a necessidade de mostrar o jogador o arquivo físico do banco de dados, para que ele possa manipular, mas sem deixar de ter aquele toque de jogo. Ou seja, até o ícone do arquivo físico dos jogos são demorados e explícitos ao jogador.

Figura 2. Interface intuitiva do Memory Card do console PlayStation 2

Os arquivos salvos são explícitos ao usuário para que o mesmo possa copiar excluir e mover arquivos dentro do mesmo dispositivo ou para outro dispositivo. Cada arquivo tem o seu ícone trabalhado de maneira artística e para que o usuário identifique mais rápido de qual jogo aquele arquivo pertence.
Em uma aplicação empresarial, esse tipo de coisa não acontece, pois o arquivo físico onde são salvos os dados é escondido e oculto do usuário. Também não possui trabalho de arte. Isso acontece mais por motivos de segurança, para que nenhuma pessoa mal intencionada roube informações importantes da empresa ou do usuário que tem essa aplicação. No caso de jogos, não se tem esse cuidado com a segurança do banco de dados, pois mesmo que os dados do banco de dados fossem alterados, de nada prejudicaria quem estivesse usando aquele software. Na pior das hipóteses, o arquivo seria corrompido e o jogador teria que começar a jogar tudo de novo o seu jogo. Devido á isso, as empresas de jogos ressaltam a importância de não colocar dados pessoais em jogos e consoles (com exceção em jogos online onde se é necessário criar uma conta para poder jogar, mas a conta em si não aparece no jogo).

5)   Impelentação
Em jogos para computador, feitos com engines mais simples, é sempre usado ferramentas de bancos de dados usadas em outras aplicações comuns onde os dados são organizados em tabelas. Mas aqueles jogos onde não se usa um banco de dados convencional e sim arquivos de texto, e outros métodos de armazenamento o código geralmente é escrito no próprio jogo. Para se definir o que é salvo no jogo, é recomendado criar uma classe contendo os dados que serão mantidos. Veja o seguinte exemplo:
public struct SaveGameData
{
    public string PlayerName;
    public Vector2 AvatarPosition;
    public int Level;
    public int Score;
}
Como visto, basta colocar as variáveis das quais deseja salvar. 
Ou seja, no caso deste jogo: O nome do jogador, posição do avatar, fase e pontuação.
Quanto maior sua classe, maior será o seu arquivo. Então, é uma boa ideia manter uma classe pequena. Também não se devem referenciar outros objetos a não ser que você queira serializar o mesmo. Na linguagem C# é feita uma estrutura de dados onde se encontra os dados importantes para aquele jogo.  Esses dados serão persistidos em arquivos físicos, e carregados ao jogo de novo, quando o jogador desejar. Basicamente é uma persistência de objetos onde não é necessário fazer relacionamento de tabelas, mas isso se depende da aplicação e tipo de jogo onde essa abordagem é usada. 
 
Referências

MICROSOFT; MICROSOFT. Saving Data to a Save Game File. Saving Data To A Save Game File, Microsoft, n. , p.01-01, 25 abr. 2012. Disponível em: <http://msdn.microsoft.com/en-us/library/bb203924.aspx>. Acesso em: 25 abr. 2012.

HUTSCAL, Luke. Designing your game’s database. Saving Data To A Save Game File, Eua, n. , p.01-01, 25 abr. 2012. Disponível em: <http://buildingbrowsergames.com/2008/04/15/designing-your-database/>. Acesso em: 25 abr. 2012.
SONY. PlayStation Blog. Playstation, América do Norte, n. , p.01-01, 25 abr. 2012. Disponível em: <http://us.playstation.com/>. Acesso em: 25 abr. 2012.




Baixe este artigo em PDF

quarta-feira, 18 de abril de 2012

Como Montar Seu Banco de Dados em jogos!

Primeiro de tudo, é recomendável você criar primeiro seu banco de dados antes de criar o jogo, afinal pode-se ter a melhor lógica e não ter com oque trabalhar com ela, acabar tornando-a inútil.

A muitas maneira de fazer o deseing de bancos de dados, e vou descrever uma bem breve.

Este modelo frisa em ter quanto menos replicação de dados melhor.

Por que você não quer replicação de dados, simples cada vez que dados desnecessários são acumulados eles pesam no seu banco de dados. E se muitos jogadores acessarem seu jogo (em caso de onlines) por dia, seu banco de dados vai ficar muito grande e sem como dar manutenção.

Isso irá acontecer quando você tem replicação de dados:


1000 players x 5 Kb = 5000 Kb (Quase 5Mb)
100000 players x 5 Kb = 500000 Kb (Quase 500Mb!)


Certamente, só cinco megas de dados replicados são facilmente manuseáveis, mas 500 megas ai já não é!

É por isso que você precisa desenhar seu banco de dados apropriadamente!
Sem contar que se deve evitar o máximo disso, por que quanto menos replicação de dados existir, menos problemas será encontrado. Também, quando for atualizar alguma coisa, será muito mais fácil atualizar coisas em um só lugar do que em múltiplos lugares e também é certo que ao dado ser acessado, ele será atualizado.

O esquema a seguir é melhor apropriado para jogos de navegador:
CREATE TABLE users (
 id int NOT NULL AUTO_INCREMENT,
 username varchar(250),
 password varchar(50),
 PRIMARY KEY(id)
);

Em um jogo de navegador, ou de MMORPG  um jogador deve ter nome de usuário e senha e um ID único. Em alguns casos, o ID pode ser u nome de usuário, mas isso fará com que seja necessário verificar constantemente se aquele nome se encontra disponível.

Esse ID será a chave primária do do jogador, ou seja, nenhum jogador terá o mesmo ID sendo ele unicamente identificável no banco de dados. O Comando de auto_incremento, significa que ele será incrementado sozinho toda a vez que um jogador for salvo dando a certeza que não terá dois jogadores com o mesmo ID.


A maioria dos jogos, o jogador tem um preventório de items,  então a seguir será demonstrado como se cria uma segunda tabela que será a de itens e ao menos tempo ligá-la á tabela do jogador:

CREATE TABLE items (
 id int NOT NULL AUTO_INCREMENT,
 name varchar(200),
 description text,
 PRIMARY KEY(id)
);
CREATE TABLE user_inventory (
 id int NOT NULL AUTO_INCREMENT,
 item_id int,
 user_id int,
 quantity int,
 PRIMARY KEY(id)
);

Então, para melhorar ilustrar, suponha-se que o jogador pegue um item : " A Espada Vorpal de Existência Hipotética". Para adicioná-la ao inventário do jogador, deve-se descobrir qual ID a Espada Vorpal  possui e adicioná-la á coluna da tabela vazia ou atualizar uma existente. 
Também por atribui-la a um ID único  poderá atualize-la uma vez só, caso haja algum bug. É possível até renome-la para outro nome, como "Espada Nefasta de Existência Hipotética" ou algo assim. 
Quando o item está armazenado em uma única tabela , fica fácil editá-lo. Mas já pensou se a Espada Vorpal estivesse armazenada  na tabela de itens do jogador? E fosse necessário mudar o nome dela?
Seria necessário atualizar a o item de cada jogador que tivesse a Espada Vorpal.
Obviamente, fazendo um modelo de relacionamento bem feito, economiza-se tempo ao se atualizar dados na tabela. Será necessário fazer apenas uma alteração ao invés de atualizar os campos de cada jogador. 




segunda-feira, 9 de abril de 2012

Criando Arquivos SAVE de jogos, usando C#


Como definir um dado de salvar o jogo?

public struct SaveGameData
{
    public string PlayerName;
    public Vector2 AvatarPosition;
    public int Level;
    public int Score;
}

Como visto, basta colocar as variáveis das quais deseja salvar. 
Ou seja, no caso deste jogo: O nome do jogador, posição do avatar, fase e pontuação.

Quanto maior sua classe , maior será o seu arquivo. Então, é uma boa ideia manter uma classe pequena. Também não se deve referenciar outros objetos a não ser que você queira serializar o mesmo.

Como serializar dados para um aquivo de salvar jogo

_______________________________________________________________________________

Criar um Recipiente de armazenamento para acessar um aparelho especifico.

// Abrir Recipiente de Armazenamento .
IAsyncResult result =
    device.BeginOpenContainer("StorageDemo", null, null);

// Espere pelo WaitHandle ficar assinável.
result.AsyncWaitHandle.WaitOne();

StorageContainer container = device.EndOpenContainer(result);

// Feche o WaitHandle.
result.AsyncWaitHandle.Close();
______________________________________________________________________________________________
Chame o método FileExists para determinar se um arquivo de jogo salvo anterior existe , se existir chame DeleteFile para deletá-lo.

string filename = "savegame.sav";

// Check to see whether the save exists.
if (container.FileExists(filename))
   // Delete it so that we can create one fresh.
   container.DeleteFile(filename);
____________________________________________________________________________________________



Fonte