+1 vote

I have an Actor class and a Controller class. Each actor has a controller which may either be the player or an AI.

I've started with this:

# actor.gd
# Scene has a child Controller node
extends Node2D

class_name Actor

onready var controller : Controller = $Controller

func _process(delta: float) -> void:
    controller.run(self, delta)

----

# controller.gd
# Subclassed for different behaviour. i.e. Player control and different AI types
extends Node

class_name Controller

func run(actor: Actor, delta: float) -> void:
    ...

But this causes a cyclic dependency error.
How else should I arrange this?

(I've considered that making controllers the parents of actors is an option, but that wouldn't be feasible for me. It's the actors that get placed in the level, and I'd want to be able to take an actor and change what controller it has.)

in Engine by (63 points)

2 Answers

+1 vote
Best answer

After discussing this elsewhere, the conclusion is to not specify types where they'd cause cyclic dependencies.

# controller.gd
# Same as before

class_name Controller

func run(actor: Actor, delta: float) -> void:
    ...

---

# actor.gd
extends Node2D

class_name Actor

onready var controller = $Controller # Type not specified

func _process(delta: float) -> void:
    controller.run(self, delta)

This is actually similar to what's done in the GDQuest OpenRPG project. In combat scenes there are Battlers that have BattlerAIs. Battlers have a variable for their BattlerAI but they don't specify its type.

# CombatArena.gd
extends Node2D
class_name CombatArena

...

func play_turn():
    var battler : Battler = get_active_battler()
    var targets : Array
    var action : CombatAction
    ...
    action = yield(battler.ai.choose_action(battler, opponents), "completed")
    targets = yield(battler.ai.choose_target(battler, action, opponents), "completed")
    ...

---

# BattlerAI.gd
extends Node
class_name BattlerAI

func choose_action(actor : Battler, battlers : Array = []):
    ...

func choose_target(actor : Battler, action : CombatAction, battlers : Array = []):
    ...

---

# Battler.gd
extends Position2D
class_name Battler

...

onready var ai = $AI # Not typed

...
by (63 points)
edited by

Any way to get "jump to declaration / definition" working without specyfing of the class?

0 votes

Hi, until now I have used the below recommendation. To simply avoid this issue.

This week I noticed not to have this error when creating the parent or referred class in a different folder.

Folder
L baseclass.GD
L Folder
| L ExtendedClass.GD #extends baseclass
...

by (14 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories