Text Adventure Game Dialogue

Set Up

// accesses html elements
const textElement = document.getElementById('text')
const optionButtonsElement = document.getElementById('option-buttons')

let state = {} // some options will result in modifications to character state

// start or restart function, sets html to first dialogue node
function startGame() {
  state = {}
  showTextNode(1)
}

Display Options

function showTextNode(textNodeIndex) {
    state.currentNode = textNodeIndex; // Store the current node id in the state object
    const textNode = textNodes.find(textNode => textNode.id === textNodeIndex) // makes sure text node id updates as you move nodes
    textElement.innerText = textNode.text // displays the text of the node on the html
    // there can be a max of three option choices, if there are less listed in the node then the html element will not display
    while (optionButtonsElement.firstChild) {
      optionButtonsElement.removeChild(optionButtonsElement.firstChild)
    }
  
    // sets up option buttons and inputs the node text in the html element
    textNode.options.forEach(option => {
      if (showOption(option)) {
        const button = document.createElement('button')
        button.innerText = option.text
        button.classList.add('btn')
        button.addEventListener('click', () => selectOption(option)) // registers the user input of which option is clicked
        optionButtonsElement.appendChild(button)
      }
    })
  }
  
  // some options only show up if the user's state has been altered by a certain action
  function showOption(option) {
    return option.requiredState == null || option.requiredState(state)
  }

Select an Option

// Modifies the `selectOption` function
function selectOption(option) {
    const nextTextNodeId = option.nextText;
    
    if (nextTextNodeId <= 0) { // if the user clicks an option labeled Restart then the game will run again from the beginning
      return startGame();
    }
    
    if (option.previousText === true) { // if the user clicks an option labeled Go Back then the game will go back to the previous text node the user had viewed
      previous(); // Call the previous function directly
      return;
    }
    
    state = Object.assign(state, option.setState); // if an answer choice modifies the state of the user it will be put into place here

    showTextNode(nextTextNodeId);
  }

Go Back to Previous Node

function previous() {
    const previousTextNodeId = findPreviousTextNodeId(state.currentNode); // Pass the current node id
    showTextNode(previousTextNodeId); // shows the last node viewer viewed
  }
  
  // Modifies the `findPreviousTextNodeId` function
  function findPreviousTextNodeId(textNodeIndex) {
    const previousTextNode = textNodes.find(node =>
      node.options && node.options.some(option => option.nextText === textNodeIndex) // finds and saves the id of the last node the viewer viewed
    );
  
    return previousTextNode ? previousTextNode.id : -1; // Updates the default value to -1
  }

Dialogue Content

const textNodes = [
    {
      id: 1,
      text: 'What\'s this, you want to challenge me on my Java knowledge of Unit 1: Primitive Types? \n\n(Marlene will ask you two conceptual questions and explain several concepts. Pay close attention as they will be useful to you later on. Estimated time: 10 minutes.)',
      options: [
        {
          text: 'Yes, It\'ll be an equal exchange.',
          nextText: 2
        },
        {
          text: 'I heard you were the best in the class on this unit.',
          nextText: 2
        }
      ]
    },
    {
        id: 3,
        text: 'Tell me some key characteristic of Primitives Data Types.',
        options: [
          {
            text: 'Primitives are predefined, can be null, can call methods, and have all the same sizes.',
            nextText: 10
          },
          {
            text: 'Primitives are predefined, always have a value, can\'t call methods, and have type dependent sizes.',
            nextText: 4
          },
          {
            text: 'Primitives are defined by you, can be null, can call methods, and have type dependent sizes.',
            nextText: 10
          }
        ]
      },
      {
        id: 10,
        text: 'That\'s not quite right. Try Again.',
        options: [
          {
            text: 'Go Back',
            previousText: true
          },
          {
            text: 'Restart',
            nextText: -1
          }
        ]
      }
]