Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Godot Dialogue System 2

An advanced non-linear dialogue system for the free and open-source Godot engine. · By radmatt

[Bug] array index overflow error

A topic by JustusPan created Oct 04, 2020 Views: 335 Replies: 6
Viewing posts 1 to 7

Sometimes following error will be reported (the index is random):

Invalid get index '124' (on base: 'String').


--------- In Message.gd ----------------------

func _start_showing_characters():
var n = 0
for x in text_node.clean_text.length():
if ! is_message_completed:
text_node.visible_characters += 1
var v = text_node.visible_characters

var letter = text_node.clean_text[v-1]    #<---------------------error position

I'm not sure what's the root cause of this issue. Just add following code temporarily, I'll come back when I finish my game jam.

if v-1 >= text_node.clean_text.length(): 
     continue
var letter = text_node.clean_text[v-1]

Same issue here. The string had 8 characters but for some reason, in my iteration x reached 9. But it happened only once, as soon as I placed breakpoints to debug, the bug disappeared and it now stops at 8 as expected…

(2 edits) (+1)

OK, so I have some hypotheses about what’s going on: a. The for loop increments x but text_node.visible_characters is unrelated. Somewhat, this value may increase more than expected at some point b. The for loop itself is correct, but text_node changes in the middle of the loop, due to parallel handling of other events. For instance:

# PRESS A BUTTON TO CONTINUE DIALOGUE
func _input(event):
	if event.is_action_pressed("continue_dialogue") and ! event.is_echo():
		if current_json_path != "":
			next()

may be run in parallel as the user presses Space just when the text reaches its last character, causing dialogue to advance to next text node. As a result, the text_node has now a different number of characters (but in practice, when getting the error text_node.visible_characters was always exactly text_node.clean_text.length()+1 (so 1 over the limit), so it doesn’t look like text is unrelated.

considering the length of the text seems to have changed between the for statement (which should check v < text_node.clean_text.length():

c. clean_text itself is changing during the loop… but I don’t see where.

@radmatt could you please help to look into this issue?

(1 edit)

I sometimes get a related issue, even with the continue hack.

Invalid get index ‘11’ (on base: ‘String’) for a string of exactly 11 chars: “Hm, okay…” The dots are important, they make us enter the block below:

Message.gd:148 (line count includes the continue hack):

if v-1 < text_node.cleaner_text.length():
    if punctuation_marks_pauses.has(text_node.cleaner_text[v-1]):
        if text_node.cleaner_text[v-1] == ".":
            # invalid index here
            if text_node.cleaner_text[v] == ".":
                _pause_t += punctuation_marks_pauses["..."]
            else:
                _pause_t += punctuation_marks_pauses[text_node.cleaner_text[v-1]]
        else:
            _pause_t += punctuation_marks_pauses[text_node.cleaner_text[v-1]]

It doesn’t surprise me that much since we check for v - 1 < length but not v. What surprises me then is that it doesn’t systematically fail, since I’m always testing with the same string. Again, it must be because that v variable suddenly goes up by 1 at the end of the iteration.

Here is another hotfix for this check index, but v, not v-1 this time:

# replace `if text_node.cleaner_text[v] == ".":` with this:
if v < text_node.clean_text.length() and text_node.cleaner_text[v] == ".":

It will avoid the error, although we are now using the pause duration for ‘.’ and not ‘…’, but v was incorrect anyway so there’s a deeper issue behind. All the characters are still displayed normally.