Godot Version
4.6
Question
video: https://youtu.be/XT44ZzqqA6s
hi beginner here.
so in my game as you may be able to see through the attached video, the player can select up to 5 cards max to try and guess the correct card. when theyre chances are exhausted the game creates a card of the correct card, and if theyre correct then theyre correct. ive come across a strange problem where if the player selects the correct card in the fifth try the game just freezes, doesnt even output an error just freezes and i genunienly dont know why. the attached video is a screen recording of me triying out this bug in all the ways i can think and through it all godot only outputted the following error once: “Invalid access to property or key ‘data’ on a base object of type ‘Nil’.” and “E 0:00:35:049 main.gd:116 @ createcard(): Index p_idx = 57 is out of bounds (items.size() = 5).
<C++ Source> scene/gui/item_list.cpp:108 @ get_item_text()
main.gd:116 @ createcard()
main.gd:82 @ finishgame()
main.gd:50 @ chancededuct()
main.gd:260 @ _on_item_list_item_selected()”
please help
if you need anything else please ask ill try to respond asap
script for my main scene witch handles basically all of the card creation process
extends Control
@onready var ICcontainer=$ScrollContainer/VBoxContainer
var infocard=preload("res://key card.tscn")
@onready var card=infocard.instantiate()
var logo=preload("res://logotexture.tscn")
@onready var logotexture=logo.instantiate()
const preitemlist=preload("res://item_list.gd")
@onready var itemlist: preitemlist=$ItemList
@onready var symbol=preload("res://texture_rect.tscn")
var red:LabelSettings= preload("res://labelsettings/wrongstat.tres")
var green:LabelSettings= preload("res://labelsettings/correctstat.tres")
var yello:LabelSettings= preload("res://labelsettings/yellostat.tres")
var greentitle:LabelSettings= preload("res://labelsettings/correct.res")
var redtitle:LabelSettings= preload("res://labelsettings/wrongtitle.res")
@export var chances =5
var emitted:bool = false
@export var awnserfound:bool = false
var awnser
var awnsername:String="blank"
#----------------------------------------------------------------------------------------------------------
#not important
func cascade(count):
var localcount=count
var insymbol=symbol.instantiate()
while localcount!=0:
await get_tree().create_timer(0.5).timeout
$listmenu.add_child(insymbol)
localcount-=1
insymbol=symbol.instantiate()
#----------------------------------------------------------------------------------------------------------
#very important
#check if 0 after
func chancededuct():
chances-=1
if chances <=0 or awnserfound:
chances=0
finishgame()
print("cannot deduct further")
#return
var colors= {"0":Color.WHITE,"1":Color(1.825, 0.399, 0.97),"2":Color(1.825, 0.399, 0.399),"3":Color(1.825, 0.841, 0.186),"4":Color(1.825, 1.801, 0.399),"5":Color(1.326, 1.825, 0.399)}
print("chances" +str(chances))
$chancegauge.frame=chances
$chancebar/chancebargauge.modulate= colors.get(str(chances),Color(1.326, 1.825, 0.399))
$chancebar/chancenumber.text=str(chances)
$chancelabel.text= "5/"+ str(chances)
#if emitted==true :
#return
##else: if chances>0:
##emitted=true
##nomorechances.emit()
#else: if chances <= 0 and not awnserfound:
#emitted=true
#chances=0
#nomorechances.emit()
#very important
func finishgame():
if awnserfound or chances<=0 and awnserfound:
print("correct")
#$listbutton.disabled=true
$chancelabel.disabled=false
$chancelabel.text="continue?"
else:if chances <=0:
print("fail")
#$listbutton.disabled=true
$chancelabel.disabled=false
$chancelabel.text="try again!"
createcard(awnser)
pass
func pickawnser():
# note: awnser used to be the object that was picked with pick_random. now awnser is that objects index.
#if anything goes wrong change it back by unhashtagfiying the old code and hastaging the new code
#also make sure to change all mentions of "comparator" in createcard function to awnser
var awnserindex
awnserindex= randi_range(0,itemlist.all_items.size()-1)
awnser=awnserindex
awnsername=itemlist.all_items.get(awnserindex).name
#awnser= itemlist.all_items.get(awnserindex)
#awnsername=awnser.name
$Label2.text=awnsername
func refill():
for item in $ItemList.all_items:
$ItemList.add_item(item.name,item.icon)
#very very important
func createcard(selectindex):
var comparator=itemlist.all_items.get(awnser)
#if chances <= 0:
#selectindex=awnser
#return
ICcontainer.add_child(card)
var selecteditem
var statlabel:Label=card.get_node("statlabel")
var pointlabel:Label=card.get_node("pointlabel")
var methodlabel:Label=card.get_node("methodlabel")
var namelabel:Label=card.get_node("nameLabel")
var icontexture:TextureRect=card.get_node("icontexture")
for item in itemlist.all_items:
if $ItemList.get_item_text(selectindex)==item.name:
selecteditem=item
namelabel.text=selecteditem.name
if selecteditem.icon.resource_name in ["bbs","recoded"]:
#print(selecteditem.icon.resource_name)
icontexture.texture=selecteditem.icon
icontexture.rotation_degrees= (-135.00+89.00)
#print(icontexture.rotation_degrees)
if selecteditem.icon.resource_name == "unix":
#print(selecteditem.icon.resource_name)
icontexture.texture=selecteditem.icon
icontexture.rotation_degrees= (-135.05+89)
if selecteditem.icon.resource_name == "kh3":
#print(selecteditem.icon.resource_name)
icontexture.texture=selecteditem.icon
icontexture.rotation_degrees= (-140.00+89)
if selecteditem.icon.resource_name == "days":
#print(selecteditem.icon.resource_name)
icontexture.texture=selecteditem.icon
icontexture.rotation_degrees= (0)
#print(icontexture.rotation_degrees)
if selecteditem.icon.resource_name in ["kh1","kh2","ddd"]:
#print(selecteditem.icon.resource_name)
icontexture.texture=selecteditem.icon
icontexture.rotation_degrees= (-45.00+89)
#print(icontexture.rotation_degrees)
else:
icontexture.texture=selecteditem.icon
statlabel.text=str(selecteditem.data.stat)
pointlabel.text=str(selecteditem.data.point)
methodlabel.text=str(selecteditem.data.method)
for game in selecteditem.data.games:
if game == null:
print("NULL GAME TEXTURE in item: ", selecteditem.name)
continue
card.get_node("GridContainer").add_child(logotexture)
var texture_rect = logotexture.get_node("TextureRect")
var outline1 = logotexture.get_node("outline1")
var COLORRECT = logotexture.get_node(".")
texture_rect.texture = game
outline1.texture = game
#outline2.texture = game
#comparisons start here:
if game in comparator.data.games:
#print("item "+ str(selecteditem.name)," game "+ str(game)," game awnser "+ str(itemlist.all_items.get(awnser).data.games))
outline1.modulate = Color.GREEN
else:
outline1.modulate =Color.RED
logotexture = logo.instantiate()
if selecteditem.data.stat == comparator.data.stat:
#statlabel.add_theme_color_override("font_color",green)
statlabel.label_settings = green
else:
#statlabel.add_theme_color_override("font_color",red)
statlabel.label_settings = red
if selecteditem.data.point == comparator.data.point:
#pointlabel.add_theme_color_override("font_color",green)
pointlabel.label_settings = green
else:
#pointlabel.add_theme_color_override("font_color",red)
pointlabel.label_settings = red
if selecteditem.data.method == comparator.data.method:
#methodlabel.add_theme_color_override("font_color",green)
methodlabel.label_settings = green
else:
#methodlabel.add_theme_color_override("font_color",red)
methodlabel.label_settings = red
if selecteditem.name == comparator.name:
namelabel.label_settings = greentitle
else:
namelabel.label_settings = redtitle
if selecteditem.data.stat == null:
statlabel.label_settings = yello
if selecteditem.data.point == null:
pointlabel.label_settings = yello
if selecteditem.data.method == null:
methodlabel.label_settings = yello
card=infocard.instantiate()
var indexx=0
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
#awnser= $ItemList.get_item_text(randi_range(0,$ItemList.item_count-1))
#$Label2.text=awnser
#$TextureRect.rotation_degrees
pickawnser()
print("window size: " + str(get_window().size))
#for item in itemlist.all_items:
#
#createcard(indexx)
#indexx+=1
##print(indexx)
#if indexx > $ItemList.item_count:
#return
cascade(10)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
pass
#if emitted ==true:
#return
#if chances <=0:
#emitted=true
#nomorechances.emit()
#if $ItemList.visible==true or $LineEdit.visible==true:
#$ScrollContainer.release_focus()
func _on_item_list_item_selected(index: int) -> void:
print("selected")
createcard(index)
#fillcard(index)
#print(index)
$ItemList.hide()
$LineEdit.hide()
var tween:Tween= create_tween()
tween.tween_property($listmenu,"global_position",Vector2(0,-646),0.3)
$listmenu.hide()
for child in $listmenu.get_children():
child.queue_free()
var name:String = $ItemList.get_item_text(index)
print("name"+str(name))
if name == " Wooden Stick":
$Label.text="roxas,that's a stick..."
return
if $ItemList.get_item_text(index)!=awnsername:
chancededuct()
$Label.text="wrong"
print("wrong")
$ItemList.clear()
refill()
else:
awnserfound=true
finishgame()
$Label.text="right"
print("right")
$ItemList.clear()
refill()
#pickawnser()
#nomorechances.emit()
#if emitted==false and awnserfound==false:
#chancededuct()
#else:
#return
#func _on_nomorechances() -> void:
#$ItemList.get_v_scroll_bar().hide()
#$ItemList.hide()
#$listbutton.disabled=true
#$LineEdit.editable=false
#$LineEdit.hide()
#$chancelabel.disabled=false
#if awnserfound==true:
#$chancelabel.text="continue?"
#else:
#$ItemList.get_v_scroll_bar().hide()
#$chancelabel.text="try again!"
#createcard(awnser)
#
#for item in itemlist.all_items:
#$ItemList.set_item_disabled(indexx,true)
#indexx+=1
#if indexx >= $ItemList.item_count:
#indexx=0
func _on_chancelabel_pressed() -> void:
get_tree().reload_current_scene()
func _on_listbutton_pressed() -> void:
if $ItemList.visible==false and $LineEdit.visible==false:
$ItemList.show()
$LineEdit.show()
$listmenu.show()
var tween:Tween= create_tween()
tween.tween_property($listmenu,"global_position",Vector2(0,0),0.3)
#cascade(10)
#$ScrollContainer.hide()
else:
$ItemList.hide()
$LineEdit.hide()
#$ScrollContainer.show()