I’m working on dialogue, and right now it’s really straightforward- each conversation/cutscene is stored as a series of single [line,speaker] pairs, so in order to play the entire dialogue the system simply needs to iterate through the array of lines and play them one-by-one until they run out, indicating the end of the conversation:
USTRUCT(Blueprintable)
struct FDialogueLine {
GENERATED_BODY()
UPROPERTY(EditAnywhere)
FString text;
UPROPERTY(EditAnywhere)
FName speakerName;
};
USTRUCT(Blueprintable)
struct FDialogueLookupTable : public FTableRowBase {
GENERATED_BODY()
UPROPERTY(EditAnywhere)
TArray<FDialogueLine> lines;
};
This is really all I need for linear dialogue, from here I could simply store each complete conversation as its own unique datatable and load the desired table whenever I want to play a conversation. However, if I wanted to add branching dialogue, where player choices selected during the conversation change the outcome, this no longer works. I have a kind of nebulous notion that I could do something like store each potential branch of the conversation in its own datatable, and make a choice look something like this:
USTRUCT(Blueprintable)
struct FDialogueChoice {
GENERATED_BODY()
UPROPERTY(EditAnywhere)
FString text;
UPROPERTY(EditAnywhere)
UDataTable* Dialogue;
};
If I do it that way, I could simply place each branch of the dialogue in its own discrete datatable, add a TArray<FDialogueChoice> to every FDialogueLine, and check after each line was displayed to see if the system needs to break out of the current dialogue, display a list of choices, and load + iterate through a new array of FDialogueLine based on which FDialogueChoice was selected.
This kinda works, but I can quickly see it spiraling out of control as the complexity of conversations increases and it becomes borderline-impossible to remember how everything is connected together. Is there any easy way I could modify my design to make it more friendly and modular, or is this entire approach ill-advised from the getgo?