v
Skip to content

Formulario de creación de personaje ​

Antes de que empiece la historia, el jugador rellena una ficha de personaje: un nombre, una clase y un trasfondo corto. Luego pulsa «Empezar la aventura» y arranca la historia, con la IA sabiendo ya quién es. La interfaz del jugador tiene plantillas justo para esto, así que el formulario no necesita código.


Lo que vas a construir ​

Unas pocas páginas por las que pasa el jugador antes del primer mensaje:

  • Un campo para el nombre
  • Un selector de clase: Guerrero, Mago o Pícaro, cada uno con una frase de descripción
  • Un campo para el trasfondo, opcional
  • Una página de confirmación que resume lo elegido, con un botón que empieza la historia

Todo lo que rellena el jugador va a variables normales. La IA las ve desde su primera respuesta.

Cómo funciona ​

1. El jugador empieza una partida nueva → aparece la primera página de inicio en lugar del chat
2. Escribe un nombre y un trasfondo → se guardan en las variables Nombre del jugador y Trasfondo
3. Elige una clase → se guarda en la variable Clase
4. Confirma → el chat empieza con tu apertura
5. El jugador envía su primer mensaje
   → El prompt de la IA incluye las variables, sus Reglas de comportamiento
     y el lore que solo entra para la clase elegida
   → La IA lo llama por su nombre y lo trata según su clase

Paso a paso ​

Paso 1: Añade las páginas de inicio desde plantillas ​

Pulsa Interfaz en el centro de la barra superior y luego Plantillas. En Inicio · antes de que empiece la historia, añade:

PlantillaQué te da
Ficha de personajeNombre, género, edad, aspecto y un secreto, con una tarjeta que se va llenando mientras el jugador escribe. Solo el nombre es obligatorio
Elegir origenUn selector de tarjetas con tres opciones. Lo convertirás en el selector de clase
Confirmar antes de empezarResume todo lo elegido hasta ahí. Siempre va al final

El jugador pasa por ellas en orden antes de que empiece la historia. Cada plantilla te dice qué variables añade a la carta («Añade estas variables a la tarjeta»). Son variables normales, que ya traen unas Reglas de comportamiento que le explican a la IA qué significan, como «El nombre del jugador. Todos en la historia lo llaman así; nunca inventes otro.»

¿Solo necesitas un nombre?

La plantilla Escribir tu nombre pide un nombre y cómo quiere el jugador que lo llamen, y nada más.

Paso 2: Convierte el selector de origen en un selector de clase ​

Selecciona la página de Elegir origen en la columna de páginas de la izquierda y cámbiala:

  1. Haz clic en el título y cámbialo por «Elige tu clase»
  2. Selecciona el selector de tarjetas. Cambia el nombre de sus tres opciones a Guerrero («Especialista cuerpo a cuerpo, mucha vida»), Mago («Magia a distancia, mucho maná») y Pícaro («Ágil y sigiloso, muchos críticos»)
  3. Haz doble clic en la página en la columna de páginas y renómbrala «Clase»

El selector guarda la opción elegida en la variable Origen. Vuelve al lienzo, busca Origen en el bloque de Variables, cámbiale el nombre a Clase y reescribe sus Reglas de comportamiento:

La clase que eligió el jugador al empezar: Guerrero, Mago o Pícaro. Decide qué puede hacer en un combate y cómo lo ven los demás. No la cambies.

Después abre Qué hace la IA con ella y pon Acceso de la IA en Solo lectura para la IA, para que la IA no pueda reescribir la clase del jugador.

Paso 3: Recorta la ficha de personaje ​

En la página de Ficha de personaje, deja el nombre y convierte uno de los campos en el trasfondo:

  • Borra las partes que no quieras (selecciónalas, o búscalas en Capas, y pulsa Supr). Después puedes borrar sus variables desde el lienzo
  • Cambia la etiqueta del campo «Un secreto» a «Trasfondo (opcional)» y su texto de ejemplo a «Unas frases sobre tu pasado». Luego, en el lienzo, cambia el nombre de su variable de Secreto del jugador a Trasfondo, y cambia sus Reglas de comportamiento por El trasfondo del jugador, escrito por el jugador. Úsalo; no lo contradigas. (La regla que trae la plantilla lo trata como un secreto que nadie en la historia conoce, y eso no es lo que quieres para un trasfondo)

Nombre del jugador se queda con la regla de la plantilla. Si quieres cubrir a los jugadores que se saltan el nombre, selecciona el botón de empezar y marca Nombre del jugador en Solo se puede pulsar cuando esto esté lleno. Así el botón se queda en gris hasta que se escriba un nombre.

Paso 4 (opcional): Dale a cada clase su propio lore ​

Las variables le dicen a la IA qué eligió el jugador. Para darle a cada clase más material, añade una entrada de lore por clase que solo le llegue a la IA con esa clase:

  1. Añade una entrada de lore «Lore del Mago» con lo que sabe y puede hacer un Mago en este mundo
  2. Arrastra la variable Clase sobre la entrada y haz clic en la línea. Pon la condición Clase es Mago
  3. Repite con Guerrero y Pícaro

Ahora, si el jugador es Mago, la IA recibe la entrada del Mago y las demás se quedan fuera. El lore condicional se explica en Apertura y lore.

Paso 5: Escribe la apertura ​

La apertura (Saludo en el lienzo) es el primer mensaje después del formulario. Escríbela como siempre:

*La puerta del destino se abre de par en par y la luz del alba se derrama sobre las Tierras Antiguas.*

*Al frente brilla la silueta de una ciudad lejana, y un camino empedrado se estira hacia ella. El viento huele a hierba y a humo de hogares lejanos.*

Ante ti hay tres caminos: una calzada ancha que lleva al pueblo, un sendero estrecho que se mete en el bosque y una cuesta que baja hasta el río. ¿Por dónde vas?

No metas lo que elige el jugador en el texto de la apertura

Las aperturas se escriben en la partida cuando esta se crea, antes de que el jugador haya rellenado el formulario. Una macro {{Nombre del jugador}} en la apertura mostraría el valor inicial de la variable, no lo que escribió el jugador. Deja el nombre y la clase a la IA: su primera respuesta ya los conoce.

Paso 6: Pruébalo ​

Desactiva Editar en la interfaz del jugador para recorrer las páginas sin gastar saldo. Luego pulsa Jugar en la barra superior:

  1. Aparece la ficha de personaje. Escribe «Elara» y una línea de trasfondo
  2. Elige Mago
  3. La página de confirmación enumera lo que elegiste. Pulsa su botón de empezar
  4. Aparece la apertura. Envía «Voy hacia el pueblo»
  5. La IA te llama Elara y te trata como Mago (bastones, hechizos, gente que se fija en tu túnica)

Este turno, a la derecha de la prueba, muestra las variables y el lore que recibió la IA.

Si algo falla:

SíntomaCausa probableSolución
No aparece el formularioLas páginas no están en la cadena de inicioTienen que salir de plantillas de Inicio · antes de que empiece la historia, con la página de confirmación al final
Una página tiene el aviso Sin salidaNingún botón de la página lleva a ningún sitioDale un botón con Ir a la página
La IA no hace caso de la claseLa variable Clase no tiene Reglas de comportamiento, o la IA no ve las variablesEscríbele Reglas de comportamiento, y comprueba que Variables mostradas a la IA, en el Context de la carta, no esté en Ninguna
El lore de la clase nunca entraEl valor de la condición no coincide exactamente con la opción elegidaLa condición tiene que decir Mago tal cual se llama la opción
La IA le cambia el nombre al jugadorLa IA puede escribir en Nombre del jugadorPon su Acceso de la IA en Solo lectura para la IA

Ruta con código propio: un formulario dentro del primer mensaje ​

Si quieres que el formulario lo dibuje tu propio código de interfaz, por ejemplo justo debajo del primer mensaje, aquí tienes la versión con código. Usa tres variables de Texto llamadas player_name, player_class y player_backstory (todas en Solo lectura para la IA, con player_name empezando en Traveler) y dos aperturas: una escena corta de «¿quién eres?» como primera, y la apertura de verdad de la historia como segunda.

El código de interfaz lee y escribe las variables por su nombre. 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 [name, setName] = React.useState("");
  const [selectedClass, setSelectedClass] = React.useState("");
  const [backstory, setBackstory] = React.useState("");

  // Once a class is saved, the form is done
  const hasCreated = String(api.variables.player_class || "") !== "";

  const classes = [
    { id: "Warrior", label: "Warrior", icon: "⚔️", desc: "Melee specialist, high HP" },
    { id: "Mage", label: "Mage", icon: "🔮", desc: "Ranged magic, high MP" },
    { id: "Rogue", label: "Rogue", icon: "🗡️", desc: "Agile and stealthy, high crit" },
  ];

  const handleStart = async () => {
    if (!selectedClass) return;
    // Switch to the second opening FIRST: switching resets variables
    // to that opening's starting values
    await api.switchGreeting(1);
    api.setVariable("player_name", name.trim() || "Traveler");
    api.setVariable("player_class", selectedClass);
    api.setVariable("player_backstory", backstory.trim());
  };

  const label = { fontSize: "13px", color: "#a5b4fc", marginBottom: "6px", fontWeight: "600" };
  const field = {
    width: "100%", padding: "10px 14px", background: "#0f172a",
    border: "1px solid #334155", borderRadius: "8px", color: "#e2e8f0",
    fontSize: "14px", outline: "none", boxSizing: "border-box", fontFamily: "inherit",
  };

  return (
    <Chat renderBubble={(msg) => (
      <div>
        <div
          style={{ color: "#e2e8f0", lineHeight: 1.7 }}
          dangerouslySetInnerHTML={{ __html: msg.contentHtml }}
        />

        {msg.messageIndex === 0 && !hasCreated && (
          <div style={{
            marginTop: "20px",
            padding: "24px",
            background: "linear-gradient(135deg, #1e1b4b 0%, #1a1a2e 100%)",
            borderRadius: "16px",
            border: "1px solid #312e81",
          }}>
            <div style={{ fontSize: "18px", fontWeight: "bold", color: "#c4b5fd", marginBottom: "20px", textAlign: "center" }}>
              Create Your Character
            </div>

            <div style={{ marginBottom: "16px" }}>
              <div style={label}>Character Name</div>
              <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="Leave blank for 'Traveler'"
                style={field}
              />
            </div>

            <div style={{ marginBottom: "16px" }}>
              <div style={{ ...label, marginBottom: "8px" }}>Choose a Class</div>
              <div style={{ display: "flex", gap: "10px" }}>
                {classes.map((cls) => {
                  const picked = selectedClass === cls.id;
                  return (
                    <button
                      key={cls.id}
                      onClick={() => setSelectedClass(cls.id)}
                      style={{
                        flex: 1,
                        padding: "14px 10px",
                        background: picked ? "linear-gradient(135deg, #4338ca, #6366f1)" : "#1e293b",
                        border: picked ? "2px solid #818cf8" : "1px solid #334155",
                        borderRadius: "10px",
                        color: picked ? "#e0e7ff" : "#94a3b8",
                        cursor: "pointer",
                        textAlign: "center",
                      }}
                    >
                      <div style={{ fontSize: "24px", marginBottom: "4px" }}>{cls.icon}</div>
                      <div style={{ fontSize: "14px", fontWeight: "bold", marginBottom: "2px" }}>{cls.label}</div>
                      <div style={{ fontSize: "11px", opacity: 0.7 }}>{cls.desc}</div>
                    </button>
                  );
                })}
              </div>
            </div>

            <div style={{ marginBottom: "20px" }}>
              <div style={label}>Backstory (optional)</div>
              <textarea
                value={backstory}
                onChange={(e) => setBackstory(e.target.value)}
                placeholder="A few sentences about your character's past..."
                rows={3}
                style={{ ...field, resize: "vertical" }}
              />
            </div>

            <button
              onClick={handleStart}
              disabled={!selectedClass}
              style={{
                width: "100%",
                padding: "14px",
                background: selectedClass ? "linear-gradient(135deg, #7c3aed, #a855f7)" : "#374151",
                border: "none",
                borderRadius: "10px",
                color: selectedClass ? "#f5f3ff" : "#6b7280",
                fontSize: "16px",
                fontWeight: "bold",
                cursor: selectedClass ? "pointer" : "not-allowed",
              }}
            >
              {selectedClass ? "Start Adventure" : "Pick a class first"}
            </button>
          </div>
        )}
      </div>
    )} />
  );
}

Qué hace el código:

  • msg.messageIndex === 0 && !hasCreated muestra el formulario solo en el primer mensaje, y solo hasta que se guarda una clase
  • Los tres valores de React.useState guardan lo que va escribiendo el jugador hasta que pulsa Start Adventure
  • api.switchGreeting(1) cambia el primer mensaje por la segunda apertura (las aperturas se cuentan desde 0). Al cambiar, las variables vuelven a los valores iniciales de esa apertura, así que el código espera a que termine el cambio y escribe las variables después. Si lo hicieras al revés, el cambio las borraría
  • api.setVariable("player_class", ...) escribe por el nombre de la variable

La IA lee estas variables en su siguiente prompt. Si quieres lore que detalle el perfil, también puedes escribir macros en una entrada que se envíe siempre:

[Player character]
Name: {{player_name}}
Class: {{player_class}}
Backstory: {{player_backstory}}

Las macros del lore se rellenan cada vez que se monta el prompt de la IA, así que siempre llevan los valores actuales. Las de una apertura no: la apertura se escribe cuando se crea la partida, así que {{player_name}} ahí muestra el valor inicial («Traveler»).

El estado que aparece junto al archivo en Paneles → Código de frontend debería ser un OK verde.

Mostrar el personaje en los mensajes siguientes ​

Dentro de renderBubble, encima del texto del mensaje:

tsx
{hasCreated && (
  <div style={{ display: "flex", gap: "8px", marginBottom: "8px", fontSize: "12px", color: "#a5b4fc" }}>
    <span>{String(api.variables.player_name)}</span>
    <span style={{ opacity: 0.5 }}>|</span>
    <span>{String(api.variables.player_class)}</span>
  </div>
)}

¿No quieres escribir el código tú?

Pulsa Asistente IA arriba a la derecha del lienzo y describe el formulario que quieres.


Para ir más lejos ​

Más clases ​

En la ruta con plantillas, añade una opción al selector de tarjetas y su entrada de lore. En la ruta con código, añade un elemento al array classes.

Puntos de atributo ​

La plantilla Repartir atributos reparte seis puntos entre Fuerza, Agilidad, Carisma e Ingenio. Ponla entre la página de la clase y la de confirmación.

Un comienzo distinto para cada clase ​

Si cada clase tiene que empezar en un sitio completamente distinto, escribe una apertura por clase y añade la plantilla Elegir inicio (necesita al menos dos aperturas). Los escenarios ligados a una apertura solo existen en las partidas que empezaron por ella. Mira Escenarios.


Referencia rápida ​

Lo que quieresCómo hacerlo
Un formulario antes de la historiaInterfaz → Plantillas → Inicio · antes de que empiece la historia
Solo el nombrePlantilla Escribir tu nombre
Varios camposPlantilla Ficha de personaje
Elegir una entre varias opcionesPlantilla Elegir origen (un selector de tarjetas), renombrada
Resumir antes de empezarPlantilla Confirmar antes de empezar, siempre al final
Hacer obligatorio un campoBotón de empezar → Solo se puede pulsar cuando esto esté lleno
Que la IA no cambie lo elegidoAcceso de la IA: Solo lectura para la IA
Lore distinto según lo elegidoEntrada de lore con una condición sobre la variable
Meter lo elegido en el texto del loreMacros como {{player_name}} en una entrada de lore (no en la apertura)
Código: cambiar de apertura y luego guardar lo elegidoawait api.switchGreeting(1) y después api.setVariable(...)

Esta es la receta n.º 4

En Salto de escenas y cambio de entradas mediante UI se explica con más detalle cómo cambiar de apertura desde botones y cómo usar macros en el lore. Crear el personaje suele ser el primer paso antes de las demás recetas: una clase puede decidir el oro inicial para la tienda o los objetos iniciales del inventario.