← BibliotecaConceptomormon/block-world
Mundo de bloques
Clonar
fogon pieces add block-worldgit clone https://git.fogon.gg/mormon/block-world.gitfogon new block-world --from block-worldMundo de bloques
Una forma de dibujar el mundo: todo son cubos de un metro, con caras de 16×16 píxeles. Acá no hay ni un archivo de imagen ni un modelo: la isla sale de una semilla (la misma semilla da el mismo mundo en todas las pantallas), las texturas se pintan píxel por píxel con código y la luz se calcula al armar la malla.

En la demo: se camina en primera persona por una isla de 256 × 256 bloques con pradera, bosque, desierto, nieve, cerros, lagos y cuevas. Clic rompe el bloque que mirás, clic derecho pone el que tenés elegido (1–9 o la rueda), espacio salta, shift corre y N pasa del día a la noche. Otra semilla en el link (?seed=7) es otra isla. En el teléfono: el pulgar izquierdo camina, el derecho mira, y un toque rompe o pone.
Es solo la página. No hay sala, ni red, ni nada guardado: todo pasa en el navegador de quien juega y al recargar la isla vuelve a estar como nueva. Es una base para empezar un juego propio, no un juego terminado.
Qué trae
client/blocks es lo que se lleva. Los cuatro primeros archivos no dependen de ningún motor.
| Archivo | Qué hace |
|---|---|
world.ts | El mundo: qué bloque hay en cada celda (World, get, set), la tabla de bloques (BLOCKS, B.stone…) y raycast, que dice qué bloque se está mirando y por qué cara. |
terrain.ts | generate(world): llena el mundo desde su semilla (isla, cerros, cuevas, cuatro tipos de suelo, árboles, flores y una cabaña donde aparece la gente). |
mesh.ts | meshChunk(world, cx, cz): un pedazo de 16 × 16 columnas como triángulos, solo con las caras que se ven y la luz de cada esquina ya calculada. |
walk.ts | Walker: alguien que camina, salta y nada, y al que los bloques sólidos frenan. |
tiles.ts | Las 28 texturas, pintadas por código (paintTiles), y tileCanvas para mostrar una en un botón. |
noise.ts | El ruido con semilla que usan el terreno y las nubes. |
three.ts | Todo eso en three.js: BlockView (las mallas, que se rehacen solas cuando cambia un bloque), Sky (día y noche, sol, luna, estrellas y nubes) y makeHighlight (el marco del bloque apuntado). |
Lo demás es la demo y sirve de ejemplo: client/main.ts tiene el teclado, el mouse, los controles táctiles, la barra de bloques, romper y poner, y los dos sonidos (hechos con código, sin archivos).
Cómo se usa en un juego
import * as THREE from "three";
import { B, World, raycast } from "./blocks/world";
import { generate } from "./blocks/terrain";
import { BlockView, Sky } from "./blocks/three";
import { Walker } from "./blocks/walk";
const world = new World({ seed: 3 }); // 256 × 256 de lado y 64 de alto, si no se dice otra cosa
generate(world); // la isla de esa semilla
const view = new BlockView(world);
const sky = new Sky(world.seed);
scene.add(sky.object, view.object);
const me = new Walker();
Object.assign(me, world.spawn); // frente a la cabaña
camera.rotation.order = "YXZ";
// En cada cuadro (dt en segundos; hour: 0 amanece, 0.25 mediodía, 0.5 atardece, 0.75 medianoche):
me.step(world, { forward: 1, right: 0, jump: false, sprint: false }, dt);
camera.position.set(me.x, me.y + me.eye, me.z);
camera.rotation.set(me.pitch, me.yaw, 0);
sky.update(hour, camera, dt, world.size / 2);
view.setLight(sky.light, sky.fog);
view.update(me.x, me.z); // arma lo que falta o cambió, lo más cercano primero
// Romper lo que se mira y poner un bloque contra esa cara:
const hit = raycast(world, camera.position.x, camera.position.y, camera.position.z, dir.x, dir.y, dir.z, 6);
if (hit) {
world.set(hit.x, hit.y, hit.z, B.air);
world.set(hit.x + hit.nx, hit.y + hit.ny, hit.z + hit.nz, B.planks);
}
world.set avisa solo a la vista: el pedazo que cambió se vuelve a armar en el cuadro siguiente.
Un mapa propio. generate es una forma de llenar el mundo, no la única. Para un mapa hecho a mano (una arena, un laberinto, un pueblo) se escribe celda por celda con world.fill(x, y, z, B.stone) y al final se llama world.settle(). world.spawn dice dónde aparece la gente.
Para hacerlo entre varios. Esta base no trae esa parte, pero queda a mano: el terreno no hace falta mandarlo (cada pantalla lo genera con la misma semilla), así que la sala solo tendría que decir la semilla, quién está dónde y qué celdas cambiaron. world.set es el único lugar por donde pasa un cambio.
Otro bloque. Se pinta su cara en tiles.ts (un nombre en NAMES y una función que da el color de cada píxel) y se agrega en world.ts (su clave en KEYS y su ficha en TYPES). Agregalos al final de la lista: el número de cada bloque es su lugar en ella, y lo ya guardado usa esos números.
Con otro motor. meshChunk devuelve arreglos comunes: posiciones, uvs (u, v y el número de textura) y light (luz del día y luz de farol, de 0 a 1 cada una). El material hace textura × max(color del día × luz del día, color del farol × luz de farol); el agua va aparte, transparente y sin escribir profundidad.
Por qué se ve así
- Las sombras son suaves sin ninguna lámpara: cada esquina de cada cara se oscurece según cuántos bloques la rodean, y según cuánto cielo ve (pleno al aire libre, menos bajo un árbol o un techo, casi nada en una cueva).
- Los faroles alumbran lo que tienen cerca con una luz cálida que no depende de la hora: de noche son lo único que se ve bien.
- Las texturas van en capas, una por dibujo: de cerca se ven los píxeles nítidos y de lejos se suavizan sin mezclarse con la de al lado.
Límites
- El mundo tiene un tamaño fijo y se genera entero al entrar (unos 100 ms para 256 × 256 × 72; la isla de la demo son unos 450 000 triángulos). No es infinito: pasando el borde hay mar.
- La luz no se propaga bloque a bloque: un farol alumbra a través de una pared, y una cueva es oscura por lo profunda que está, tenga o no una boca cerca.
- El agua no corre y la arena no cae: si se rompe la orilla de un lago, el agua se queda donde estaba.
- No guarda nada ni es para varios: lo que se construye se pierde al recargar.
server/room.tsyshared.tsestán vacíos, solo porque todo proyecto de Fogón los lleva. - Necesita WebGL 2 (cualquier navegador actual). three.js es una dependencia de npm: el juego que lo use se arma con la CLI de Fogón (
fogon dev,fogon deploy).
De dónde sale
Escrito para la biblioteca de Fogón. Código y texturas MIT.
Elegí un archivo.
| Versión | Cuándo | Peso | Commit |
|---|---|---|---|
| v1 en la demo | 12 de nov de 2026 | 997 KB | 06df759 |
Todavía nadie publicó una versión hecha a partir de esta pieza.
Hacé tu versión de
Copiá este pedido y pegáselo a tu IA (Claude, ChatGPT…): arma tu versión con el código de este juego y la publica como un juego tuyo.