I am trying to sort my inventory items by name. All routes I take result in an error that I cannot figure out, not all errors being the same. I am a few months in and slowly understanding gdscript. Any help would be appreciated!
My inventory is fully functional, including adding items, removing items, splitting stacks, etc. Just trying to add a sort function now.
The inventory array is of “SlotData” resource (contains quantity and ItemData resource)
ItemData resource contains name, texture, and other item linked variables.
Typically when accessing the name I would use “slot_data.item_data.name”
My current code (generated from Google AI overview)
@export var slots : Array [SlotData]
func sort_by_name_trigger(): #triggered by the "y" key to start sorting
slots.sort_custom(_sort_slots_by_item_name)
func _sort_slots_by_item_name(slot_a: SlotData, slot_b: SlotData) -> bool:
if slot_a.item_data and slot_b.item_data:
return slot_a.item_data.name < slot_b.item_data.name # Sort ascending by name
elif slot_a.item_data:
return true # Slot with item comes before empty slot
else:
return false # Empty slot comes after slot with item
currently I am getting an error, and I am assuming it is trying to access a null reference.
(Invalid access to property or key ‘item_data’ on a base object of type 'Nil)
There are 7 of the 40 slots containing items of varying types.
Your sorting functions looks good. I reckon it’s the SlotData that’s throwing the error. Debug your datatype. I think it’s likely that an empty slot is trowing the NULL. Make sure that empty slots are also a SlotData object, or change the logic to checks is SlotData exists before accessing .item_data.
Thanks for the reply! After posting this, I noticed slot_b was null, causing the error. I couldn’t get back on to add it to the original message, as It was pending approval, being my first post. I will say all slots are null unless there was an item located at that slot. See print out of the first 10 slots below, as the rest of the 40 slots are null. Note that the 5 null slots do not show up on the forum message, but are there.
I’m assuming I should add another if statement to say if == null then “do something”? In that case I can try the following (guessing, as I am still not real familiar of how the custom sort works yet)
if a == null and b != null then b < a (sends a to the end of the list)
if a != null and b == null then b > a (sends b to the end of the list)
if a == null and b == null then a > b (as it don’t matter which is listed first)
I prefer not to write data in my empty slots, as this is how the code knows where items are.
What does SlotData contain? You need to check if slot_a is null, can slot_a.item_data ever be null? If not then you could use this to check for null elements in the array.
func _sort_slots_by_item_name(slot_a: SlotData, slot_b: SlotData) -> bool:
if slot_a and slot_b:
return slot_a.item_data.name < slot_b.item_data.name # Sort ascending by name
elif slot_a:
return true # Slot with item comes before empty slot
else:
return false # Empty slot comes after slot with item
I am assuming it steps through all the slots and compares them to the next slot. In this case, if there are empty slots scattered in the inventory anywhere, you could have either a or b null and any time.
This works, adding slot_a and slot_b to the beginning, to verify they are both not null, then adding slot_a and !slot_b to the elif statement:
if slot_a and slot_b and slot_a.item_data and slot_b.item_data:
return slot_a.item_data.name < slot_b.item_data.name # Sort ascending by name
elif slot_a and !slot_b and slot_a.item_data:
return true # Slot with item comes before empty slot
else:
return false # Empty slot comes after slot with item