Clone do Minecraft para Windows, Mac OS X e Linux. Apenas alguns milhares de linhas de C usando OpenGL moderno (shaders). O suporte multijogador online está incluído usando um servidor baseado em Python.
http://www.michaelfogleman.com/craft/
Binários para Mac e Windows estão disponíveis no site.
http://www.michaelfogleman.com/craft/
Veja abaixo como executar a partir da fonte.
Baixe e instale o CMake se ainda não o tiver feito. Você pode usar o Homebrew para simplificar a instalação:
brew install cmake
sudo apt-get install cmake libglew-dev xorg-dev libcurl4-openssl-dev
sudo apt-get build-dep glfw
Baixe e instale CMake e MinGW. Adicione C:MinGWbin
ao seu PATH
.
Baixe e instale cURL para que CURL/lib e CURL/include estejam em seu diretório Arquivos de Programas.
Use os seguintes comandos no lugar daqueles descritos na próxima seção.
cmake -G "MinGW Makefiles"
mingw32-make
Depois de ter as dependências (veja acima), execute os seguintes comandos em seu terminal.
git clone https://github.com/fogleman/Craft.git
cd Craft
cmake .
make
./craft
Depois de muitos anos, craft.michaelfogleman.com foi removido. Consulte a seção Servidor para obter informações sobre auto-hospedagem.
Você pode se conectar a um servidor com argumentos de linha de comando...
./craft [HOST [PORT]]
Ou, com o comando "/online" do próprio jogo.
/online [HOST [PORT]]
Você pode executar seu próprio servidor ou conectar-se ao meu. O servidor é escrito em Python, mas requer uma DLL compilada para que possa realizar a geração do terreno assim como o cliente.
gcc -std=c99 -O3 -fPIC -shared -o world -I src -I deps/noise deps/noise/noise.c src/world.c
python server.py [HOST [PORT]]
/goto [NAME]
Teleporte para outro usuário. Se NAME não for especificado, um usuário aleatório será escolhido.
/list
Exibir uma lista de usuários conectados.
/login NAME
Mude para outro nome de usuário registrado. O servidor de login será contatado novamente. O nome de usuário diferencia maiúsculas de minúsculas.
/logout
Cancele a autenticação e torne-se um usuário convidado. Logins automáticos não ocorrerão novamente até que o comando /login seja emitido novamente.
/offline [FILE]
Mude para o modo off-line. FILE especifica o arquivo salvo a ser usado e o padrão é "craft".
/online HOST [PORT]
Conecte-se ao servidor especificado.
/pq P Q
Teletransporte-se para o pedaço especificado.
/spawn
Teleporte de volta para o ponto de desova.
O terreno é gerado usando ruído Simplex - uma função de ruído determinística semeada com base na posição. Assim o mundo será sempre gerado da mesma forma em um determinado local.
O mundo está dividido em blocos de 32x32 no plano XZ (Y está para cima). Isso permite que o mundo seja “infinito” (a precisão do ponto flutuante é atualmente um problema em valores grandes de X ou Z) e também facilita o gerenciamento dos dados. Apenas pedaços visíveis precisam ser consultados no banco de dados.
Somente faces expostas são renderizadas. Esta é uma otimização importante, pois a grande maioria dos blocos está completamente oculta ou expõe apenas uma ou duas faces. Cada pedaço registra uma sobreposição de largura de um bloco para cada pedaço vizinho, para saber quais blocos ao longo de seu perímetro estão expostos.
Apenas pedaços visíveis são renderizados. Uma abordagem ingênua de seleção de tronco é usada para testar se um pedaço está no campo de visão da câmera. Se não estiver, não será renderizado. Isso também resulta em uma melhoria de desempenho bastante decente.
Os buffers de pedaços são completamente regenerados quando um bloco é alterado naquele pedaço, em vez de tentar atualizar o VBO.
O texto é renderizado usando um atlas de bitmap. Cada personagem é renderizado em dois triângulos formando um retângulo 2D.
OpenGL “moderno” é usado - nenhuma função de pipeline obsoleta e de função fixa é usada. Objetos de buffer de vértice são usados para coordenadas de posição, normal e textura. Shaders de vértices e fragmentos são usados para renderização. As funções de manipulação de matrizes estão em matriz.c para matrizes de translação, rotação, perspectiva, ortográfica, etc. Os modelos 3D são compostos de primitivas muito simples – principalmente cubos e retângulos. Esses modelos são gerados em código em cube.c.
A transparência em blocos de vidro e plantas (as plantas não assumem a forma retangular completa de seus triângulos primitivos) é implementada descartando pixels de cor magenta no sombreador de fragmento.
As alterações do usuário no mundo são armazenadas em um banco de dados sqlite. Apenas o delta é armazenado, então o mundo padrão é gerado e as alterações do usuário são aplicadas na parte superior durante o carregamento.
A tabela principal do banco de dados é denominada “bloco” e possui colunas p, q, x, y, z, w. (p, q) identifica o pedaço, (x, y, z) identifica a posição do bloco e (w) identifica o tipo de bloco. 0 representa um bloco vazio (ar).
No jogo, os pedaços armazenam seus blocos em um mapa hash. Uma chave (x, y, z) é mapeada para um valor (w).
A posição y dos blocos é limitada a 0 <= y < 256. O limite superior é principalmente uma limitação artificial para evitar que os usuários construam estruturas desnecessariamente altas. Os usuários não estão autorizados a destruir blocos em y = 0 para evitar cair no mundo.
O modo multijogador é implementado usando soquetes antigos. É usado um protocolo simples, ASCII, baseado em linha. Cada linha é composta por um código de comando e zero ou mais argumentos separados por vírgula. O cliente solicita pedaços do servidor com um comando simples: C,p,q,key. “C” significa “Pedaço” e (p, q) identifica o pedaço. A chave é usada para armazenamento em cache - o servidor enviará apenas atualizações de bloco que foram executadas desde a última vez que o cliente solicitou esse pedaço. As atualizações de bloco (em tempo real ou como parte de uma solicitação de bloco) são enviadas ao cliente no formato: B,p,q,x,y,z,w. Após enviar todos os blocos de um pedaço solicitado, o servidor enviará uma chave de cache atualizada no formato: K,p,q,key. O cliente armazenará essa chave e a usará na próxima vez que precisar solicitar esse pedaço. As posições dos jogadores são enviadas no formato: P,pid,x,y,z,rx,ry. O pid é o ID do jogador e os valores rx e ry indicam a rotação do jogador em dois eixos diferentes. O cliente interpola as posições dos jogadores das duas últimas atualizações de posição para uma animação mais suave. O cliente envia sua posição ao servidor no máximo a cada 0,1 segundos (menos se não estiver em movimento).
O cache do lado do cliente para o banco de dados sqlite pode exigir muito desempenho ao se conectar a um servidor pela primeira vez. Por esse motivo, as gravações do sqlite são executadas em um thread em segundo plano. Todas as gravações ocorrem em uma transação para desempenho. A transação é confirmada a cada 5 segundos, em oposição a uma quantidade lógica de trabalho concluído. Um buffer circular/circular é usado como uma fila para quais dados serão gravados no banco de dados.
No modo multijogador, os jogadores podem observar uns aos outros na visualização principal ou na visualização picture-in-picture. A implementação do PnP foi surpreendentemente simples – basta alterar a janela de visualização e renderizar a cena novamente do ponto de vista do outro jogador.
O teste de acerto (para qual bloco o usuário está apontando) é implementado escaneando um raio da posição do jogador para fora, seguindo seu vetor de visão. Este não é um método preciso, portanto a taxa de passos pode ser menor para ser mais precisa.
O teste de colisão simplesmente ajusta a posição do jogador para permanecer a uma certa distância de quaisquer blocos adjacentes que sejam obstáculos. (Nuvens e plantas não são marcadas como obstáculos, então você passa direto por elas.)
Uma cúpula texturizada é usada para o céu. A coordenada X da textura representa a hora do dia. Os valores Y são mapeados da parte inferior da esfera do céu até o topo da esfera do céu. O jogador está sempre no centro da esfera. Os shaders de fragmento dos blocos também amostram a textura do céu para determinar a cor de neblina apropriada para mesclar com base na posição do bloco em relação ao céu de apoio.
A oclusão de ambiente é implementada conforme descrito nesta página:
http://0fps.wordpress.com/2013/07/03/ambient-occlusion-for-minecraft-like-worlds/