Mapa y navegación de escenas
Un mapa en el que el jugador puede tocar: elige el bosque y la escena se traslada allí. La IA recibe el ambiente del bosque, la música pasa con un fundido a la pista del bosque y la siguiente respuesta de la IA describe la llegada. Se monta con una variable, lore condicional, reglas de música y botones de la interfaz del jugador, sin código.
Lo que vas a construir
- Una página de mapa con cuatro lugares: Village (pueblo), Forest (bosque), Cave (cueva) y Market (mercado)
- El lugar actual está marcado, y su botón no se puede volver a pulsar
- Al tocar un lugar, la escena se traslada: cambia la ubicación, el lore de ese lugar le llega a la IA y la frase del jugador «(Me dirijo a Forest)» entra en el chat para que la IA describa la llegada
- Cada lugar tiene su propia música, con fundido de una a otra
Cómo funciona
El jugador toca "Forest" en el mapa
→ El botón pone Location en Forest, vuelve al chat
y dice "(Me dirijo a Forest)" por el jugador
→ Ahora le llega a la IA la entrada de lore "Forest" (condición: Location es Forest); la de "Village" ya no
→ La regla de música de Forest coincide: la pista del pueblo se apaga y entra la del bosque
→ La IA responde a "(Me dirijo a Forest)" con el ambiente del bosque ya en la manoSolo cambia la variable. El lore y la música la vigilan y la siguen.
Paso a paso
Paso 1: Crea la variable
En la fila Puedes añadir, abajo en la carta, pulsa + Variable.
| Campo | Valor |
|---|---|
| Nombre | Location |
| Tipo | Texto |
| Valor inicial | Village |
| Reglas de comportamiento | Dónde está el jugador: Village, Forest, Cave o Market. Cámbiala cuando el jugador viaje claramente a uno de esos sitios. |
Deja Acceso de la IA en La IA puede leer y escribir si quieres que la IA también pueda mover al jugador en la historia («sigues el arroyo y te adentras en el bosque»). Ponlo en Solo lectura para la IA si solo debe moverlo el mapa.
Paso 2: Escribe una entrada de lore por lugar
Añade una entrada de lore para cada lugar. Luego arrastra Location sobre cada entrada, haz clic en la línea y pon la condición: Location es Village (y así con los demás). Las entradas pasan al bloque de lore condicional, y a la IA solo le llega la del lugar actual.
Village
[Ubicación: el pueblo]
El jugador está en el pueblo. Llévalo a las descripciones de las escenas:
- Un pueblecito tranquilo; callejuelas empedradas serpentean entre casas de madera
- Sale humo de las chimeneas; huele a pan recién hecho y a guiso
- Los vecinos charlan junto al pozo; en la herrería suena un martillo
- Los campos de trigo se extienden a lo lejos, meciéndose con el viento
- El ambiente es cálido y cotidianoForest
[Ubicación: el bosque]
El jugador está en el bosque. Llévalo a las descripciones de las escenas:
- Árboles viejos tapan casi todo el cielo; la luz cae a manchas sobre el musgo
- El aire es húmedo y huele a tierra, a resina y a flores silvestres
- Cantos de pájaros por todas partes y, de vez en cuando, el chasquido de una rama
- La maleza podría esconder un conejo, un ciervo o algo peor
- Cuanto más te adentras, más juntos están los árboles y menos luz hay
- El ambiente es antiguo, salvaje e inciertoCave
[Ubicación: la cueva]
El jugador está en la cueva. Llévalo a las descripciones de las escenas:
- Hongos luminosos en las paredes de roca dan una luz tenue, entre azul y verde
- Gotea agua de las estalactitas, y cada gota resuena
- El aire es frío y húmedo, y huele a mineral
- El suelo es resbaladizo e irregular; los túneles del fondo están completamente a oscuras
- A veces sube de las profundidades un gruñido sordo, o el crujido de una roca que se mueve
- El ambiente es oscuro y opresivoMarket
[Ubicación: el mercado]
El jugador está en el mercado. Llévalo a las descripciones de las escenas:
- Filas de puestos y toldos de colores, cargados de toda clase de mercancías
- Los comerciantes pregonan su género; el regateo sube y baja por todas partes
- Especias, carne asada, cuero y flores, todo a la vez
- El escaparate de una tienda de magia parpadea con una luz extraña; en una esquina, un alquimista mezcla algo
- Viajeros de todo tipo se abren paso entre la multitud
- El ambiente es ruidoso y ajetreadoPaso 3 (opcional): Música para cada lugar
Añade cuatro pistas de BGM en la página Audio (si la carta todavía no tiene audio, pulsa + Audio en la fila Puedes añadir): Village, Forest, Cave y Market, cada una con Reproducir en bucle activado y 2 segundos de Fundido de entrada (s) y Fundido de salida (s). Pon Village en la Playlist por defecto con Reproducción automática activada.
Luego, Configuración de BGM → BGM condicional → Agregar regla condicional, una vez para Forest, otra para Cave y otra para Market:
| Campo | Valor |
|---|---|
| CUANDO | Condición de variable: Location es Forest |
| Reproducir | Forest |
| Fundido de entrada (s) / Fundido de salida (s) | 3 / 3 |
| Detener BGM anterior | Activado |
| Al terminar | Volver a la playlist por defecto |
Cuando el jugador vuelve al pueblo no coincide ninguna regla, y Al terminar recupera la música del pueblo de la playlist.
Con fundidos de 3 segundos, la pista anterior y la nueva se solapan un momento, una bajando mientras la otra sube, así que la música nunca se corta al cambiar de lugar. Más en la Guía de diseño de audio.
Paso 4: Monta la página del mapa
Pulsa Interfaz en el centro de la barra superior. Añade una página con Nueva página (una Página en blanco), llámala «Mapa» y ponle un título y una frase corta como «¿Adónde vas?».
Añade un Botón por lugar (Añadir una parte → Botón). Para el botón del bosque, en Al pulsar, en orden:
- Cambiar una variable: Location, Poner en,
Forest - Ir a la página: la página de la conversación
- Decir una frase por el jugador:
(Me dirijo a Forest)
El último paso es el que hace que la IA describa la llegada en el acto: es como si el jugador lo hubiera escrito.
Para que el jugador no viaje al sitio donde ya está, dale a cada botón Cuándo mostrar → Cuando una variable cumple: Location no es Forest. Añade arriba una parte Texto que diga Estás en: {Location} (usa Insertar el valor de una variable…).
Añade a la página un Botón que solo vuelva atrás (Ir a la página → la conversación), para que el jugador pueda cerrar el mapa sin moverse. Y en la página de la conversación, añade un botón «Mapa» con Ir a la página → Mapa.
Desactiva Editar para recorrerlo sin gastar saldo.
La plantilla Mapa
Plantillas → Mapa («Toca un lugar para ir; los que aún no se han desbloqueado no se pueden tocar») monta una página de mapa ya hecha con cinco lugares de ejemplo. Añade Ubicación y Lugares abiertos, una lista a la que la IA añade lugares cuando la historia le da al jugador forma de llegar a ellos, así que los lugares empiezan bloqueados y se van abriendo según avanza la historia. Úsala si quieres que los lugares los desbloquee la historia en lugar de estar todos abiertos desde el principio.
Lugares como escenarios
Cuando un lugar crece hasta ser una parte del juego por sí mismo (con sus propios PNJ, reglas y variables, quizá con su propia IA), conviértelo en un escenario en lugar de una sola entrada de lore. Pon el Cuándo se usa del escenario en Cuando una variable cumple una condición, Location = Cave, y todo lo que hay dentro solo cuenta mientras el jugador está allí. Puedes arrastrar la variable Location sobre el escenario para configurarlo.
Paso 5: Pruébalo
Pulsa Jugar en la barra superior.
- Suena la música del pueblo. Abre Mapa: «Estás en: Village», y no hay botón de Village
- Toca Forest. Vuelves al chat, se envía «(Me dirijo a Forest)» y la IA describe el bosque
- Si añadiste música, la pista del pueblo pasa con un fundido a la del bosque
- Ve a la cueva y luego vuelve al pueblo: regresa la música del pueblo de la playlist
- Entre viaje y viaje, habla con normalidad; el mapa siempre está a un toque
Este turno, a la derecha de la prueba, muestra qué entrada de lugar recibió la IA.
Si algo falla:
| Síntoma | Causa probable | Solución |
|---|---|---|
| Tocar un lugar no hace nada | El botón no tiene pasos | Revisa Al pulsar, en orden |
| La ubicación cambia pero la IA no responde | Falta el paso Decir una frase por el jugador | Añádelo como último paso |
| La IA describe el lugar equivocado | La condición de una entrada no coincide con el valor que pone el botón | Forest tiene que escribirse igual en el botón y en la condición |
| Se mezcla el ambiente de dos lugares | Una de las entradas está en el bloque que se envía siempre | Revisa Cuándo lo ve la IA en cada entrada |
| Suenan dos pistas a la vez | Detener BGM anterior está desactivado | Actívalo en la regla de cada lugar |
| La música salta en lugar de hacer fundido | Los fundidos están en 0 | Pon Fundido de entrada (s) y Fundido de salida (s) de la regla en 2 o 3 |
Ruta con código propio: un panel de mapa con rutas de viaje
Si escribes tu propia interfaz, aquí tienes un panel de mapa debajo del último mensaje que además limita adónde puede ir el jugador desde donde está. Cambia la misma variable Location y envía la misma frase, así que el lore y la música de los Pasos 2 y 3 funcionan sin tocar nada.
Paneles → Código de frontend → abre index.tsx y sustituye el return <Chat /> que viene por defecto:
export default function MyWorld() {
const api = useYumina();
const current = String(api.variables["Location"] || "Village");
const msgs = api.messages || [];
const locations = [
{ id: "Village", icon: "🏘️", color: "#92400e", bg: "#fef3c7", border: "#f59e0b", activeBg: "#f59e0b" },
{ id: "Forest", icon: "🌲", color: "#166534", bg: "#dcfce7", border: "#22c55e", activeBg: "#22c55e" },
{ id: "Cave", icon: "🕳️", color: "#3b0764", bg: "#f3e8ff", border: "#a855f7", activeBg: "#a855f7" },
{ id: "Market", icon: "🏪", color: "#9a3412", bg: "#ffedd5", border: "#f97316", activeBg: "#f97316" },
];
// Where you can go from each place
const routes = {
Village: ["Forest", "Market"],
Forest: ["Village", "Cave"],
Cave: ["Forest"],
Market: ["Village"],
};
const reachable = routes[current] || [];
const travel = (loc) => {
api.setVariable("Location", loc.id);
api.sendMessage("(I head to the " + loc.id + ")");
};
return (
<Chat renderBubble={(msg) => {
const isLastMsg = msg.messageIndex === msgs.length - 1;
return (
<div>
<div
style={{ color: "#e2e8f0", lineHeight: 1.7 }}
dangerouslySetInnerHTML={{ __html: msg.contentHtml }}
/>
{isLastMsg && !msg.isStreaming && (
<div style={{
marginTop: "16px",
padding: "16px",
background: "rgba(15,23,42,0.6)",
borderRadius: "12px",
border: "1px solid #334155",
}}>
<div style={{ fontSize: "13px", color: "#94a3b8", marginBottom: "12px", fontWeight: "600", letterSpacing: "0.05em" }}>
WORLD MAP
</div>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "10px" }}>
{locations.map((loc) => {
const isHere = current === loc.id;
const canGo = reachable.includes(loc.id);
return (
<button
key={loc.id}
onClick={() => { if (!isHere && canGo) travel(loc); }}
style={{
padding: "14px 10px",
background: isHere ? loc.activeBg : loc.bg,
border: `2px solid ${isHere ? loc.activeBg : loc.border}`,
borderRadius: "10px",
color: isHere ? "#ffffff" : loc.color,
fontSize: "14px",
fontWeight: "700",
cursor: isHere ? "default" : canGo ? "pointer" : "not-allowed",
opacity: isHere ? 1 : canGo ? 0.85 : 0.3,
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "6px",
}}
>
<span style={{ fontSize: "28px" }}>{loc.icon}</span>
<span>{loc.id}</span>
{isHere && <span style={{ fontSize: "11px", fontWeight: "500" }}>You are here</span>}
</button>
);
})}
</div>
</div>
)}
</div>
);
}} />
);
}Qué hace el código:
api.variables["Location"]lee la variable por su nombreroutesenumera adónde lleva cada lugar. Los lugares a los que no se puede llegar desde aquí salen apagados y no se pueden tocartravel()cambia Location y luegoapi.sendMessage(...)envía la frase del viaje como si la dijera el jugador, así que la IA responde con el lore del lugar nuevo ya en su prompt!msg.isStreamingoculta el mapa mientras la IA sigue escribiendo, para que el jugador no pueda viajar a mitad de una respuestagridTemplateColumns: "1fr 1fr"coloca los cuatro lugares de dos en dos; usa"1fr 1fr 1fr"para tres columnas
El estado que aparece junto al archivo en Paneles → Código de frontend debería ser un OK verde.
¿No quieres escribir el código tú?
Pulsa Asistente IA arriba a la derecha del lienzo y describe el mapa que quieres.
Añadir un lugar
- Añade una entrada de lore «Harbor» con la condición Location es
Harbor - Si quieres, añade una pista para el puerto y una regla de BGM condicional para ella
- Añade un botón Harbor en la página del mapa (o una línea en el array
locationsy enroutes) - Añade Harbor a las Reglas de comportamiento de Location para que la IA sepa que existe
No hay que cambiar nada de lo que ya está.
Referencia rápida
| Lo que quieres | Cómo hacerlo |
|---|---|
| Saber dónde está el jugador | Una variable de Texto, Location |
| Darle a la IA el ambiente del lugar actual | Una entrada de lore por lugar, con una condición sobre Location |
| Mover al jugador desde un botón | Pasos: Cambiar una variable, Ir a la página, Decir una frase por el jugador |
| Que la IA describa la llegada en el acto | Decir una frase por el jugador (o api.sendMessage() en código) |
| Ocultar el botón del sitio donde está | Cuándo mostrar → Cuando una variable cumple, Location no es … |
| Música para cada lugar | Una regla de BGM condicional por lugar, con Detener BGM anterior activado |
| Lugares que se abren durante la historia | Plantilla Mapa con Lugares abiertos |
| Un lugar grande con contenido propio | Un escenario que se usa Cuando una variable cumple una condición |
| Limitar las rutas entre lugares | Código de interfaz (la ruta con código propio de arriba) |
Esta es la receta n.º 12
El mismo montaje (una variable, más lore y música que la siguen) sirve para los pisos de una torre, las habitaciones de una casa o mundos al otro lado de un portal. El Ciclo Día-Noche lo usa con la hora en lugar del lugar, y los dos se combinan: un bosque de noche puede tener su propia entrada con las dos condiciones.
