Godot Version
Godot 4.6.1
Issue
I’m trying to utilize exported variables to make my project easy to modify and add stuff for in the future. If possible, I want to be able to assign all of the data in the Inspector to quickly make a new instance of an object.
However, when I change my Resource structure just a little bit, it starts to cause the error shown above, and I can’t find out why my resources stop importing properly and how to fix it.
Details
- The data causing this error:
- BeastCore (Resource): Contains immutable data, made to be saved to define the very core of the instance.
- BeastData (Resource): Contains mutable data, that helps make each monster instance unique (like stats). Has an exported variable that holds the immutable data.
- Beast (Node): A custom-defined extension of Node that, when initialized (the initialization requires Monster Data as an argument), contains all the relevant data for other scripts/nodes to access. I am trying to remove this node, now that I know the data can be properly initialized within the Resource.
- Battle Entity (New Resource): An empty resource class. I’m trying to make BeastData and another resource extend this resource, for organization. I want my enemy’s exported enemy_data variable to only accept a Battle Entity, so that I’m limited to selecting extended Resources that are made to work with that specific node.
- Enemy (Node): Holds the data and assigns the variables accordingly, based on what exported variable is returned. I am giving that variable BeastData.
- When the exact project folder is copied over from my desktop, the project works just fine.
- Any changes that I make to the resource structure will cause Godot to never show the imported data in the Stack Frames, even though I have it correctly set within the exported variable.
- Issues with resources not properly imported only started recently, when I was having some issues with managing a bare git repository I use to hold my project between computers. I’m not sure if this can cause something like this to happen with Godot?
- The Enemy Script (Original):
extends Node2D
@export var enemy_data: Resource
var active_beast: Beast
## Assigns itself the beast data, depending on if the enemy is a trainer with multiple beasts, or just a wild beast.
var enemy_beast: BeastData
func _ready() -> void:
# Get the data either the beast as a wild beast, or the first beast in a trainer's party for a trainer battle.
if enemy_data is Trainer:
enemy_beast = enemy_data.party[0]
elif enemy_data is BeastData:
enemy_beast = enemy_data
# If the resource type is unrecognized, do not continue loading a sprite.
else:
printerr("Unrecognized resource type. Can only load a Trainer for a trainer battle, or a Beast for a wild beast battle.")
get_tree().quit(1)
# Set the beast's data.
set_active_beast(enemy_beast)
@onready var health_bar_size = $BattleUI/HealthBar.size.x
func set_active_beast(beast_data: BeastData) -> void:
if active_beast: active_beast.queue_free()
active_beast = Beast.new(beast_data)
$BeastSprite.texture = active_beast.sprite
$BattleUI/NameTag.set_text(active_beast.beast_name + " lv. " + str(active_beast.level))
- The Beast Script (Original):
class_name Beast extends Node
var beast_name: String
var sprite: Texture
var max_health: int
var current_health: int
var level: int
var speed: int
var learned_attacks: Array[Attacks]
var beast_data: BeastData
func _init(new_beast: BeastData) -> void:
beast_data = new_beast
beast_name = new_beast.nickname if new_beast.nickname else new_beast.beast_core.name
sprite = new_beast.beast_core.sprite
max_health = new_beast.max_health
current_health = new_beast.current_health
level = new_beast.level
speed = new_beast.speed
learned_attacks = new_beast.learned_attacks
- Beast Data Script (Original):
## The beast's data. Wraps around the core to provide mutable data like stats, health, and experience, to make the beast whole.
class_name BeastData extends Resource
## The very bare minimum data that defines the beast. This data stays the same between any of the same beast.
@export var beast_core: BeastCore
## The beast's max health.
@export var max_health: int = 100
## The beast's current health.
var current_health: int = max_health
## The beast's level.
@export var level: int
## The beast's speed. Determines which beast goes first.
@export var speed: int
## The 4 attacks this beast currently knows.
@export var learned_attacks: Array[Attacks]
@export var nickname: String
- The Enemy Script (Changed):
extends Node2D
@export var enemy_data: BattleEntity
var active_beast: BeastData
func _ready() -> void:
## Assigns itself the beast data, depending on if the enemy is a trainer with multiple beasts, or just a wild beast.
var enemy_beast: BeastData
# Get the data either the beast as a wild beast, or the first beast in a trainer's party for a trainer battle.
if enemy_data is Trainer:
enemy_beast = enemy_data.party[0]
elif enemy_data is BeastData:
enemy_beast = enemy_data
# If the resource type is unrecognized, do not continue loading a sprite.
else:
printerr("Unrecognized resource type. Can only load a Trainer for a trainer battle, or a Beast for a wild beast battle.")
get_tree().quit(1)
# Set the beast's data.
set_active_beast(enemy_beast)
@onready var health_bar_size = $BattleUI/HealthBar.size.x
func set_active_beast(beast_data: BeastData) -> void:
active_beast = beast_data
$BeastSprite.texture = active_beast.sprite
$BattleUI/NameTag.set_text(active_beast.name + " lv. " + str(active_beast.level))
- Beast Data (Changed, Replacing Beast):
## The beast's data. Wraps around the core to provide mutable data like stats, health, and experience, to make the beast whole.
class_name BeastData extends BattleEntity
## The very bare minimum data that defines the beast. This data stays the same between any of the same beast.
@export var beast_core: BeastCore
## The beast's max health.
@export var max_health: int = 100
## The beast's current health.
var current_health: int = max_health
## The beast's level.
@export var level: int
## The beast's speed. Determines which beast goes first.
@export var speed: int
## The 4 attacks this beast currently knows.
@export var learned_attacks: Array[Attacks]
@export var nickname: String
var name: String
func _init(new_beast_core: BeastCore, new_max_health: int = 100, new_current_health: int = new_max_health, new_level: int = 1, new_speed: int = 1, new_learned_attacks: Array[Attacks] = [], new_name: String = ""):
beast_core = new_beast_core
name = nickname if nickname else beast_core.name if beast_core.name else new_name
max_health = new_max_health
current_health = new_current_health
level = new_level
speed = new_speed
learned_attacks = new_learned_attacks
## Sets the health for the specified beast.
func set_health(health_bar: Node, max_bar_size: float, new_health: int) -> void:
if new_health >= max_health: current_health = max_health
else:
current_health = new_health
health_bar.size.x = (current_health * max_bar_size)/max_health
- Battle Entity Script (New):
class_name BattleEntity extends Resource
If you are experienced with Godot and/or Resources, may you assist with this? I don’t know if this is an error I caused and failed to understand, or if there actually is something wrong with my Godot. I created an account just to ask this, I’ve literally never been stumped so badly by an error before.
Thank you!

