I've run into yet another weird instance of circular references in gdscript. I'll probably put in an issue if I can figure out how to make a minimal project out of it, but I thought I'd look for input first.

I've got an inheritance structure that looks like this.

Entity
  Creature
    Player

Each entity, including the player is a Node2D, child of the Dungeon (tilemap). When I check (in Entity) whether an object is an instance of Dungeon, it causes parser errors. Note that this is while running the project from the editor, but the project never reaches the execution stage.

func _ready():
	var my_parent = get_parent()
	if my_parent is Dungeon:
		pass

SCRIPT ERROR: Compile Error: Identifier not found: grid_position
          at: GDScript::reload (res://player.gd:36)

grid_position is a parameter of Entity, which should be inherited by Player. The double-inheritance can't be traced by the parser, but it can be traced by the editor, which has no problem autocompleting the parameters. There are no errors in the editor.

Now, if I just use a parameter to determine whether it's a dungeon, everything works fine.

func _ready():
	var my_parent = get_parent()
	if my_parent.get('is_dungeon'):
		pass

If anyone is really interested, the code is here, but it may give you a headache.

I bet c# doesn't have these issues. 🙂

Edit: The problem is likely due to a similar line in Dungeon checking if an object "is Entity", causing a circular reference.

    duane Each entity, including the player is a Node2D, child of the Dungeon (tilemap).

    Any particular reason you want to have them as children of the Dungeon tilemap?

    Might it not be better to have specific spawners as children of the tilemap instead and they would spawn(instantiate) the entities in their own respective branches of the scene tree?

      duane Is this Godot 3 or 4?

      When I check (in Entity) whether an object is an instance of Dungeon

      Shouldn't that be either "child of Dungeon" or "instance of Entity"?

      Oh alright, if my_parent is Dungeon:, child of Dungeon.

      Weird, looks indeed fine to me so far.

      Yeah seems like probably the two scripts are having GDScriptCompiler::_parse_expression called on each other at the same time in a bad way, but that's gonna require some stack-tracing if anyone wants to untangle it. Cyclic references are supposedly okay as of this PR which went into 4.0, and you're on 4.1, so it's supposed to be fine. I can't find any open issues related, so probably worth reporting.

      • Toxe replied to this.

        award and you're on 4.1

        Oh right, it says the version right inside the project file. I could have checked there first.

        You should probably refactor the whole thing so there is no need at all for any of those is X checks.

        Megalomaniak Any particular reason you want to have them as children of the Dungeon tilemap?

        That's just so they move with the tilemap. I'm going to have a spawner, but in the last version I still left them children of Dungeon. They're spawned randomly and all treated the same, so I'm not sure what advantage there would be to splitting them up. Keeping them as the only children of a node would mean I didn't have to check their identity, though.

        After reading these posts, I'm starting to think I should have a controller node that owns the tilemap, the entities, and the MapMaker class that builds the dungeon. Everything is very tightly coupled at the moment, but it's hard to see how to fix that. They have to be able to interact with each other and the dungeon constantly.