Choosing a random line from a txt file

Godot Version

4.2.1

Question

Hi, I found an old forum thread to help me with what I put in the title, I adapted it to Godot 4 and it worked. But when I turned it into a function to activate through a button signal, it gives me an Breakpoint error.

extends Control

func _on_button_pressed():
	var file = "res://list.txt"
	var list = FileAccess.open(file, FileAccess.READ)
	var line_counter = 0 #an integer to count the lines
	while not list.eof_reached(): #this loops through each line until the file end is reached
		line_counter+=1 #as its doing so, before getting the next line, it adds a counter
		list.get_line() #sets the file read cursor to the next line
	list.seek(0) #this is now outside of the former loop. after the loop, reset the cursor position
	var random_last_line = randi() % line_counter # integer generated that is equal to line 0, to a random line counted
	var stored_line = '' #the varialbe that will store the line is an empty string for now
	for i in range(0,random_last_line):
		stored_line = list.get_line() #randomly get a line, which is now set to store_line string variable
	
	print(stored_line)
	$Label.text = stored_line

It specifically says that the breakpoint happesn with var random_last_line = randi() % line_counter

Hmmm, the code works for me. It print’s the stored line, but no errors.

In my game I created an array (wisdom) and used this to print the dialogue:

$Label.text = (wisdom.pick_random())

I must have changed something without noticing, for some reason it worked fine if I also declared the same variables in _ready().

Also someone on Reddit showed me a much much simpler way to do it, I’ll share it in case someone googles this:

func random_item():    
    var file = "res://list.txt"
    var list = FileAccess.open(file, FileAccess.READ)
    var rng = RandomNumberGenerator.new()
        
    while not list.eof_reached():
        $Label.text = list.get_line()
        if rng.randi() % 10 == 0:
            return
1 Like

I realize this is an old topic, but I wanted to point out that this would be biased towards lines earlier in the file. Since you’re rolling the dice after every line, the probability that an individual line will be picked depends on its order in the file:

The likelihood that the first line is picked is 0.1. The likelihood that the second line is picked is the probability that the first one wasn’t picked and the second one is: (1 - 0.1)*(0.1) = 0.09. And so on.

If you wanted it to be uniformly distributed, you would still need an initial loop to count the number of lines, then pick your random number in that range.

1 Like