← LibraryConceptmormon/block-world
Mundo de bloques
Clone
fogon pieces add block-worldgit clone https://git.fogon.gg/mormon/block-world.gitfogon new block-world --from block-worldhttps://fogon.gg/piece/40/mundo-de-bloquesMundo 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.
Pick a file.
| Version | When | Size | Commit |
|---|---|---|---|
| v1 in the demo | Nov 12, 2026 | 997 KB | 06df759 |
Nobody has published a version made from this piece yet.
Put together the request for your agent
Pick what you want to do, copy the request and paste it into your AI (Claude, ChatGPT, Codex…). It does the rest.