Saltar al contenido principal

Sistema de Misiones

El sistema de misiones proporciona un ciclo de vida completo de misiones: creación, seguimiento, progreso, finalización, fracaso, recompensas, requisitos previos, límites de tiempo y misiones repetibles. Todos los datos de misiones se definen mediante ScriptableObjects y están integrados con el sistema de guardado y CommandGraph.

Descripción General de la Arquitectura​

ClasePropósito
QuestScriptableObject que define los objetivos, recompensas, requisitos previos y metadatos de una misión
ObjectiveClase serializable que representa una única tarea rastreable dentro de una misión
QuestRewardClase serializable que representa una recompensa otorgada al completar
QuestStatusEstado en tiempo de ejecución de una misión: contadores de progreso, marcas de tiempo, banderas de finalización/fracaso
QuestManagerSavableObject que rastrea todos los estados de misiones, maneja el ciclo de vida y dispara eventos

Quest​

Crea una misión mediante MCE > Quests > Quest en el menú de activos. Cada Quest ScriptableObject tiene las siguientes secciones:

Clasificación​

CampoTipoDescripción
IsMainQuestboolLas misiones principales son críticas para la progresión de la historia
CategoryQuestCategoryOrganiza la misión en el registro de misiones (ver más abajo)
DifficultyQuestDifficultyEasy, Normal, Hard, Expert — mostrado en la UI

Categorías de Misiones:

  • MainStory — progresión de la historia principal
  • SideQuest — misiones opcionales de NPC
  • DailyTask — se reinicia cada 24 horas
  • WeeklyChallenge — se reinicia cada 7 días
  • Event — misiones de evento por tiempo limitado
  • Collection — llenar el MonsterDex, encontrar todos los objetos, etc.

Otorgante de la Misión​

CampoTipoDescripción
QuestGiverCharacterDataEl NPC que asigna esta misión

Requisitos​

CampoTipoDescripción
PrerequisiteQuestsList<Quest>Misiones que deben completarse primero
MinBadgesintNúmero mínimo de medallas para aceptar (0 = ninguna)
RecommendedLevelintMostrado en la UI, no es obligatorio

Tiempo y Repetición​

CampoTipoDescripción
TimeLimitSecondsintLímite de tiempo en segundos (0 = sin límite). La misión falla automáticamente al expirar
IsRepeatableboolSi la misión puede reiniciarse después de completarse
RepeatCooldownSecondsintTiempo de espera antes de reaceptar (86400 = diario, 604800 = semanal)

Objective​

Cada misión contiene una List<Objective> que define las tareas que el jugador debe completar. Los objetivos están ordenados y pueden avanzarse automáticamente.

Tipos de Objetivo (11)​

TipoDescripciónCampos Clave
TalkHablar con un NPC específicoTargetNPC
DeliverEntregar un objeto a un NPCTargetNPC, TargetItem
DefeatDerrotar entrenadores o monstruos salvajesTargetMonster (null = cualquiera), TargetCount
CatchCapturar una especie específicaTargetMonster, TargetCount
CollectRecolectar una cantidad de un objetoTargetItem, TargetCount
GoToViajar a un mapa específicoMapLocation
EscortEscoltar a un NPC a un destinoTargetNPC, MapLocation
EvolveEvolucionar un monstruo de una especieTargetMonster
HatchEggIncubar un huevo de monstruoTargetMonster (null = cualquiera)
WinAtFacilityGanar una batalla en una instalación específicaMapLocation
CustomRastreado mediante una variable del juegoCustomVariableKey, TargetCount

Campos del Objetivo​

[Serializable]
public class Objective
{
public string LocalizationKey; // Texto descriptivo localizado
public ObjectiveType Type; // Qué debe hacer el jugador
public SceneInfoAsset MapLocation; // Dónde (para GoTo, marcador en minimapa)
public CharacterData TargetNPC; // Quién (para Talk/Deliver/Escort)
public MonsterEntry TargetMonster; // Qué especie (null = cualquiera)
public ScriptableObject TargetItem; // Qué objeto (Collect/Deliver)
public int TargetCount = 1; // Cuántos se necesitan
public bool IsOptional; // Objetivo bonus, no requerido
public bool HiddenUntilPrevious; // Oculto hasta que se complete el objetivo anterior
public string CustomVariableKey; // Para seguimiento de tipo Custom
}

Los objetivos opcionales no bloquean la finalización de la misión. Los objetivos ocultos crean una sensación de descubrimiento a medida que la misión progresa.

QuestReward​

Cada misión tiene una List<QuestReward> otorgada automáticamente al completar.

Tipos de Recompensa (6)​

TipoCamposEjemplo
ItemItemReward, ItemQuantity5x Super Potion
MoneyMoneyAmount$5.000
ExperienceExpAmount2.000 EXP distribuidos al equipo
MonsterMonsterReward, MonsterLevelLv.20 Thundermane
GameVariableGameVariableKey, GameVariableValueEstablecer HAS_BIKE = 1
UnlockCustomUnlockId"safari_zone_access"
// Cada recompensa tiene una descripción legible para la UI
reward.GetDescription(); // "Super Potion x5", "$5.000", "2.000 EXP", etc.

QuestManager​

QuestManager es un SavableObject (ScriptableObject con soporte de guardado/carga) que posee todo el estado runtime de las misiones. Crear mediante MCE > Quests > Manager.

Ciclo de Vida de las Misiones​

No Iniciada  -->  StartQuest()  -->  Activa (rastreando objetivos)
|
+---------+-----+-----+---------+
| |
CompleteQuest() FailQuest()
| |
Completada Fallida
|
(si IsRepeatable)
|
StartQuest() (después de enfriamiento)

Iniciar una Misión​

questManager.StartQuest(quest, startingObjective: 0);

Esto crea una entrada QuestStatus, registra la marca de tiempo de inicio, muestra una notificación y establece el objetivo inicial. Si la misión es repetible y está en enfriamiento, la llamada se ignora con una advertencia.

Progresar Objetivos​

// Incrementar el contador de progreso para el objetivo #0 en 1
questManager.UpdateObjectiveProgress(quest, objectiveIndex: 0, delta: 1);

Cuando el progreso alcanza el TargetCount del objetivo, el sistema muestra una notificación y avanza automáticamente al siguiente objetivo no opcional. Si todos los objetivos requeridos están completos, la misión se completa automáticamente.

También puedes establecer el objetivo actual directamente:

questManager.SetQuestObjective(quest, objective: 2);

Completar y Fallar​

questManager.CompleteQuest(quest);  // Marca completada, otorga recompensas, dispara evento
questManager.FailQuest(quest); // Marca fallida, dispara evento

Misiones con Límite de Tiempo​

Llama a questManager.CheckTimeExpiry() periódicamente (ej. desde el Update de un MonoBehaviour) para fallar automáticamente las misiones cuyo tiempo ha expirado:

long remaining = questManager.GetRemainingTime(quest); // segundos, o -1

Consultar Misiones​

// Todas las misiones con las que el jugador ha interactuado
Dictionary<Quest, QuestStatus> all = questManager.GetAllQuests();

// Consultas filtradas
List<Quest> active = questManager.GetActiveQuests();
List<Quest> completed = questManager.GetCompletedQuests();
List<Quest> failed = questManager.GetFailedQuests();

// Filtrar por categoría, estado de finalización y/o estado de fracaso
// Firma: GetQuestsFiltered(QuestCategory? category = null, bool? completed = null, bool? failed = null)
List<Quest> dailies = questManager.GetQuestsFiltered(
category: QuestCategory.DailyTask,
completed: false,
failed: null
);

// Verificar requisitos previos
bool canStart = questManager.ArePrerequisitesMet(quest);

// Obtener todas las misiones disponibles para iniciar (requisitos cumplidos, no iniciadas aún)
List<Quest> available = questManager.GetAvailableQuests();

// Verificar si el jugador tiene una misión específica
bool has = questManager.HasQuest(quest);

Porcentaje de Finalización del Juego​

El QuestManager rastrea un porcentaje de finalización del juego basado en las misiones completadas. Puede calcularse automáticamente (completadas / total de misiones en la base de datos del mundo) o contra un denominador fijo (QuestsForHundo). El porcentaje se vuelve visible para el jugador cuando VisibleGamePercentage está establecido en true.

float pct = questManager.GameCompletionPercentage; // 0.0 - 1.0

Eventos​

questManager.OnQuestStarted      += (Quest q) => { ... };
questManager.OnObjectiveProgressed += (Quest q, int objIdx, int newVal) => { ... };
questManager.OnObjectiveChanged += (Quest q, int newObjIdx) => { ... };
questManager.OnQuestCompleted += (Quest q) => { ... };
questManager.OnQuestFailed += (Quest q) => { ... };
questManager.OnRewardsGranted += (Quest q, List<QuestReward> rewards) => { ... };

Guardar / Cargar​

QuestManager extiende SavableObject y serializa todos los estados de las misiones a JSON mediante SavableQuestManager. Las referencias a misiones se almacenan por nombre y se resuelven contra WorldDatabase al cargar.

Nodos de CommandGraph (10)​

El sistema de misiones proporciona 10 nodos de CommandGraph para usar en scripts de NPC y disparadores de eventos:

Nodos de Acción​

NodoDescripción
StartQuestIniciar una misión con un índice de objetivo inicial opcional
CompleteQuestMarcar una misión como completada (otorga recompensas)
FailQuestMarcar una misión como fallida
UpdateQuestObjectiveEstablecer el objetivo actual en un índice específico
ProgressQuestObjectiveIncrementar el contador de progreso de un objetivo en un delta
UnlockGameCompletionPercentageHacer visible el porcentaje de finalización para el jugador

Nodos de Condición​

NodoDescripción
IfPlayerHasQuestRamificar si el jugador ha iniciado (o completado) una misión
IfCompletedQuestRamificar si una misión ha sido completada
IfQuestFailedRamificar si una misión ha sido fallida
IfCurrentQuestObjectiveRamificar si el objetivo actual de la misión coincide con un índice específico

Ejemplo: Flujo de Misión de NPC​

[IfPlayerHasQuest] -- No --> [Dialog: "¡Necesito ayuda!"] --> [StartQuest]
-- Sí --> [IfCompletedQuest] -- Sí --> [Dialog: "¡Gracias!"]
-- No --> [IfCurrentQuestObjective(1)]
-- Sí --> [Dialog: "¿Lo encontraste?"]
-- No --> [Dialog: "¡Sigue buscando!"]

Crear una Misión: Paso a Paso​

  1. Crear el activo Quest: Haz clic derecho en la ventana Proyecto, selecciona MCE > Quests > Quest
  2. Establecer clasificación: Elige categoría, dificultad y si es una misión principal
  3. Asignar el otorgante: Arrastra el CharacterData del NPC al campo Quest Giver
  4. Definir objetivos: Agrega entradas a la lista de Objetivos. Establece el tipo, objetivo y cantidad para cada uno
  5. Definir recompensas: Agrega entradas a la lista de Recompensas. Elige el tipo de recompensa y completa los campos relevantes
  6. Establecer requisitos previos (opcional): Arrastra otros activos Quest a PrerequisiteQuests
  7. Configurar tiempo/repetición (opcional): Establece TimeLimitSeconds y/o IsRepeatable con un tiempo de enfriamiento
  8. Registrar en WorldDatabase: Agrega la misión a WorldDatabase.Quests para que aparezca en las consultas de disponibilidad
  9. Conectar CommandGraph: Usa los nodos de misión en el CommandGraph de tu NPC para iniciar, rastrear y completar la misión