How do I access an arrays values from a seperate script that is a class

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dragon20C

This is the first time working with a class I am having issues understanding on how to use them correctly I have a class that is storing an array, and I want my other scripts to look up values from them but when I try to access a value from it, it says invalid get index “chart” base on gdscript,

here is the code:

extends Node
class_name TypeChart


var chart = [#   Nor   Fir   Wat   Ele   Gra   Ice   Fig   Poi   Gro   Fly   Psy   Bug   Roc   Gho   Dra   Dar  Ste    Fai
	#Normal
	[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.5, 0, 1, 1, 0.5],
	#Fire
	[1, 0.5, 0.5, 1, 2, 2, 1, 1, 1, 1, 1, 2, 0.5, 1, 0.5, 1,2, 1],
	#Water
	[1, 2, 0.5, 2, 0.5, 1, 1, 1, 2, 1, 1, 1, 2, 1, 0.5, 1, 1],
	#Electric
	[1, 1, 2, 0.5,0.5, 2, 1, 1, 0, 2, 1, 1, 1, 1, 0.5, 1, 1],
	#Grass
	[1, 0.5, 2, 1,  0.5, 1, 1, 0.5, 2, 0.5, 1, 0.5, 2, 1, 0.5, 1, 0.5, 1],
	#Ice
	[1, 0.5, 0.5, 1, 2, 0.5, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 0.5, 1],
	#Fighting
	[2, 1, 1, 1, 1, 2, 1, 0.5, 1, 0.5, 0.5, 0.5, 2, 0, 1, 2, 2, 0.5],
	#Poison
	[1, 1, 1, 1, 2, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 0, 2],
	#Ground
	[1, 2, 1, 2, 0.5, 1, 1, 2, 1, 0, 1, 0.5, 2, 1, 1, 1, 2, 1],
	#Flying
	[1, 1, 1, 0.5, 2, 1, 2, 1, 1, 1, 1, 2, 0.5, 1, 1, 1, 0.5, 1],
	#Psychic
	[1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0.5, 1, 1, 1, 1, 0, 0.5, 1],
	#Bug
	[1, 0.5, 1, 1, 2, 1, 0.5, 0.5, 1, 0.5, 2, 1, 1, 0.5, 1, 2, 0.5, 0.5],
	#Rock
	[1, 2, 1, 1, 1, 2, 0.5, 1, 0.5, 2, 1, 2, 1, 1, 1, 1, 0.5, 1],
	#Ghost
	[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.5, 1, 1, 2, 1, 0.5, 1, 1],
	#Dragon
	[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0.5, 0],
	#Dark
	[1, 1, 1, 1, 1, 1, 0.5, 1, 1, 1, 2, 1, 1, 2, 1, 0.5, 1, 0.5],
	#Steel
	[1, 0.5, 0.5, 0.5, 1, 2, 1, 1, 1, 1, 1, 2, 0.5, 1, 1, 1, 0.5, 2],
	#Fairy
	[1, 0.5, 1, 1, 1, 1, 2, 0.5, 1, 1,  1, 1, 1, 1, 2, 2, 0.5, 1]
	]

A simple separate script
and this is where I use the class name to try to access the array

func Get_effectiveness(attack_type,defence_type):
	if attack_type == Types.monster_type.none or defence_type == Types.monster_type.none:
		return 1
	var row : int = attack_type
	var col : int = defence_type
	print("row : " + str(row))
	print("col : " + str(col))
	return TypeChart.chart[row][col]
:bust_in_silhouette: Reply From: timothybrentwood

Either create a Singleton out of it (recommended ONLY FOR STATIC VALUES if you are just starting to program): Singletons (Autoload) — Godot Engine (stable) documentation in English

Then you can access it from anywhere in your script using TypeChart.chart. Otherwise you’ll need to instance(? generally what it’s called in other programming languages, but Godot makes a distiction) it in order to access it:

const LTypeChart = load("res://TypeChart.gd") # your path may differ
var type_chart_instance
func _ready():
    type_chart_instance = LTypeChart.new() # i think _ready() will not run but _init() will

func cool_function():
    do_cool_stuff()
    move.type_array = type_chart_instance.chart[3]

But regardless of which way you do it, please use a Dictionary with constants for keys over an array. XD

extends Node
class_name TypeChart

const TYPE_KEY_FIRE = "fire"
const TYPE_KEY_NORMAL = "nor"
const TYPE_KEY_WATER = "wat"

var CHART: Dictionary = {
    TYPE_KEY_FIRE : { TYPE_KEY_FIRE : 1, TYPE_KEY_NORMAL : 1, TYPE_KEY_WATER: 0.25},
    TYPE_KEY_NORMAL : { TYPE_KEY_FIRE : 1, TYPE_KEY_NORMAL : 1, TYPE_KEY_WATER: 1},
    TYPE_KEY_WATER: { TYPE_KEY_FIRE : 2, TYPE_KEY_NORMAL : 1, TYPE_KEY_WATER: 1},
}
# example usage getting fire's effectiveness vs water:
TypeChart.CHART.get(TypeChart.TYPE_KEY_FIRE).get(TypeChart.TYPE_KEY_WATER)

I know it seems like a lot of work for not much gain, but it’s wayyyyyy worth it not to have to memorize which type is at which index for 18 different types. IMO your get_effectiveness() function should live in your TypeChart class - it’s a perfect candidate. And if you go the Singleton route consider naming your TypeChart class something more generic like DataBase, or Globals, or CONSTANTS and using it for more things.

Honestly I have it as a singalton it was the only way I could think of access this array and you mention changing it to a dictionary, I find dicts hard to use , plus I have it like this simply because effectiveness compares two values and finds the corresponding value to both

Dragon20C | 2021-05-07 13:19

Dictionaries are very much your friend when creating maps between things. (Type -> Type -> Effectiveness)

I’m thinking about when you create moves: move.type = 5 is WAY less readable and more prone to typing (as in keyboard) errors than move.type = TypeChart.TYPE_KEY_FIRE. Godot will also give you the auto-completion for TYPE_KEY_FIRE when you start typing it making it super convenient to use.

5 would be what’s referred to has a magical number - they are evil and should be avoided at all costs. Any number that exists in code besides 0 (or in some cases -1) should be accessed via a variable. Trivial example, but what’s more readable at a glance?

if index == -1:
   do_something()

or

const NOT_FOUND = -1
if index == NOT_FOUND:
    do_something()

timothybrentwood | 2021-05-07 13:55

At the very least consider using an enum to access your array:

class_name TypeChart
enum TYPE { NORMAL = 0,
FIRE, WATER, ELETRIC, GRASS,...., FAIRY}
chart[TYPE.NORMAL][TYPE.WATER] # same thing as chart[0][2]

or from outside of the class:

move.type = TypeChart.TYPE.ELECTRIC # move.type set to 3

timothybrentwood | 2021-05-07 14:10