Sobre
Na verdade, essas são duas perguntas em uma. Antes de tudo, estou procurando uma maneira de armazenar com eficiência grandes quantidades de dados do bloco. O outro aspecto lida com a consulta do conjunto de dados e a exibição de blocos. Deixe-me dar-lhe alguns antecedentes primeiro.
Estamos criando um jogo de tycoon multiplayer baseado em navegador usando a biblioteca CraftyJS para renderizá-lo no Canvas. No fundo da GUI, estamos rodando o Yii Framework em PHP e tudo se conecta a um gerador de mapas aleatórios e mecanismo de jogo em Python.
É assim que o primeiro mapa aproximado é exibido : http://i.imgur.com/khAXtl.png
Armazenando os dados do mapa
O mundo do jogo é gerado aleatoriamente cada vez que o jogo é iniciado. O tamanho é de 100x100 peças hexagonais para cada jogador. Isso significa que, para um jogo com três jogadores, existem 90.000 peças criadas. Atualmente, apenas crio uma matriz JavaScript a partir da qual renderizo o mapa.
Isso funciona bem para renderização, mas para qualquer tipo de interação com o mapa, precisamos armazenar qual jogador possui o ladrilho, que tipo de estrutura é construída sobre ele, qual é o preço atual e assim por diante. No começo, pelo menos para o protótipo, queríamos usar o MySQL, mas após alguns testes, não é exatamente tão rápido quanto eu gostaria. Talvez um armazenamento de objetos como o MongoDB seja mais adequado para armazenar dados de bloco em vez de uma tabela SQL. Ou talvez algo mais?
Exibindo o mapa
Outro problema que vejo está se movendo pelo mapa. Atualmente, estou criando entidades Crafty para cada bloco, mesmo que não esteja na janela de exibição. Isso é lento, porque, embora o Crafty renderize apenas os da janela de exibição, ele armazena e possivelmente itera através de todos os blocos em cada evento de renderização. O que eu tenho atualmente é um mapa gerado desenhado que é muito lento para carregar e gagueja quando você se move, agora eu gostaria de torná-lo jogável.
Minha primeira ideia foi carregar o subconjunto de blocos exibido na janela de exibição. Mas quando um jogador moveria a janela de visualização para uma área em branco, eu precisaria consultar o servidor e aguardar a resposta, somente então o mapa poderá ser renderizado. Isso seria bom em um aplicativo nativo, mas é lento em um jogo na web.
A maneira de obter um bom desempenho no mapa pode ser pré-carregar um subconjunto maior de blocos em uma matriz javascript e usá-lo como cache. O jogador teria algumas telas "armazenadas em cache" e, quando ele move a janela de visualização, eu carregava mais blocos no "cache" do JS.
Estou indo na direção certa? Gostaria muito de obter mais informações de alguém que fez algo semelhante. Eu sou novo no desenvolvimento de jogos, mas tenho passado por muitas fontes nas últimas duas semanas.
fonte
Respostas:
Jogabilidade
Antes de mais nada, gostaria de perguntar: você realmente precisa de 10000 peças por jogador? Embora eu não saiba que tipo de jogo você está criando, geralmente é verdade que mapas grandes produzem jogos longos. O maior mapa da Civilização 5 é 10240 blocos, e isso apenas funciona porque você não precisa jogar em mais do que uma fração dele.
Banco de dados
Você não deve tentar executar um jogo como esse em um banco de dados, é necessário manter os dados na memória do aplicativo. Você pode usar um banco de dados para fazer backup do jogo. Para um backup completo, salve uma serialização dos dados do jogo e, em seguida, você poderá incrementá-lo salvando as ordens dadas e, em seguida, execute-as novamente se o backup precisar ser usado.
Armazenamento JavaScript
Quanto ao cliente, eu diria que é melhor você manter o mapa inteiro carregado, pelo menos se você ficar com os gazilhões de blocos, ter tudo isso em uma bela árvore de objetos pode ser um pouco demais, então você provavelmente deve manter os dados em um formato codificado "semi-binário". As strings funcionam excelente para esse tipo de coisa; alternativamente, você pode armazenar com segurança números inteiros não assinados até 53 bits em um float de 64 bits, encher muitos deles em uma matriz e acho que você verá uma pegada de memória bastante modesta.
Visualização JavaScript
Embora eu não diga que você não deve necessariamente usar canvas, na verdade você não precisa disso para coisas como esta. Configure tudo como um monte de elementos img e altere a propriedade src para exibir diferentes partes do mapa.
Dica profissional
A propósito, às vezes é mais fácil compartilhar a semente usada para gerá-la do que compartilhar o mapa inteiro.
fonte
O MySQL não é lento. Provavelmente você está executando consultas ingênuas ou possui índices abaixo do ideal. Abordagens NoSQL como o MongoDB podem ser mais rápidas, talvez não. Seu padrão de acesso e escolha de consulta é o que realmente importa aqui. É possível dar conselhos sobre como melhorar o desempenho, mas não sem ver o que você já está fazendo.
Sim, claro. Não há muito a acrescentar aqui - o cliente solicita blocos do servidor, portanto, você só precisa garantir que os solicitados cubram uma área maior que a tela.
Termo aditivo:
Se você é competente com o Python, aconselho que você evite o intermediário do PHP. Se você rodar o jogo como um processo Python, poderá manter os dados do bloco na memória com muito mais facilidade e reduzir significativamente os acessos ao MySQL. Ajuda que o Python também seja uma linguagem muito mais saudável do que o PHP.
fonte