Storing variables in a dictionary?

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

I’m working on a level generator node. I have a function which performs weighted choosing with given dictionaries based on their key values.

var obstacles = {"obstacle01": 15, "obstacle02": 4, "obstacle03": 1}

So basically my function returns the string “obstacle01” 15 times out of 20. I want to instance scenes based on function’s picks. How can convert these strings to a path variable?

I’m not sure I understand your question. If the strings represent scene resources that already exist in your file system, say:

  • res://
    • obstacles
  • obstacle01.tscn
  • obstacle02.tscn

you can construct your paths as a string from the fixed location where they’re saved:

var path = 'res://obstacles/%s.tscn' % obstacle_name

pouing | 2021-10-24 01:16

Yes, that’s exactly what I was asking. Although this method works for me, it takes too much memory to reload the path for each selection. It would be nice to match the outputs of the function with a predetermined constant.

onready var Obstacle01 = preload("res://Resources/Floaters/rock01.tscn")
onready var Obstacle02 = preload("res://Resources/Floaters/rock02.tscn")
onready var Obstacle03 = preload("res://Resources/Floaters/rock03.tscn")

I have these in my hand. But I can’t I can’t perform the conversion from String to variable name. str2var doesn’t work.

Martik | 2021-10-24 10:14

:bust_in_silhouette: Reply From: skysphr

You could simply have an obstacle map that maps resource names to data:

var obstacle_map = {
   "obstacle01": preload("res://Resources/Floaters/rock01.tscn"),
   "obstacle02": preload("res://Resources/Floaters/rock02.tscn"),
   "obstacle03": preload("res://Resources/Floaters/rock03.tscn")
}

var pick_list = []
var obstacles = {"obstacle01": 15, "obstacle02": 4, "obstacle03": 1}
for i in obstacles:
    for _n in obstacles[i]:
        pick_list.append(i)
pick_list.shuffle()
var pick = pick_list[0]
var new_item = obstacle_map[pick].instance()

Edit: Misunderstood the initial question and edited the answer accordingly.

This is a good alternative for my weighted picking algorithm so thank you for that but I already have one. What I’m asking is to match the picks of the function with a predetermined constant

onready var Obstacle01 = preload("res://Resources/Floaters/rock01.tscn")
onready var Obstacle02 = preload("res://Resources/Floaters/rock02.tscn")
onready var Obstacle03 = preload("res://Resources/Floaters/rock03.tscn")

like these. So I can Instance them to my scene without too much memory consumption.

Edit: New solution is very efficient, cheers!

Martik | 2021-10-24 16:14