Clon de Minecraft para Windows, Mac OS X y Linux. Sólo unos pocos miles de líneas de C utilizando OpenGL moderno (sombreadores). Se incluye soporte multijugador en línea mediante un servidor basado en Python.
http://www.michaelfogleman.com/craft/
Los binarios de Mac y Windows están disponibles en el sitio web.
http://www.michaelfogleman.com/craft/
Consulte a continuación para ejecutar desde la fuente.
Descargue e instale CMake si aún no lo tiene. Puede utilizar Homebrew para simplificar la instalación:
brew install cmake
sudo apt-get install cmake libglew-dev xorg-dev libcurl4-openssl-dev
sudo apt-get build-dep glfw
Descargue e instale CMake y MinGW. Agregue C:MinGWbin
a su PATH
.
Descargue e instale cURL para que CURL/lib y CURL/include estén en su directorio de Archivos de programa.
Utilice los siguientes comandos en lugar de los que se describen en la siguiente sección.
cmake -G "MinGW Makefiles"
mingw32-make
Una vez que tenga las dependencias (ver arriba), ejecute los siguientes comandos en su terminal.
git clone https://github.com/fogleman/Craft.git
cd Craft
cmake .
make
./craft
Después de muchos años, craft.michaelfogleman.com ha sido eliminado. Consulte la sección Servidor para obtener información sobre el autohospedaje.
Puede conectarse a un servidor con argumentos de línea de comando...
./craft [HOST [PORT]]
O bien, con el comando "/online" en el propio juego.
/online [HOST [PORT]]
Puedes ejecutar tu propio servidor o conectarte al mío. El servidor está escrito en Python pero requiere una DLL compilada para que pueda realizar la generación del terreno tal como el 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]
Teletransportarse a otro usuario. Si NOMBRE no se especifica, se elige un usuario aleatorio.
/list
Muestra una lista de usuarios conectados.
/login NAME
Cambie a otro nombre de usuario registrado. Se volverá a contactar con el servidor de inicio de sesión. El nombre de usuario distingue entre mayúsculas y minúsculas.
/logout
Anule la autenticación y conviértase en usuario invitado. Los inicios de sesión automáticos no volverán a ocurrir hasta que se vuelva a emitir el comando /login.
/offline [FILE]
Cambie al modo fuera de línea. ARCHIVO especifica el archivo guardado que se utilizará y el valor predeterminado es "craft".
/online HOST [PORT]
Conéctese al servidor especificado.
/pq P Q
Teletransportarse al fragmento especificado.
/spawn
Teletransportarse de regreso al punto de generación.
El terreno se genera utilizando ruido Simplex, una función de ruido determinista basada en la posición. Entonces el mundo siempre se generará de la misma manera en un lugar determinado.
El mundo está dividido en bloques de 32x32 en el plano XZ (Y está arriba). Esto permite que el mundo sea "infinito" (la precisión del punto flotante es actualmente un problema en valores grandes de X o Z) y también facilita la gestión de los datos. Sólo es necesario consultar los fragmentos visibles desde la base de datos.
Sólo se renderizan las caras expuestas. Esta es una optimización importante ya que la gran mayoría de los bloques están completamente ocultos o solo exponen una o dos caras. Cada fragmento registra una superposición de un bloque de ancho para cada fragmento vecino, de modo que sepa qué bloques a lo largo de su perímetro están expuestos.
Sólo se renderizan fragmentos visibles. Se utiliza un enfoque ingenuo de selección de frustums para probar si un fragmento está a la vista de la cámara. Si no es así, no se representa. Esto también da como resultado una mejora de rendimiento bastante decente.
Los buffers de fragmentos se regeneran por completo cuando se cambia un bloque en ese fragmento, en lugar de intentar actualizar el VBO.
El texto se representa mediante un atlas de mapa de bits. Cada personaje se representa en dos triángulos que forman un rectángulo 2D.
Se utiliza OpenGL "moderno": no se utilizan funciones de canalización de funciones fijas obsoletas. Los objetos de búfer de vértice se utilizan para coordenadas de posición, normales y de textura. Para el renderizado se utilizan sombreadores de vértices y fragmentos. Las funciones de manipulación de matrices están en Matrix.c para matrices de traducción, rotación, perspectiva, ortográficas, etc. Los modelos 3D se componen de primitivos muy simples, en su mayoría cubos y rectángulos. Estos modelos se generan en código en cube.c.
La transparencia en bloques de vidrio y plantas (las plantas no adoptan la forma rectangular completa de sus primitivos triangulares) se implementa descartando píxeles de color magenta en el sombreador de fragmentos.
Los cambios de usuario en el mundo se almacenan en una base de datos sqlite. Solo se almacena el delta, por lo que se genera el mundo predeterminado y luego los cambios del usuario se aplican en la parte superior al cargar.
La tabla principal de la base de datos se denomina "bloque" y tiene las columnas p, q, x, y, z, w. (p, q) identifica el fragmento, (x, y, z) identifica la posición del bloque y (w) identifica el tipo de bloque. 0 representa un bloque vacío (aire).
En el juego, los fragmentos almacenan sus bloques en un mapa hash. Una clave (x, y, z) se asigna a un valor (w).
La posición y de los bloques está limitada a 0 <= y < 256. El límite superior es principalmente una limitación artificial para evitar que los usuarios construyan estructuras innecesariamente altas. Los usuarios no pueden destruir bloques en y = 0 para evitar caer debajo del mundo.
El modo multijugador se implementa utilizando enchufes antiguos. Se utiliza un protocolo simple, ASCII, basado en líneas. Cada línea se compone de un código de comando y cero o más argumentos separados por comas. El cliente solicita fragmentos del servidor con un comando simple: C,p,q,key. "C" significa "fragmento" y (p, q) identifica el fragmento. La clave se utiliza para el almacenamiento en caché: el servidor solo enviará actualizaciones en bloque que se hayan realizado desde la última vez que el cliente solicitó ese fragmento. Las actualizaciones de bloque (en tiempo real o como parte de una solicitud fragmentada) se envían al cliente en el formato: B,p,q,x,y,z,w. Después de enviar todos los bloques para un fragmento solicitado, el servidor enviará una clave de caché actualizada en el formato: K,p,q,key. El cliente almacenará esta clave y la usará la próxima vez que necesite solicitar ese fragmento. Las posiciones de los jugadores se envían en el formato: P,pid,x,y,z,rx,ry. El pid es el ID del jugador y los valores rx y ry indican la rotación del jugador en dos ejes diferentes. El cliente interpola las posiciones de los jugadores de las dos últimas actualizaciones de posiciones para una animación más fluida. El cliente envía su posición al servidor como máximo cada 0,1 segundos (menos si no se mueve).
El almacenamiento en caché del lado del cliente en la base de datos sqlite puede consumir mucho rendimiento cuando se conecta a un servidor por primera vez. Por esta razón, las escrituras de sqlite se realizan en un hilo en segundo plano. Todas las escrituras ocurren en una transacción para desempeño. La transacción se confirma cada 5 segundos en lugar de una cantidad lógica de trabajo completado. Un búfer circular/anillo se utiliza como cola para los datos que se escribirán en la base de datos.
En el modo multijugador, los jugadores pueden observarse unos a otros en la vista principal o en una vista de imagen en imagen. La implementación de PnP fue sorprendentemente simple: simplemente cambie la ventana gráfica y renderice la escena nuevamente desde el punto de vista del otro jugador.
La prueba de impacto (a qué bloque apunta el usuario) se implementa escaneando un rayo desde la posición del jugador hacia afuera, siguiendo su vector de visión. Este no es un método preciso, por lo que la velocidad de paso se puede reducir para que sea más precisa.
La prueba de colisión simplemente ajusta la posición del jugador para permanecer a cierta distancia de cualquier bloque adyacente que sea un obstáculo. (Las nubes y las plantas no están marcadas como obstáculos, por lo que debes atravesarlas).
Para el cielo se utiliza una cúpula celeste texturizada. La coordenada X de la textura representa la hora del día. Los valores de Y se asignan desde la parte inferior de la esfera del cielo hasta la parte superior de la esfera del cielo. El jugador siempre está en el centro de la esfera. Los sombreadores de fragmentos para los bloques también toman muestras de la textura del cielo para determinar el color de niebla apropiado para mezclar según la posición del bloque en relación con el cielo de fondo.
La oclusión ambiental se implementa como se describe en esta página:
http://0fps.wordpress.com/2013/07/03/ambient-occlusion-for-minecraft-like-worlds/