My Player Spawner/Manager has messed up my farming system

Godot Version

4.6

Question

I’ve just started expanding a game from the one scene testing area to one that manages the player globally across multiple maps, but I keep breaking my farming system in one of two ways. Either the Farm Manager can no longer tell what tile the player is standing on, or the tool scripting can’t see the Farm Manager. I’ve tried changing the player back to an actual child of the scene running rather than the manager but the tools scripting (child of player) still cant find the Farm Manager even with an absolute path set.

If you share code, please wrap it inside three backticks or replace the code in the next block:

extends Node #Player Manager Global Script#


const PLAYER_NODE = preload("uid://cdr1qa3m5xq3q")


var player : Player
var player_spawned : bool = false


func _ready() -> void:
	add_player_instance()
	
func add_player_instance():
	player = PLAYER_NODE.instantiate()
	get_tree().current_scene.add_child (player)
	
func set_player_position(_new_pos : Vector2):
	player.global_position = _new_pos


class_name  PlayerTools

extends Node2D

enum Tool {
	WATER_BUCKET,
	SCYTHE,
	SEED,
	HOE
}

var current_tool : Tool
var current_seed : CropData

@onready var farm_manager: FarmManager = %FarmManager


func _ready() -> void:
	current_tool = Tool.HOE
	Global.SetPlayerTool.connect(set_tool)

func set_tool (tool: Tool, seed: CropData):
	current_tool = tool
	current_seed = seed



func _process(delta: float) -> void:
	if Input.is_action_just_pressed("Plant"):
		match current_tool:
			Tool.HOE:
				print("Is my node valid? ", is_instance_valid(farm_manager))
				print("What is inside my variable? ", farm_manager)
				farm_manager.try_till_tile(global_position)
			Tool.WATER_BUCKET:
				farm_manager.try_water_tile(global_position)
			Tool.SCYTHE:
				farm_manager.try_harvest_tile(global_position)
			Tool.SEED:
				farm_manager.try_seed_tile(global_position, current_seed)


class_name FarmManager #Controls Tile Types#

extends Node




enum TileType {
	
	GRASS,
	TILLED,
	TILLED_WATERED,
	NO_TILL
}

class TileInfo:
	var tilled: bool 
	var watered: bool
	var crop : PlanterCrop
	
@onready var tile_map_layer: TileMapLayer = $FarmTile








var tile_info : Dictionary[Vector2i, TileInfo]
var crop_scene : PackedScene = preload("res://Assets/Scenes/Harvestables/planter_crop.tscn")

var tile_atlas_coords : Dictionary[TileType, Vector2i] = {
	TileType.GRASS: Vector2i(1,1),
	TileType.TILLED: Vector2i(3,1),
	TileType.TILLED_WATERED: Vector2i (4,1),
	TileType.NO_TILL: Vector2i(0,1)
}





# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	
	Global.NewDay.connect(_on_new_day)
	Global.HarvestCrop.connect(_on_harvest_crop)

	for cell in tile_map_layer.get_used_cells():
		tile_info [cell] = TileInfo.new()

#Custom Functions#

func _on_new_day (day: int):
	for tile_pos in tile_map_layer.get_used_cells():
		if tile_info[tile_pos].watered:
			_set_tile_state(tile_pos, TileType.TILLED)
		elif tile_info[tile_pos].tilled:
			if tile_info[tile_pos].crop == null:
				_set_tile_state(tile_pos, TileType.GRASS)

func _on_harvest_crop (crop: PlanterCrop):
	tile_info[crop.tile_map_coords].crop = null
	_set_tile_state(crop.tile_map_coords, TileType.TILLED)
	
	
func try_till_tile (player_pos: Vector2):
	print("tilled")
	var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
	print(player_pos)
	
	if tile_info[coords].crop:
		return
	if tile_info[coords].tilled:
		return
	_set_tile_state(coords,TileType.TILLED)
	
func try_water_tile (player_pos: Vector2):
	
	#Get player Position
	var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
	
	#Check if Tilled#
	if not tile_info[coords].tilled:
		return
		
		#Otherwise Water#
	_set_tile_state(coords, TileType.TILLED_WATERED)

	
	#Also water plant#
	if tile_info [coords].crop:
		tile_info [coords].crop.watered = true
		
	
func try_seed_tile (player_pos: Vector2, crop_data : CropData):
	var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
	
	#Only plant on tilled#
	if not tile_info[coords].tilled:
		return
		
	#Can't plant new seed on tile#
	if tile_info[coords].crop:
		return
	
	if Global.owned_seeds[crop_data] <= 0:
		return
	
	var crop: PlanterCrop = crop_scene.instantiate()
	add_child(crop)
	crop.global_position = tile_map_layer.to_global(tile_map_layer.map_to_local(coords))
	
	#Call Function located in Planter Crop Scripting#
	crop.set_crop(crop_data, is_tile_watered(coords), coords)
	tile_info[coords].crop = crop
	
	Global.consume_seed(crop_data)
	#Remove Seeds Here#
	
	
func try_harvest_tile (player_pos: Vector2):
	var coords: Vector2i = tile_map_layer.local_to_map(player_pos)
	
	if not tile_info[coords].crop: #Dont check unplanted cells#
		return
		
	if not tile_info[coords].crop.harvestable: #Only harvest when ready#
		return
		
	Global.harvest_crop(tile_info[coords].crop)
	tile_info[coords].crop = null
	
	
func is_tile_watered (pos: Vector2) -> bool:
	var coords := tile_map_layer.local_to_map(pos)
	return tile_info[coords].watered

func _set_tile_state (coords: Vector2i, tile_type: TileType): 
	tile_map_layer.set_cell (coords,0, tile_atlas_coords[tile_type])
	

	match tile_type:
		TileType.GRASS:
			tile_info[coords].tilled = false
			tile_info[coords].watered = false
		TileType.TILLED:
			tile_info[coords].tilled = true
			tile_info[coords].watered = false	
		TileType.TILLED_WATERED:
			tile_info[coords].tilled = true
			tile_info[coords].watered = true
			

When does the problems occur? When you are first spawning in the player or later when you respawn it?

Do you get any error messages?

Do any line of your code get highlighted?

What changes have you made since it worked properly?

If it crashes instantly on boot, it could be that you spawn one node in before the other and that when you run _ready() in it, the other is not yet available.

Try using unique name instead of a nodepath, or at least double checking if the nodepath is still correct. Its easy to forget updating a nodepath after changing the placement of a node in the scene tree.

Also, try to avoid copy pasting in entire scripts in like this when you need help. Its just a waste of time to have to read through how you flip a sprite or how you water a plant, when that is not what casues problems. I didnt read anything in your script. Take a few minutes extra to make it easier for people to understand your problem or you will not get as helpful replies. If you dont know which part of your scripts are relevant, it is fine, but then try to make simpler scripts until you improve enough to understand more about what you are doing.