← LibraryAssetmormon/desert-market
Mercado del desierto
Clone
fogon pieces add desert-marketgit clone https://git.fogon.gg/mormon/desert-market.gitfogon new desert-market --from desert-markethttps://fogon.gg/piece/50/mercado-del-desiertoMercado del desierto
Un pueblo de mercado en el desierto, hecho entero por código con three.js: casas de revoque con puertas en arco, postigos, cúpulas y torres, una muralla con almenas, arcos de entrada, toldos sobre las calles y todo lo que hay en un mercado. No trae ningún archivo de imagen ni de modelo: las texturas se pintan solas en un canvas al cargar y las formas son cajas, perfiles torneados y planos. Cada cosa se construye suelta, con su tamaño para las colisiones, o el pueblo completo de una vez.

En la demo: el pueblo visto desde arriba, girando despacio. Arrastrá para mirar, la rueda (o dos dedos) acerca, WASD mueve el punto que se mira. La pestaña Las piezas muestra cada cosa por separado: tocá un nombre para verla sola, con la línea de código que la hace. Nada pasa por una sala: es solo la página.

Qué trae
Dos carpetas, y las dos se llevan:
| Archivo | Qué hay |
|---|---|
shared/market/layout.ts | El pueblo como números, sin three.js ni navegador (lo puede leer una sala). PROP_SIZE: la caja que ocupa cada objeto. BLOCKS, LINTELS, PROPS, PAVED, AWNINGS: qué hay y dónde. townBoxes(): todo lo sólido como cajas [minX, minY, minZ, maxX, maxY, maxZ]. townMap(): el pueblo como mapa para un juego de dos bandos (el borde, las cajas, por dónde entra cada bando y el medio). |
client/market/textures.ts | Las texturas pintadas por código (stone, plaster, cobble, sand, wood, stripes), paint y material para hacer otras, y makeMaterials(): los 27 materiales del pueblo. |
client/market/shapes.ts | createMarket(seed): los materiales y la suerte que usa todo lo demás (la misma semilla, el mismo mercado). box, lathe, ground: las formas con la textura repetida por metro. merge(group): un grupo terminado, en una malla por material. |
client/market/props.ts | buildProp(name, market): crate, crateBig, barrel, stall, cart, lowWall, well, palm, pots, sacks. PROP_NAMES, PROP_LABEL (sus nombres en español) y pot(market, scale), una vasija sola. |
client/market/buildings.ts | building(market, { width, depth, height, kind }): una casa entera (ochre, white con cúpula, rose con torre, stone). Y sus partes: door, shutterWindow, beamEnds, dome, tower, townWall, gateArch, awning. |
client/market/town.ts | buildTown(market): el pueblo completo, ya unido en una malla por material. |
client/market/sky.ts | skyDome(), dunes(market) y daylight(): el cielo, las dunas a lo lejos y la luz de un mediodía despejado, con sombras que cubren todo el pueblo. |
Lo demás es la demo: client/main.ts (la cámara, las pestañas) y una sala vacía, que Fogón pide a todo proyecto.
Cómo se usa en un juego
Todo sale parado sobre el piso en el origen de su grupo, en metros y con y hacia arriba: se pone con position y se gira con rotation.y.
Unas cosas sueltas, en una escena propia:
import { building } from "./market/buildings";
import { buildProp } from "./market/props";
import { createMarket } from "./market/shapes";
import { daylight, skyDome } from "./market/sky";
const market = createMarket(); // los materiales se pintan una sola vez
scene.add(skyDome(), daylight());
const barrel = buildProp("barrel", market);
barrel.position.set(4, 0, -2);
scene.add(barrel);
const house = building(market, { width: 10, depth: 8, height: 5, kind: "white" });
house.position.set(-8, 0, 0);
scene.add(house);
Con muchas cosas quietas, merge(group) las deja en una malla por material: un pueblo entero se dibuja en unas decenas de llamadas.
El pueblo completo:
import { createMarket } from "./market/shapes";
import { daylight, dunes, skyDome } from "./market/sky";
import { buildTown } from "./market/town";
const market = createMarket();
scene.add(skyDome(), dunes(market), daylight(), buildTown(market));
renderer.shadowMap.enabled = true;
Lo sólido. Lo que se dibuja y lo que choca salen de los mismos números. Para un objeto suelto, PROP_SIZE[name] es [ancho, alto, fondo] de su caja, centrada en su origen. Para el pueblo, townBoxes() da todas las cajas (las casas, la muralla, el dintel de cada arco desde donde empieza a ser sólido, y cada objeto):
import { townBoxes } from "../shared/market/layout";
const boxes = townBoxes(); // [minX, minY, minZ, maxX, maxY, maxZ], en metros
Con «Duelo por equipos». townMap() tiene la forma de mapa que pide ese kit de la biblioteca: sus bots caminan por las calles y las balas frenan en las paredes sin tocar nada más.
// server/room.ts
import { townMap } from "../shared/market/layout";
export default defineRoom({ ...game, ...deathmatch(townMap()) });
// client/main.ts: `buildTown(market)` en vez de `buildMap(scene, map)`, y `new Walker(townMap())`
Límites
- Un solo lugar y una sola hora: un pueblo de 82 × 62 m con su muralla, al mediodía. No hay interiores (las casas son bloques macizos: las puertas y ventanas están pintadas sobre la pared), ni noche, ni otros climas.
- Las cajas de colisión son simples. Un puesto choca hasta la altura de la mesa, no su techo; la palmera, solo el tronco; la fuente es un cuadrado. Los toldos no chocan.
- Las texturas se pintan al cargar (17 canvas de 512 px): tarda un momento en un teléfono lento, y necesita un navegador (
document).createMarket()se llama una vez y se comparte. - **
buildTowndevuelve todo unido:** sirve para un pueblo quieto. Para mover o sacar una cosa (un cajón que se rompe), armalo conBLOCKS,PROPSy los constructores, como hacebuildTown, y dejá esa cosa fuera delmerge(userData.noMerge = true). - Puertas, ventanas y colores de toldo se sortean con la semilla: otra semilla en
createMarket(seed), otro pueblo con las mismas calles. - Las sombras de
daylight()usan un mapa de 4096 px; en equipos flojos conviene bajarlo: el sol esdaylight().getObjectByName("sun"), y ahísun.shadow.mapSize.set(2048, 2048).
De dónde sale
Es el mapa Zoco del juego Contrafuego, del mismo estudio, reescrito para three.js común y partido en piezas. Licencia MIT.
Pick a file.
| Version | When | Size | Commit |
|---|---|---|---|
| v1 in the demo | Nov 12, 2026 | 1.2 MB | 853d644 |
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.