v
Skip to content

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 mano

Solo 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.

CampoValor
NombreLocation
TipoTexto
Valor inicialVillage
Reglas de comportamientoDó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 cotidiano

Forest ​

[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 incierto

Cave ​

[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 opresivo

Market ​

[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 ajetreado

Paso 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:

CampoValor
CUANDOCondición de variable: Location es Forest
ReproducirForest
Fundido de entrada (s) / Fundido de salida (s)3 / 3
Detener BGM anteriorActivado
Al terminarVolver 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:

  1. Cambiar una variable: Location, Poner en, Forest
  2. Ir a la página: la página de la conversación
  3. 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.

  1. Suena la música del pueblo. Abre Mapa: «Estás en: Village», y no hay botón de Village
  2. Toca Forest. Vuelves al chat, se envía «(Me dirijo a Forest)» y la IA describe el bosque
  3. Si añadiste música, la pista del pueblo pasa con un fundido a la del bosque
  4. Ve a la cueva y luego vuelve al pueblo: regresa la música del pueblo de la playlist
  5. 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íntomaCausa probableSolución
Tocar un lugar no hace nadaEl botón no tiene pasosRevisa Al pulsar, en orden
La ubicación cambia pero la IA no respondeFalta el paso Decir una frase por el jugadorAñádelo como último paso
La IA describe el lugar equivocadoLa condición de una entrada no coincide con el valor que pone el botónForest tiene que escribirse igual en el botón y en la condición
Se mezcla el ambiente de dos lugaresUna de las entradas está en el bloque que se envía siempreRevisa Cuándo lo ve la IA en cada entrada
Suenan dos pistas a la vezDetener BGM anterior está desactivadoActívalo en la regla de cada lugar
La música salta en lugar de hacer fundidoLos fundidos están en 0Pon 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:

tsx
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 nombre
  • routes enumera adónde lleva cada lugar. Los lugares a los que no se puede llegar desde aquí salen apagados y no se pueden tocar
  • travel() cambia Location y luego api.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.isStreaming oculta el mapa mientras la IA sigue escribiendo, para que el jugador no pueda viajar a mitad de una respuesta
  • gridTemplateColumns: "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 ​

  1. Añade una entrada de lore «Harbor» con la condición Location es Harbor
  2. Si quieres, añade una pista para el puerto y una regla de BGM condicional para ella
  3. Añade un botón Harbor en la página del mapa (o una línea en el array locations y en routes)
  4. 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 quieresCómo hacerlo
Saber dónde está el jugadorUna variable de Texto, Location
Darle a la IA el ambiente del lugar actualUna entrada de lore por lugar, con una condición sobre Location
Mover al jugador desde un botónPasos: Cambiar una variable, Ir a la página, Decir una frase por el jugador
Que la IA describa la llegada en el actoDecir 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 lugarUna regla de BGM condicional por lugar, con Detener BGM anterior activado
Lugares que se abren durante la historiaPlantilla Mapa con Lugares abiertos
Un lugar grande con contenido propioUn escenario que se usa Cuando una variable cumple una condición
Limitar las rutas entre lugaresCó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.