Quests&Objectives

Events

QuestComp->OnQuestStarted.AddDynamic(this, &AMyPlayerState::OnQuestStarted);
QuestComp->OnObjectiveProgress.AddDynamic(this, &AMyPlayerState::OnObjectiveProgress);
QuestComp->OnQuestCompleted.AddDynamic(this, &AMyPlayerState::OnQuestCompleted);
QuestComp->OnQuestFailed.AddDynamic(this, &AMyPlayerState::OnQuestFailed);
QuestComp->OnQuestAbandoned.AddDynamic(this, &AMyPlayerState::OnQuestAbandoned);
QuestComp->OnObjectiveFailTimerStarted.AddDynamic(this, &AMyPlayerState::OnFailTimerStarted);
QuestComp->OnQuestSaveDirty.AddDynamic(this, &AMyPlayerState::OnQuestSaveDirty);

Bind on the server PlayerState or GameMode for all events. Bind on the owning client for HUD.

Client OnRep diffs emit Started, Available, and Completed when Times Completed increases. They also emit phase advances, objective counts, and fail-timer started.

Fail Time Remaining replicates about four times a second. That path does not mark save dirty.

First replication is a snapshot

The first OnRep_QuestStates does not replay historical delegates.

void UMyTrackerWidget::NativeConstruct()
{
    Super::NativeConstruct();
    UQuestComponent* QC = GetOwningQuestComponent();
    ActiveQuests = QC->GetQuestsByStatus(EQuestStatus::Active);
    RebuildRows();
    QC->OnObjectiveProgress.AddDynamic(this, &UMyTrackerWidget::OnProgress);
}

Fail and abandon on the client

Those transitions change Active to Available in one update. Client OnRep does not fire Failed or Abandoned for that change.

When the widget is shown, rebuild from GetQuestsByStatus. Server bindings still receive OnQuestFailed and OnQuestAbandoned.