Skip to content

Inventario y equipo

Construye una cuadrícula de inventario — muestra todos los artículos que el jugador ha recolectado, con iconos y cantidades. Los consumibles pueden usarse (desaparecen cuando se agotan), el equipo puede ponerse. Esta receta te muestra cómo combinar una variable JSON, lógica del Root Component y comportamientos para construir un sistema de inventario completo.


Lo que vas a construir

Un panel de inventario integrado en la interfaz del chat. El jugador ve todos sus artículos, cada uno mostrando un icono, nombre y cantidad. Debajo de cada artículo hay un botón de acción:

  • Consumibles (por ejemplo, pociones) — haz clic en "Use" → HP se restaura en 20 → el conteo de pociones disminuye en 1 → se elimina del inventario cuando el conteo llega a 0 → emergente dice "Used a potion! HP +20"
  • Equipo (por ejemplo, espada de hierro) — haz clic en "Equip" → la ranura de arma muestra "Iron Sword" → la IA sabe que el jugador está blandiendo una espada de hierro → emergente dice "Equipped Iron Sword!"
El jugador hace clic en el botón "Use" en una poción
  → el renderizador comprueba: ¿el inventario contiene una poción?
    → sí: actualiza el array de inventario, hp +20, toast de éxito
    → no: toast de advertencia "No potions left!"

El jugador hace clic en el botón "Equip" en Iron Sword
  → el renderizador comprueba: ¿ya equipado?
    → no: dispara el comportamiento "equip-sword"
    → el comportamiento establece equipped_weapon, le dice a la IA, muestra notificación
    → sí: toast informativo "Already equipped!"

Cómo funciona

El inventario se almacena como una variable JSON — una única variable que contiene un array completo de objetos de artículo. El Root Component lee este array para mostrar la cuadrícula, y lo manipula directamente usando api.setVariable() cuando el jugador usa o adquiere artículos.

¿Por qué manejar la lógica en el Root Component? Los operadores de condición del sistema de comportamientos (eq, neq, gt, lt, contains, etc.) funcionan sobre valores simples — números, cadenas, booleanos. No pueden buscar dentro de arrays JSON (por ejemplo, "¿contiene el array un objeto con name = Potion?"). Para estructuras de datos complejas como inventarios, el Root Component es el lugar adecuado para manejar la lógica usando JavaScript.

Los comportamientos aún se usan para cosas en las que son buenos: establecer variables simples (equipped_weapon), inyectar instrucciones a la IA ("Tell AI") y mostrar notificaciones.

La división:

QuéDóndePor qué
Mostrar la cuadrícula de inventarioRoot ComponentLee el array JSON y renderiza UI
Usar un consumibleRoot ComponentNecesita encontrar, actualizar y eliminar elementos del array
Equipar un armaComportamientoEstablece una variable de tipo string + le dice a la IA
Decir a la IA sobre los cambiosComportamientoSolo los comportamientos pueden inyectar instrucciones a la IA

Paso a paso

Paso 1: Crea las variables

Necesitamos 3 variables — inventario (array JSON), puntos de vida (número) y arma actualmente equipada (cadena).

Editor → barra lateral izquierda → pestaña Variables → haz clic en "Add Variable" para cada una

Variable 1: Inventario

CampoValorPor qué
Nombre visibleInventarioEtiqueta legible para ti
IDinventoryEl ID usado en código y comportamientos para leer/escribir esta variable
TipoJSONEl inventario es un array — necesita el tipo JSON para almacenarlo
Valor por defecto[{"name":"Potion","icon":"🧪","count":2},{"name":"Iron Sword","icon":"⚔️","count":1}]Las nuevas sesiones empiezan con 2 pociones y 1 espada de hierro
CategoríaInventoryLo agrupa bajo la categoría Inventory
Reglas de comportamientoLos botones del inventario gestionan automáticamente las acciones de usar y equipar. También puedes añadir artículos durante la historia (el jugador encuentra botín, recibe una recompensa) o quitar artículos (rotos, perdidos, robados).Le dice a la IA que el inventario también puede cambiar durante la narración

El valor predeterminado de una variable JSON debe ser JSON válido. Usa comillas dobles alrededor de los nombres de los campos y los valores de cadena. Cada objeto de artículo tiene tres campos: name (para coincidencia y visualización), icon (para la UI), count (para seguir la cantidad de los consumibles).

Variable 2: Puntos de vida

CampoValorPor qué
Nombre visiblePuntos de vidaEtiqueta legible
IDhpSe usa cuando las pociones restauran HP
TipoNumberHP es numérico — necesita sumar/restar
Valor por defecto80Empezar por debajo del máximo le da al jugador una razón para usar una poción
Valor mínimo0Evita que HP sea negativo
Valor máximo100Tope de HP en 100, evita acumulación infinita
CategoríaStatsVariable de estadística del personaje
Reglas de comportamientoEl valor actual representa los puntos de vida restantes del jugador (0-100). Disminuye en combate o situaciones peligrosas, aumenta al usar pociones o descansar.Le dice a la IA cuándo cambiar HP

Variable 3: Arma equipada

CampoValorPor qué
Nombre visibleArma equipadaEtiqueta legible
IDequipped_weaponRegistra el nombre del arma equipada del jugador
TipoStringAlmacena el nombre del arma como texto
Valor por defecto(déjalo vacío)Cadena vacía = nada equipado
CategoríaCustomVariable de estado del equipo
Reglas de comportamientoEl valor actual es el nombre del arma que el jugador tiene equipada. Una cadena vacía significa que no hay nada equipado. El botón de equipar lo establece automáticamente, pero también puedes cambiarlo durante la historia — por ejemplo, el arma se rompe, se la roban o el jugador encuentra una nueva.Le dice a la IA que el estado del equipo también puede cambiar narrativamente

¿Por qué usar una cadena para equipped_weapon en lugar de JSON? Porque el jugador solo puede blandir un arma a la vez. Una cadena simple es suficiente — vacía significa desequipado, "Iron Sword" significa equipado. Si quieres un sistema de equipo de múltiples ranuras (arma + armadura + accesorio), podrías usar un objeto JSON en su lugar.


Paso 2: Crea los comportamientos

Necesitamos 2 comportamientos — equipar espada de hierro (éxito y ya equipado). El uso de pociones se maneja completamente en el Root Component.

Editor → pestaña Behaviors → haz clic en "Add Behavior"

Comportamiento 1: Equipar Espada de Hierro (éxito)

WHEN (disparador):

CampoValorPor qué
Trigger TypeAction button pressedSe dispara cuando el Root Component llama a executeAction("equip-sword")
Action IDequip-swordCoincide con la llamada executeAction("equip-sword") en el Root Component

ONLY IF (condiciones):

VariableOperadorValorPor qué
equipped_weaponneqIron SwordNo ya equipado — evita superposición con el Comportamiento 2

DO (efectos):

Añade estos efectos en orden:

Tipo de efectoConfiguraciónQué hace
Modificar variableVariable equipped_weapon, operación set, valor Iron SwordEstablece el arma actual a Iron Sword
Tell AIContenido: El jugador equipó una Espada de Hierro. A partir de ahora, el jugador empuña un mandoble de hierro. Refleja la presencia del arma en las descripciones de combate y en las interacciones.Inyecta una instrucción para que la IA sepa del arma
Mostrar notificaciónMensaje Equipped Iron Sword!, estilo achievementEmergente de éxito dorado

¿Qué hace "Tell AI"? Inyecta una instrucción temporal en el contexto de la IA. De esta forma, cuando la IA escriba su próxima respuesta, sabe que el jugador acaba de equipar una espada y puede reflejarlo en la narrativa (por ejemplo, "You tighten your grip on the iron sword. Its cold edge glints in the firelight.").

Comportamiento 2: Equipar Espada de Hierro (ya equipada)

WHEN:

CampoValor
Trigger TypeAction button pressed
Action IDequip-sword

ONLY IF:

VariableOperadorValorPor qué
equipped_weaponeqIron SwordYa equipada — no es necesario equipar de nuevo

DO:

Tipo de efectoConfiguraciónQué hace
Mostrar notificaciónMensaje Iron Sword is already equipped!, estilo infoEmergente informativo azul

¿Por qué dividir esto en dos comportamientos? Mismo patrón que la receta de la tienda — un único comportamiento solo puede tener un conjunto de condiciones. Si las condiciones pasan, se ejecuta; si no, no pasa nada. Así que usamos dos comportamientos para cubrir ambos casos. Escuchan el mismo action ID, pero sus condiciones son mutuamente exclusivas — solo uno se dispara.

¿Por qué no hay comportamiento "use-potion"? Porque comprobar si un array JSON contiene un artículo específico requiere JavaScript — el operador contains del sistema de comportamientos solo funciona en cadenas, no en arrays. Así que la lógica de las pociones vive en el Root Component donde tenemos acceso completo a JavaScript. El Root Component actualiza las variables inventory y hp directamente mediante api.setVariable().


Paso 3: Añade el panel de inventario en el Root Component

Este es el paso que hace que la UI del inventario aparezca en el chat. Mostraremos tres secciones debajo del último mensaje: una barra de HP, una ranura de equipo y una cuadrícula de inventario (cada artículo con un botón de acción).

Editor → sección Custom UI → abre index.tsx → pega lo siguiente (reemplazando el predeterminado return <Chat />):

tsx
export default function MyWorld() {
  var api = useYumina();
  var msgs = api.messages || [];

  // Lee las variables
  var hp = Number(api.variables.hp ?? 80);
  var equippedWeapon = String(api.variables.equipped_weapon || "");
  var inventory = Array.isArray(api.variables.inventory)
    ? api.variables.inventory
    : [];

  // ── Lógica del inventario (se ejecuta en el Root Component) ──

  function useItem(itemName) {
    var inv = Array.isArray(api.variables.inventory)
      ? api.variables.inventory
      : [];
    var idx = -1;
    for (var i = 0; i < inv.length; i++) {
      if (inv[i] && inv[i].name === itemName) { idx = i; break; }
    }
    if (idx === -1) {
      api.showToast("No " + itemName + " left!", "error");
      return;
    }
    var item = inv[idx];
    var newInv = inv.slice(); // copia el array
    if (Number(item.count) <= 1) {
      newInv.splice(idx, 1); // elimínalo por completo
    } else {
      newInv[idx] = { name: item.name, icon: item.icon, count: Number(item.count) - 1 };
    }
    api.setVariable("inventory", newInv);

    // Específico para pociones: restaurar HP
    if (itemName === "Potion") {
      var currentHp = Number(api.variables.hp ?? 0);
      api.setVariable("hp", Math.min(currentHp + 20, 100));
      api.showToast("Used a potion! HP +20", "success");
    }
  }

  function equipItem(itemName, actionId) {
    if (equippedWeapon === itemName) {
      api.showToast(itemName + " is already equipped!", "info");
      return;
    }
    api.executeAction(actionId); // dispara el comportamiento para set + Tell AI
  }

  // Mapa de tipos de artículo: decide qué acción recibe cada artículo
  var itemActions = {
    "Potion": { type: "consumable", handler: function() { useItem("Potion"); }, label: "Use" },
    "Iron Sword": { type: "equipment", handler: function() { equipItem("Iron Sword", "equip-sword"); }, label: "Equip" },
  };

  return (
    <Chat renderBubble={(msg) => {
      var isLastMsg = msg.messageIndex === msgs.length - 1;
      return (
    <div>
      {/* Renderiza el texto del mensaje normalmente (la plataforma ya renderizó el HTML, usa contentHtml directamente) */}
      <div
        style={{ color: "#e2e8f0", lineHeight: 1.7 }}
        dangerouslySetInnerHTML={{ __html: msg.contentHtml }}
      />

      {/* Muestra el panel de inventario solo debajo del último mensaje */}
      {isLastMsg && (
        <div style={{
          marginTop: "16px",
          padding: "16px",
          background: "rgba(15, 23, 42, 0.6)",
          borderRadius: "12px",
          border: "1px solid #334155",
        }}>

          {/* ====== Barra de HP ====== */}
          <div style={{
            display: "flex",
            alignItems: "center",
            gap: "10px",
            marginBottom: "14px",
          }}>
            <span style={{ fontSize: "16px" }}>❤️</span>
            <div style={{ flex: 1 }}>
              <div style={{
                display: "flex",
                justifyContent: "space-between",
                marginBottom: "4px",
              }}>
                <span style={{ color: "#94a3b8", fontSize: "12px" }}>HP</span>
                <span style={{ color: "#e2e8f0", fontSize: "12px", fontWeight: "bold" }}>
                  {hp} / 100
                </span>
              </div>
              <div style={{
                height: "8px",
                background: "#1e293b",
                borderRadius: "4px",
                overflow: "hidden",
              }}>
                <div style={{
                  height: "100%",
                  width: Math.min(hp, 100) + "%",
                  background: hp > 50
                    ? "linear-gradient(90deg, #22c55e, #4ade80)"
                    : hp > 20
                      ? "linear-gradient(90deg, #eab308, #facc15)"
                      : "linear-gradient(90deg, #ef4444, #f87171)",
                  borderRadius: "4px",
                  transition: "width 0.3s ease",
                }} />
              </div>
            </div>
          </div>

          {/* ====== Ranura de equipo ====== */}
          <div style={{
            display: "flex",
            alignItems: "center",
            gap: "8px",
            marginBottom: "14px",
            padding: "10px 14px",
            background: "rgba(30, 41, 59, 0.8)",
            borderRadius: "8px",
            border: "1px solid #475569",
          }}>
            <span style={{ fontSize: "16px" }}>⚔️</span>
            <span style={{ color: "#94a3b8", fontSize: "13px" }}>Weapon:</span>
            <span style={{
              color: equippedWeapon ? "#e2e8f0" : "#475569",
              fontSize: "13px",
              fontWeight: equippedWeapon ? "600" : "normal",
              fontStyle: equippedWeapon ? "normal" : "italic",
            }}>
              {equippedWeapon || "None"}
            </span>
          </div>

          {/* ====== Encabezado del inventario ====== */}
          <div style={{
            fontSize: "14px",
            fontWeight: "bold",
            color: "#94a3b8",
            marginBottom: "10px",
            textTransform: "uppercase",
            letterSpacing: "1px",
          }}>
            Inventory
          </div>

          {/* ====== Cuadrícula de inventario ====== */}
          {inventory.length === 0 ? (
            <div style={{
              padding: "24px",
              textAlign: "center",
              color: "#475569",
              fontSize: "13px",
              background: "rgba(30, 41, 59, 0.4)",
              borderRadius: "8px",
              border: "1px dashed #334155",
            }}>
              Inventory is empty
            </div>
          ) : (
            <div style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))",
              gap: "8px",
            }}>
              {inventory.map(function(item, idx) {
                var name = String(item?.name || item);
                var icon = String(item?.icon || "📦");
                var count = Number(item?.count ?? 1);
                var action = itemActions[name];

                return (
                  <div
                    key={idx}
                    style={{
                      display: "flex",
                      flexDirection: "column",
                      alignItems: "center",
                      padding: "12px 8px 8px",
                      background: "rgba(30, 41, 59, 0.8)",
                      borderRadius: "8px",
                      border: equippedWeapon === name
                        ? "1px solid #22d3ee"
                        : "1px solid #475569",
                      gap: "6px",
                    }}
                  >
                    <span style={{ fontSize: "28px" }}>{icon}</span>
                    <span style={{
                      color: "#e2e8f0",
                      fontSize: "12px",
                      fontWeight: "600",
                      textAlign: "center",
                    }}>
                      {name}
                    </span>
                    <span style={{
                      color: "#64748b",
                      fontSize: "11px",
                    }}>
                      x{count}
                    </span>

                    {/* Botón de acción */}
                    {action && (
                      <button
                        onClick={action.handler}
                        style={{
                          marginTop: "4px",
                          padding: "4px 14px",
                          background: action.type === "consumable"
                            ? "linear-gradient(135deg, #065f46, #047857)"
                            : equippedWeapon === name
                              ? "linear-gradient(135deg, #374151, #4b5563)"
                              : "linear-gradient(135deg, #1e3a5f, #1e40af)",
                          border: action.type === "consumable"
                            ? "1px solid #10b981"
                            : equippedWeapon === name
                              ? "1px solid #6b7280"
                              : "1px solid #3b82f6",
                          borderRadius: "6px",
                          color: action.type === "consumable"
                            ? "#a7f3d0"
                            : equippedWeapon === name
                              ? "#9ca3af"
                              : "#bfdbfe",
                          fontSize: "12px",
                          fontWeight: "600",
                          cursor: "pointer",
                          width: "100%",
                        }}
                      >
                        {equippedWeapon === name ? "Equipped" : action.label}
                      </button>
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </div>
      )}
    </div>
      );
    }} />
  );
}

Recorrido por el código

No te intimides por la longitud — lo que hace es muy directo. Vamos sección por sección:

Configuración básica

tsx
var api = useYumina();
var msgs = api.messages || [];
// ...
<Chat renderBubble={(msg) => {
  var isLastMsg = msg.messageIndex === msgs.length - 1;
  // ...
}} />
  • El Root Component MyWorld() es la entrada para la UI del mundo. <Chat renderBubble={...} /> deja a la plataforma manejar la lista de mensajes, el cuadro de entrada y el desplazamiento — solo tomas el control del aspecto de cada burbuja
  • useYumina() — toma la API de Yumina para que puedas leer variables y disparar acciones
  • msg.messageIndex — el índice de la burbuja actual en la lista de mensajes. El panel de inventario solo se renderiza debajo del último mensaje, así que no se repite en cada uno
  • msg.contentHtml — el HTML que la plataforma ya renderizó desde Markdown, se puede pasar directamente a dangerouslySetInnerHTML

Leyendo variables

tsx
var hp = Number(api.variables.hp ?? 80);
var equippedWeapon = String(api.variables.equipped_weapon || "");
var inventory = Array.isArray(api.variables.inventory)
  ? api.variables.inventory
  : [];
  • api.variables.hp — lee los puntos de vida. ?? 80 es un fallback en caso de que la variable no se haya cargado aún
  • api.variables.equipped_weapon — lee el arma actual. Cadena vacía significa nada equipado
  • api.variables.inventory — lee el inventario. Array.isArray() protege contra tipos inesperados

Funciones de lógica de inventario

tsx
function useItem(itemName) {
  var inv = Array.isArray(api.variables.inventory)
    ? api.variables.inventory : [];
  var idx = -1;
  for (var i = 0; i < inv.length; i++) {
    if (inv[i] && inv[i].name === itemName) { idx = i; break; }
  }
  if (idx === -1) {
    api.showToast("No " + itemName + " left!", "error");
    return;
  }
  // ... update array and call api.setVariable()
}

Este es el patrón clave. Dado que los operadores de condición del sistema de comportamientos no pueden buscar dentro de arrays JSON, manejamos la lógica directamente aquí en el Root Component:

  1. Encuentra el artículo — recorre el array y coincide por name
  2. Comprueba si existe — si no se encuentra, muestra un toast de error
  3. Actualiza el array — disminuye el conteo o elimina por completo
  4. Escríbelo de vuelta — llama a api.setVariable("inventory", newInv) para persistir el cambio

Para el equipo, equipItem() delega a api.executeAction() porque el comportamiento maneja el establecimiento de la variable y la inyección de una instrucción a la IA:

tsx
function equipItem(itemName, actionId) {
  if (equippedWeapon === itemName) {
    api.showToast(itemName + " is already equipped!", "info");
    return;
  }
  api.executeAction(actionId);
}

Mapa de tipos de artículo

tsx
var itemActions = {
  "Potion": { type: "consumable", handler: function() { useItem("Potion"); }, label: "Use" },
  "Iron Sword": { type: "equipment", handler: function() { equipItem("Iron Sword", "equip-sword"); }, label: "Equip" },
};

Una tabla de búsqueda. Dado el nombre de un artículo, te dice la etiqueta del botón y la función handler a llamar. El campo type controla el color del botón — los consumibles obtienen verde, el equipo obtiene azul. ¿Quieres añadir un nuevo artículo? Añade una línea aquí. Para consumibles, añade lógica a useItem. Para equipo, crea un comportamiento correspondiente en el editor.

Botón de acción

tsx
<button onClick={action.handler}>
  {equippedWeapon === name ? "Equipped" : action.label}
</button>

Hacer clic en el botón llama directamente a la función handler. Para consumibles, el handler gestiona el array en JavaScript. Para equipo, el handler llama a api.executeAction() que dispara el comportamiento correspondiente.

¿No quieres escribir código tú mismo? Usa Studio AI

Barra superior del editor → haz clic en "Enter Studio" → panel AI Assistant → describe lo que quieres en lenguaje natural, por ejemplo "Construye una cuadrícula de inventario con una barra de HP, ranura de equipo y artículos que se puedan usar o equipar" — la IA generará el código por ti.


Paso 4: Guarda y prueba

  1. Haz clic en Save en la parte superior del editor
  2. Haz clic en Start Game o vuelve a la página de inicio e inicia una nueva sesión
  3. Verás el panel de inventario debajo de la respuesta de la IA: HP 80/100, ranura de arma vacía, 2 pociones y 1 espada de hierro
  4. Haz clic en "Use" en una poción — HP va de 80 a 100, la poción desaparece, el toast dice "Used a potion! HP +20"
  5. Haz clic en "Equip" en Iron Sword — la ranura de arma muestra "Iron Sword", el botón se vuelve gris y dice "Equipped", el emergente dice "Equipped Iron Sword!"
  6. Haz clic en el botón "Equipped" en Iron Sword de nuevo — el toast dice "Iron Sword is already equipped!"
  7. Sigue chateando con la IA — si añadiste el efecto "Tell AI", la respuesta de la IA reflejará que el jugador blande una espada de hierro

Si algo no funciona:

SíntomaCausa probableSolución
El panel de inventario no apareceEl código del Root Component no se guardó o tiene un error de sintaxisComprueba el estado de compilación en la parte inferior de la sección Custom UI — debería mostrar un "OK" verde
El inventario no muestra artículosEl valor predeterminado de la variable JSON tiene mal formatoAsegúrate de que el predeterminado sea un array JSON válido con nombres de campos entre comillas dobles
El botón no hace nada al hacer clicEl action ID del comportamiento no coincide con el códigoConfirma que el action ID del comportamiento sea exactamente equip-sword, coincidiendo con el argumento executeAction() en el código
Se usó una poción pero no desaparecióLa función useItem no puede encontrar el nombre del artículoAsegúrate de que el campo name del artículo en el JSON coincida exactamente con lo que useItem() busca — sensible a mayúsculas
HP no cambióLa llamada api.setVariable no está alcanzando la variable correctaComprueba que el ID de la variable sea exactamente hp — debe coincidir con la definición de la variable
Equipado pero la IA no lo sabeFalta el efecto "Tell AI"Añade un efecto "Tell AI" dentro de la sección DO del comportamiento de equipar

Cómo puede la IA modificar el inventario

La IA también puede añadir o eliminar artículos durante la historia usando directivas. Como el inventario es una variable JSON, la IA puede usar la directiva push para añadir artículos:

Derrotaste al goblin y encontraste una poción de salud entre sus pertenencias.
[inventory: push {"name":"Potion","icon":"🧪","count":1}]

Limitaciones de las directivas de IA en arrays

La directiva push funciona bien para añadir artículos. Sin embargo, delete en arrays solo funciona con un índice numérico (por ejemplo, [inventory: delete 0] elimina el primer elemento), y merge solo funciona en objetos planos, no en arrays. Para operaciones complejas de inventario (eliminar un artículo específico por nombre, actualizar conteos de artículos), usa la lógica JavaScript del Root Component o diseña tu sistema para que la IA comunique su intención a través de otras variables sobre las que los comportamientos puedan actuar.


Referencia rápida

Qué quieresCómo hacerlo
Almacenar una lista de artículosCrea una variable JSON con un valor predeterminado de [{...}, ...]
Mostrar una cuadrícula de inventarioEn el Root Component, usa CSS Grid + inventory.map()
Usar un consumibleRoot Component: encontrar artículo → actualizar array → api.setVariable() → mostrar toast
Equipar un artículoRoot Component: llama a api.executeAction() → Comportamiento: establecer variable + Tell AI
Comprobar si el jugador posee un artículoRoot Component: inventory.find(i => i.name === "ItemName")
Añadir un artículo (IA)Directiva de IA: [inventory: push {"name":"Item","icon":"📦","count":1}]
Seguir el equipo actualCrea una variable de tipo string — cadena vacía = nada equipado
Botón dispara usar/equiparEn el Root Component, llama a funciones handler o api.executeAction("actionId")
Hacer saber a la IA sobre los cambiosAñade un efecto "Tell AI" en el comportamiento

Pruébalo tú mismo — mundo demo importable

Descarga este JSON e impórtalo como un nuevo mundo para ver todo en acción:

recipe-7-demo.json

Cómo importar:

  1. Ve a Yumina → My WorldsCreate New World
  2. En el editor, haz clic en More ActionsImport Package
  3. Selecciona el archivo .json descargado
  4. El mundo se crea con todas las variables, comportamientos y Root Component preconfigurados
  5. Inicia una nueva sesión y pruébalo

Qué incluye:

  • 3 variables (inventory + hp puntos de vida + equipped_weapon arma actual)
  • 2 comportamientos (equipar espada de hierro éxito + ya equipada)
  • Un Root Component (barra de HP + ranura de equipo + cuadrícula de inventario + botones de acción + lógica de usar/equipar)

Esta es la Receta #7

Las recetas anteriores cubrieron el salto de escenas, los sistemas de combate, las interfaces de tienda y la creación de personaje. Esta receta te enseña a gestionar un inventario de array JSON usando lógica JavaScript del Root Component combinada con comportamientos para cambios de estado simples. El mismo patrón funciona para registros de misiones, árboles de habilidades, recetas de crafteo — cualquier cosa que necesite "gestionar una lista, realizar operaciones en sus elementos".