Godot Version
v4.4.1.stable.official.49a5bc7b6
Question
I’m working on a project, currently trying to write some functionality into my scripting to support evaluation of precondition checks to see if instantiation of relevant objects is allowed. It’s not very relevant to the issue, but just for a matter of framing, I’ll share a brief description:
- The game is an RTS game, and among other things, the player can build
Structure
s in the game world - The validity of structure placement depends on 1) the structure in question, 2) the potential position of the structure, etc. for example, a given structure might only be buildable where there are resources
- The structures are packed as scenes, to be instantiated and positioned after the player issues the command
- I’ve put the logic for checking the validity of a structure’s placemnet in a class relevant to the structure type, and unfortunately it’s not straightforward to access the member functions of the relevant type, so I’m writing static functions to perform the checks, and I have enums that point to the validity-checking-functions, packed scenes, etc. relevant to the structure in question.
So, there’s the explanation of why my code is structured in the manner that it is. Now, in order to facilitate the passing around of the structure
properties, I made a StructureSpec
class to hold references to specifics of certain structures, and I have a dictionary mapping the enumerated Structure
types to their specs. I think the failure in my code starts around here:
- I have class definitions for different types of units, structures, etc. in my game
- Different unit types will have different types of commands that they can receive, and for that reason, I’ve defined static functions and objects which track valid commands for the different unit types. Some child classes basically have a superset of the capabilities of their parent classes, so I access the static references of the parent classes to aggregate them with other logic.
- The above was working completely fine, but when I added the
StructureSpec
implementation to my project, I found that the accessing of the just mentionedstatic
references suddenly returnednull
values. - In my probing around, I specifically found that the issue occurs when I pass around references to the
Script
s that implement theStructure
s that I’ve been discussing. In the snippet below, note that the existing definition ofstructure_type_spec_map
fails to run, but the commented-out version runs without issue:
class_name StructureSpec
var cube_grid_arrangement: Array
var type: Script
func _init(
a_script: Variant,
a_cube_grid_arrangement: Array
) -> void:
type = a_script
cube_grid_arrangement = a_cube_grid_arrangement
static var structure_type_spec_map: Dictionary[int, StructureSpec] = {
Structure.Type.MINE: StructureSpec.new(Mine, [Vector3i.ZERO]),
Structure.Type.DWELLING: StructureSpec.new(Structure, [Vector3i.ZERO]),
Structure.Type.OUTPOST: StructureSpec.new(Outpost, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1), Vector3i(0,-1,1), Vector3i(0,1,-1), Vector3i(1,0,-1), Vector3i(1,-1,0)]),
Structure.Type.LAB: StructureSpec.new(Lab, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1)]),
Structure.Type.COMPOUND: StructureSpec.new(Structure, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1)]),
Structure.Type.ARMORY: StructureSpec.new(Structure, [Vector3i.ZERO])
}
#static var structure_type_spec_map: Dictionary[int, StructureSpec] = {
#Structure.Type.MINE: StructureSpec.new(null, [Vector3i.ZERO]),
#Structure.Type.DWELLING: StructureSpec.new(null, [Vector3i.ZERO]),
#Structure.Type.OUTPOST: StructureSpec.new(null, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1), Vector3i(0,-1,1), Vector3i(0,1,-1), Vector3i(1,0,-1), Vector3i(1,-1,0)]),
#Structure.Type.LAB: StructureSpec.new(null, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1)]),
#Structure.Type.COMPOUND: StructureSpec.new(null, [Vector3i.ZERO, Vector3i(-1,1,0), Vector3i(-1,0,1)]),
#Structure.Type.ARMORY: StructureSpec.new(null, [Vector3i.ZERO])
#}
- Because of this, I believe that my project throws an error, where my
static
field returns null, due to some sort of circular initialization.
I’m not really sure what’s going on, but I’d appreciate if somebody could describe the issue I’m seeing, with any direct methods of addressing it!
Maybe some refactoring is in order to avoid this situation to begin with, but that would be a way longer discussion.