// Displays a given story element for this player
    private void display_element(TimeBytes_StoryElement element)
    {
        // First check for a revisit
        if (element.alreadyVisited && element.revisitAlt != null)
        {
            display_element(element.revisitAlt);
            return;
        }
        element.alreadyVisited = true;

        // Basic setup for new element
        current_element = element;
        MinigameController.Instance.AddScore(player, 1);

        // Invoke the element's entryEvent, if it's not empty
        if (element.entryEvent != null)
        {
            element.entryEvent.Invoke();
        }

        // Initialize the description text
        description_TMP.text = element.description;
        description_TMP.maxVisibleCharacters = 0;
        time_til_next_char = 0.25f;

        if (element is TimeBytes_Fork)
        {
            TimeBytes_Fork fork = element as TimeBytes_Fork;
            option1_TMP.text = fork.Option1.text;
            option2_TMP.text = fork.Option2.text;
        }
        else if (element is TimeBytes_Extension)
        {
            TimeBytes_Extension extension = element as TimeBytes_Extension;
            // TODO - just have a third, centered text display for "continue"?
            if (extension.continuation.text.Length == 0)
            {
                option1_TMP.text = TimeBytes_Config.default_continue_text;
            }
            else
            {
                option1_TMP.text = extension.continuation.text;
            }
            option2_TMP.text = "";
        }
        else if (element is TimeBytes_Leaf)
        {
            TimeBytes_Leaf leaf = element as TimeBytes_Leaf;
            option1_TMP.text = "";
            option2_TMP.text = "";
        }
    }
    // Called every frame
    private void Update()
    {
        // Update the description, character by character
        if (!descr_fully_visible())
        {
            time_til_next_char -= Time.deltaTime;
            while (time_til_next_char < 0 && !descr_fully_visible())
            {
                incr_descr_length();
            }
        }

        // Check for input from this player, to select an option (as long as the animation is done)
        if (descr_fully_visible())
        {
            if (current_element is TimeBytes_Fork)
            {
                if (MinigameInputHelper.IsButton1Down(player))
                {
                    TimeBytes_Fork fork = current_element as TimeBytes_Fork;
                    choose_option(fork.Option1);
                }
                else if (MinigameInputHelper.IsButton2Down(player))
                {
                    TimeBytes_Fork fork = current_element as TimeBytes_Fork;
                    choose_option(fork.Option1);
                }
            }
            else if (current_element is TimeBytes_Extension)
            {
                if (MinigameInputHelper.IsButton1Down(player) || MinigameInputHelper.IsButton2Down(player))
                {
                    TimeBytes_Extension extension = current_element as TimeBytes_Extension;
                    choose_option(extension.continuation);
                }
            }
        }

        // If any joystick input was given, skip the rest of the text animation
        bool hor_skip  = Mathf.Abs(MinigameInputHelper.GetHorizontalAxis(player)) > TimeBytes_Config.joystick_skip_thresh;
        bool vert_skip = Mathf.Abs(MinigameInputHelper.GetVerticalAxis(player)) > TimeBytes_Config.joystick_skip_thresh;

        if (hor_skip || vert_skip)
        {
            description_TMP.maxVisibleCharacters = description_TMP.text.Length;
        }
    }