Better Way to do weapon stats

Godot Version

v4.7

Question

Hi, I have created a global stat that has info for my weapons, however, I was wondering if there was a better way it implementing it.

I feel that if I implemented more to it, something might break, like the id. I tried grabbing the key from the dictionary without using a for loop, but I couldn’t figure out how.

This is the global script. GlobalRangeStats

extends Node

var range_held : int = 0
var range_name : String = "Pistol"

# Key, value
# Has player bought/unlocked
var range_unlock : Dictionary = {
	"Pistol": true,
	"Rifle": false,
	"Fast Shooter": false,
}

# Range items
var range_items = {
	0: {"Damage": 1, "Attack Speed": 1.0, "Pierce": 0, "Name": "Pistol",},
	1: {"Damage": 3, "Attack Speed": 2.0, "Pierce": 1, "Name": "Rifle",},
}

extend Resources

extends Resource
class_name RangeData

@export var name: String
@export var damage: int
@export var attacK_speed: float
@export var pierce: int

With a custom resource you can create resources in the filesystem for each of your weapons, and load them like other resources.

Question:

How would that work for the inventory? Also selecting the weapon? And adding more items?

The code below is a mock up. The script is attached to Node 2d. I also have an Button Option.

extends Node2D

@export var rangestats : RangeResource

@onready var option_button: OptionButton = $OptionButton

func _ready() -> void:
	# Clear to prevent repeats
	option_button.clear()
	# If player has bought/unlocked, then add to OptionButton
	for weapon in GlobalRangeStats.range_unlock:
		if GlobalRangeStats.range_unlock[weapon] == true:
			option_button.add_item(rangestats.name)
	
func _on_option_button_item_selected(index: int) -> void:
	pass

Depends on your inventory system.

Depends on your weapon selection system.

You can create more weapons by right clicking the filesystem and picked “New Resource” you can also create resource at run time with WeaponData.new()


I don’t know what the code is supposed to do, if you used resources I believe it would compile and run. My sample even has a .name property. The range_unlock can use Resources as keys, but I’d recommend a more base type, even the path of the resource may prove more useful and performant.

Resources are very similar in function to Dictionaries, but they have many more underlying systems that aid in development.

I’m confused by what you said. Mostly how to get the values.

So, for example. Pistol has 1 damage. Rifle has 3. How do I get these values? How to I switch from one to another?

I also don’t want to create a lot of resources. I won’t be making that many weapons, but it feels tedious. Also, how would you get resource if each one is named differently?

I was thinking of changing name : String to name : Array then adding the names to the array. However, something about that feels wrong?

var my_gun: RangeData = load("res://pistol.tres")
print(my_gun.damage) # 1

my_gun = load("res://rifle.tres") # changed to rifle
print(my_gun.damage) # 3

To me, it feels like less work and importantly less error-prone than filling in dictionaries.

I’m not sure how this would apply, seems like one weapon should have one name, not an array of names.

Alright, it’s working. Thank you!