Procedural Generation - Instancing

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

I am trying to create procedural generation for my game. Essentially what I want is, an island will spawn, and below that, a random island would spawn, and below that, a random island would spawn, etc. The way I am trying to do this is by choosing a random number and instancing a scene based on the number. Island1 can instance island2, which can instance island1 and island 3, and island 3, which can instance island1 and island2. I’ll eventually add more islands, but at the moment I’m trying to figure out procedural generation first. This isn’t working - it will always display an error saying I can’t preload a certain island. I’m guessing that preload can’t load the node that is calling it or parents of the node that is calling it, so I tried doing get_parent().add_child() instead, which yielded the same results. Can someone help me?

are you able to upload the project files? it’s hard to say without seeing what is actually going on.

Eric Ellingson | 2019-07-28 22:29

Sure. I don’t think it’s a problem with the files, though. Like I said before, as far as I can tell, preloading does not work if you are trying to preload the node the script refers to, or a parent of that node - I just need to find a work-around to this.
Anyways, here are the files:
Bad Egg – Google Drive

ThreeSpark | 2019-07-28 22:56

:bust_in_silhouette: Reply From: Eric Ellingson

You can just change preload to load and it works fine, but I did the following:

[1] Add an autoloaded script (see Singletons (AutoLoad) — Godot Engine (3.1) documentation in English if you’re not familiar) called Islands.gd that looks like this:

# Islands.gd
extends Node

var island1 = preload("res://procgen/nodes/island1.tscn")
var island2 = preload("res://procgen/nodes/island2.tscn")
var island3 = preload("res://procgen/nodes/island3.tscn")

[2] Change your island scenes to reference that autoloaded script:

# island1.gd
extends Node2D

var dir = 200

func _ready():
	randomize()
	var choice = rand_range(2, 3)
	var rounded_choice = int(round(choice))
	if rounded_choice == 2:
		var i = Islands.island2.instance()
		i.position = Vector2(position.x, position.y + dir)
		get_parent().add_child(i)
		get_parent().get_node("Player").position = i.position
	if rounded_choice == 3:
		var i = Islands.island3.instance()
		i.position = Vector2(position.x, position.y + dir)
		get_parent().add_child(i)
		get_parent().get_node("Player").position = i.position

func _process(delta):
	var up = Input.is_action_pressed("ui_up")
	var down = Input.is_action_pressed("ui_down")