Monday, January 21, 2019

text based - How do I implement branching dialogue in javascript?


I'm making a very basic visual novel type of game in JavaScript. I'm a beginner, so I'm just doing this for fun and learning, and due to bad planning I have run into a bit of a problem when you get to a branch in dialogue.


Currently I hold the script for the game in a string variable and I break up each scene with a tag such as "#~" into smaller arrays so that the game script looks like this:


var script = "Hello World!#~How are you today?"

var gameText = script.split("#~");
//gameText[0]= Hello World!

This works great for linear stuff, but how should I handle a branch in the dialogue tree? This method seems very complicated, as I would have to know exactly how long each path is and then if I ever needed to change anything it would be a headache.


How can I do this in a simpler way? I'm trying to stick to vanilla JavaScript as I'd like the game to work with Web Run Time.



Answer



Philipp's answer already shows the right direction. I just think the data structure is needlessly verbose. Shorter texts would be easier to write and read.


Even if shorter texts would make the algorithm a bit more complex, that's worth doing, because you only write the algorithm once, but most of your time will be spent writing and maintaining the story. Therefore optimize for making easier the part you will spend most time doing.


var story = [
{ m: "Hi!" },

{ m: "This is my new game." },
{ question: "Do you like it?", answers: [
{ m: "yes", next: "like_yes" },
{ m: "no", next: "like_no" },
] },
{ label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
{ label: "like_no", m: "You made me sad!", next: "like_end" },
{ label: "like_end" },
{ m: "OK, let's change the topic" }
];


Some explanations for this design:


The whole story is written in one array. You don't have to provide numbers, they are provided automatically by the array syntax: the first item has index 0, the next one has index 1, etc.


In most cases, it is not necessary to write the number of the following step. I assume that most lines of text are not branches. Let's make "the next step is the following item" a default assumption, and only make notes when it is otherwise.


For jumps, use labels, not numbers. Then, if you later add or remove a few lines, the logic of the story will be preserved, and you don't have to adjust the numbers.


Find a reasonable compromise between clarity and shortness. For example, I suggest to write "m" instead of "message", because that will be the most frequently used command ever, so making it short will make the text more legible. But there is no need to shorten the remaining keywords. (However, do as you wish. The important thing is to make it most legible for you. Alternatively, you could support both "m" and "message" as valid keywords.)


The algorithm for the game should be something like this:


function execute_game() {
var current_line = 0;
while (current_line < story.length) {

var current_step = story[current_line];
if (undefined !== current_step.m) {

display_message(current_step.m);
if (undefined !== current_step.next) {
current_line = find_label(current_step.next);
} else {
current_line = current_line + 1;
}


} else if (undefined !== current_step.question) {

// display the question: current_step.question
// display the answers: current_step.answers
// choose an answer
// and change current_line accordingly

}
}
}


By the way, these ideas were inspired by Ren'Py, which is not exactly what you want (not JavaScript, not web), but could give you some cool ideas anyway.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...