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 clasePaso 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:
| Plantilla | Qué te da |
|---|---|
| Ficha de personaje | Nombre, género, edad, aspecto y un secreto, con una tarjeta que se va llenando mientras el jugador escribe. Solo el nombre es obligatorio |
| Elegir origen | Un selector de tarjetas con tres opciones. Lo convertirás en el selector de clase |
| Confirmar antes de empezar | Resume 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:
- Haz clic en el título y cámbialo por «Elige tu clase»
- 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»)
- 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:
- Añade una entrada de lore «Lore del Mago» con lo que sabe y puede hacer un Mago en este mundo
- Arrastra la variable Clase sobre la entrada y haz clic en la línea. Pon la condición Clase es
Mago - 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:
- Aparece la ficha de personaje. Escribe «Elara» y una línea de trasfondo
- Elige Mago
- La página de confirmación enumera lo que elegiste. Pulsa su botón de empezar
- Aparece la apertura. Envía «Voy hacia el pueblo»
- 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íntoma | Causa probable | Solución |
|---|---|---|
| No aparece el formulario | Las páginas no están en la cadena de inicio | Tienen 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 salida | Ningún botón de la página lleva a ningún sitio | Dale un botón con Ir a la página |
| La IA no hace caso de la clase | La variable Clase no tiene Reglas de comportamiento, o la IA no ve las variables | Escrí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 entra | El valor de la condición no coincide exactamente con la opción elegida | La condición tiene que decir Mago tal cual se llama la opción |
| La IA le cambia el nombre al jugador | La IA puede escribir en Nombre del jugador | Pon 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:
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 && !hasCreatedmuestra el formulario solo en el primer mensaje, y solo hasta que se guarda una clase- Los tres valores de
React.useStateguardan 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íaapi.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:
{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 quieres | Cómo hacerlo |
|---|---|
| Un formulario antes de la historia | Interfaz → Plantillas → Inicio · antes de que empiece la historia |
| Solo el nombre | Plantilla Escribir tu nombre |
| Varios campos | Plantilla Ficha de personaje |
| Elegir una entre varias opciones | Plantilla Elegir origen (un selector de tarjetas), renombrada |
| Resumir antes de empezar | Plantilla Confirmar antes de empezar, siempre al final |
| Hacer obligatorio un campo | Botón de empezar → Solo se puede pulsar cuando esto esté lleno |
| Que la IA no cambie lo elegido | Acceso de la IA: Solo lectura para la IA |
| Lore distinto según lo elegido | Entrada de lore con una condición sobre la variable |
| Meter lo elegido en el texto del lore | Macros como {{player_name}} en una entrada de lore (no en la apertura) |
| Código: cambiar de apertura y luego guardar lo elegido | await 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.
