Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove actor parameter in behavour's in favor of something else #61

Closed
Shadowblitz16 opened this issue Dec 28, 2023 · 11 comments
Closed

Comments

@Shadowblitz16
Copy link

Shadowblitz16 commented Dec 28, 2023

Passing a actor is bad because the actor is of unknown type and in cases of built in scripts or scenes can't be typed.
Also if we rely on actors behaviors could rely on a variable or function that is not on that type of node.
This means that a behavior would either crash or fail in the case a node type is used that is incompatable

Consider one of the following...

  • A monolithic ActorControl, Actor2D and Actor3D type as well as respective BT counter parts
  • A ec base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics
  • A ecs base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics
  • Remove actor parameter and use a event driven appoach (this would mean handling logic through signals)

Godot's design philosophy doesn't help.

@ThePat02
Copy link
Owner

Passing a actor is bad because the actor is of unknown type and in cases of built in scripts or scenes can't be typed.

Well, generally you know what type of Node your actor will be, as you set it by yourself. When using it in scripts, casting it to a type by using something like

actor = actor as ClassOfActorNode

as discussed in #54 could help. When you want to hot-swap the actor around while running, you should use conditionals like

if actor is SpecificActorClass:
    # Handle class specific logic and methods
    pass

to check for types.

Consider one of the following... [...]

Regarding your suggestions: I am not really sure what you are proposing here. Would you mind giving me a quick example of how these would work? As I see it, most of this would over-complicate a system that is easy to use and quite intuitive to implement. What problem are you trying to solve?

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Dec 28, 2023

Passing a actor is bad because the actor is of unknown type and in cases of built in scripts or scenes can't be typed.

Well, generally you know what type of Node your actor will be, as you set it by yourself. When using it in scripts, casting it to a type by using something like

actor = actor as ClassOfActorNode

as discussed in #54 could help. When you want to hot-swap the actor around while running, you should use conditionals like

if actor is SpecificActorClass:
    # Handle class specific logic and methods
    pass

to check for types.

Consider one of the following... [...]

Regarding your suggestions: I am not really sure what you are proposing here. Would you mind giving me a quick example of how these would work? As I see it, most of this would over-complicate a system that is easy to use and quite intuitive to implement. What problem are you trying to solve?

The idea behind a monolithic node is it would basically be scene or node that covered all use cases
This way when you use the parameter actor you have everything you need already there.

Ec and Ecs would use components and a single entity type
The way this works is you only have one type and the components are the things that do the work.
So for example if you need logic you can add it via a scene and then retrieve the components without needing any extra interface since the entity type has everything you need to get and set components

The event system would for example be something like...
signal set_velocity(v:Vector2)
The BT stuff could emit this when it needed to set the velocity of the actor and the scene would use advanced signals to hook it up.
These signals would probably be exported to the root BT node.

@Shadowblitz16 Shadowblitz16 changed the title Remove actor parameter in behavour's in favor of signals/events Remove actor parameter in behavour's in favor of something else Dec 28, 2023
@ThePat02
Copy link
Owner

The idea behind a monolithic node is it would basically be scene or node that covered all use cases
This way when you use the parameter actor you have everything you need already there.

Oh you are basically taking about a dedicated Actor class, right? I think this is WAY too project-specific. I implemented a few of these in my personal projects - all of them are different.

The BT stuff could emit this when it needed to set the velocity of the actor and the scene would use advanced signals to hook it up.

You are supposed to handle these things by yourself. This plugin only provides a framework to do so. There are endless signals to implement and it would become cluttered really fast. But yeah, having an Actor class is really recommended for bigger projects, but it is not something we could easily implement in a general way.

@Shadowblitz16
Copy link
Author

The idea behind a monolithic node is it would basically be scene or node that covered all use cases
This way when you use the parameter actor you have everything you need already there.

Oh you are basically taking about a dedicated Actor class, right? I think this is WAY too project-specific. I implemented a few of these in my personal projects - all of them are different.

The BT stuff could emit this when it needed to set the velocity of the actor and the scene would use advanced signals to hook it up.

You are supposed to handle these things by yourself. This plugin only provides a framework to do so. There are endless signals to implement and it would become cluttered really fast. But yeah, having an Actor class is really recommended for bigger projects, but it is not something we could easily implement in a general way.

A giant actor class is pretty impossible since we would lose the gui features.
Also you can't class_name scenes.

In the case of events...
I am not talking about you implementing every single possible event.
I am talking more of removing the actor parameter and having a api for users to define their own events.

@ThePat02
Copy link
Owner

Also you can't class_name scenes.

Well, I am a bit confused on why you need scenes?

I am talking more of removing the actor parameter and having a api for users to define their own events.

But you can already do that by using signals in extended Scripts for your FSM or BT? Technically, you don't need to use actor anywhere.

@ThePat02 ThePat02 added question Further information is requested discussion and removed question Further information is requested labels Dec 28, 2023
@SirPigeonz
Copy link
Contributor

Hello @Shadowblitz16 :) I'm this add-on contributor and user, I will also try to help.

Passing a actor is bad because the actor is of unknown type and in cases of built in scripts or scenes can't be typed.
Also if we rely on actors behaviors could rely on a variable or function that is not on that type of node.
This means that a behavior would either crash or fail in the case a node type is used that is incompatable

It's not ideal to pas generic Node, but it has its uses, and it's an optional property so you don't have to use it. I think it should be better documented, maybe? Was it clear that it was optional, or you were not aware? Any ideas how we can make it more clear?

I personally use it rarely, when working with AI, skill system or some dynamic custom logic in my game. Although, I think, it's mostly because of my game type.
It would be useful when you have for example an RPG game with a huge amount of very custom NPCs and you don't want to manually manage signals to bundle Behavior nodes with them for each independently. In this case, some generic Actor type created to fit your game will save you some time, although you will have to take care to check types in your custom Leafs and States.

Consider one of the following...

A monolithic ActorControl, Actor2D and Actor3D type as well as respective BT counter parts

Creating generic Actor ourselves would be wasted time because each game will have its own architecture and needs, it will actually scare of users that want only Behavior tools that they want to integrate into their own architecture.

A ec base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics
A ecs base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics

This would be an enormous undertaking that would have the similar effect of scaring users away that don't need that or already have their own preferred architecture for that. This kind of tool should be a separate add-on project.
There is actually a proposal to bring a special Swarm System to Godot core that could be used in situation when you are ready to give up some flexibility and extensibility for greater performance: godotengine/godot-proposals#2380
Potentially it will use ECS or similar pattern as a base architecture and will be integrable with more flexible Scene System design. :)

Remove actor parameter and use a event driven appoach (this would mean handling logic through signals)

This is something that we moved towards a bit. Especially with Signal Leaf node and Call Leaf node. I planned to propose to expose more generic events that we use inside the code as a signal, in similar fashion to States Charts add-on for Godot.
Although sometimes extending our nodes into custom ones is more desirable, I think we will want to preserve that too. Although allowing more flexibility for users workflow through signals is a nice thing and in spirit of Godot design. I think.

In my game I use both approaches depending on the context of a task. I often also want to mix both approaches.

In the case of events...
I am not talking about you implementing every single possible event.
I am talking more of removing the actor parameter and having a api for users to define their own events.

Can you elaborate how you would see this? We already have Signal Leaf and Call Leaf, you can also feed our own event into BTree, also, I personally consider exposing calls like tick(), _on_state_enter(), _on_state_update(), _on_transition() as signals. Would that be sufficient for you, or you need something more? Let's talk :)

Also you can't class_name scenes.

Yes you can't, but! There are solutions :) I personally make, my own ActorConfig, LevelConfig, MobConfig nodes that act as a component node for holding metadata for specific types of final Scenes made with composition. They hold members with pointers for each important component, and you can select them as your point of connection with BT system to feed important components for use in the BT :)

@Shadowblitz16
Copy link
Author

Hello @Shadowblitz16 :) I'm this add-on contributor and user, I will also try to help.

Passing a actor is bad because the actor is of unknown type and in cases of built in scripts or scenes can't be typed.
Also if we rely on actors behaviors could rely on a variable or function that is not on that type of node.
This means that a behavior would either crash or fail in the case a node type is used that is incompatable

It's not ideal to pas generic Node, but it has its uses, and it's an optional property so you don't have to use it. I think it should be better documented, maybe? Was it clear that it was optional, or you were not aware? Any ideas how we can make it more clear?

I personally use it rarely, when working with AI, skill system or some dynamic custom logic in my game. Although, I think, it's mostly because of my game type. It would be useful when you have for example an RPG game with a huge amount of very custom NPCs and you don't want to manually manage signals to bundle Behavior nodes with them for each independently. In this case, some generic Actor type created to fit your game will save you some time, although you will have to take care to check types in your custom Leafs and States.

Consider one of the following...

A monolithic ActorControl, Actor2D and Actor3D type as well as respective BT counter parts

Creating generic Actor ourselves would be wasted time because each game will have its own architecture and needs, it will actually scare of users that want only Behavior tools that they want to integrate into their own architecture.

A ec base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics
A ecs base which has components for networking, gui, particles, pathfinding, graphics, colliison, input, and physics

This would be an enormous undertaking that would have the similar effect of scaring users away that don't need that or already have their own preferred architecture for that. This kind of tool should be a separate add-on project. There is actually a proposal to bring a special Swarm System to Godot core that could be used in situation when you are ready to give up some flexibility and extensibility for greater performance: godotengine/godot-proposals#2380 Potentially it will use ECS or similar pattern as a base architecture and will be integrable with more flexible Scene System design. :)

Remove actor parameter and use a event driven appoach (this would mean handling logic through signals)

This is something that we moved towards a bit. Especially with Signal Leaf node and Call Leaf node. I planned to propose to expose more generic events that we use inside the code as a signal, in similar fashion to States Charts add-on for Godot. Although sometimes extending our nodes into custom ones is more desirable, I think we will want to preserve that too. Although allowing more flexibility for users workflow through signals is a nice thing and in spirit of Godot design. I think.

In my game I use both approaches depending on the context of a task. I often also want to mix both approaches.

In the case of events...
I am not talking about you implementing every single possible event.
I am talking more of removing the actor parameter and having a api for users to define their own events.

Can you elaborate how you would see this? We already have Signal Leaf and Call Leaf, you can also feed our own event into BTree, also, I personally consider exposing calls like tick(), _on_state_enter(), _on_state_update(), _on_transition() as signals. Would that be sufficient for you, or you need something more? Let's talk :)

I can't elaberate since I am not very good with behavour trees. I am still learning.
exposing those as signals would definitely be good but as long as you have that actor node passed as a a parameter
your giving new users the idea we should use that.

I definitely think signals are the way to go since they can be hooked into setters and getters

Also you can't class_name scenes.

Yes you can't, but! There are solutions :) I personally make, my own ActorConfig, LevelConfig, MobConfig nodes that act as a component node for holding metadata for specific types of final Scenes made with composition. They hold members with pointers for each important component, and you can select them as your point of connection with BT system to feed important components for use in the BT :)

@ThePat02
Copy link
Owner

I can't elaberate since I am not very good with behavour trees. I am still learning.
exposing those as signals would definitely be good but as long as you have that actor node passed as a a parameter
your giving new users the idea we should use that.

Well you are not wrong, but it IS highly encouraged to define an actor or even a custom Actor class, so nodes can access and manipulate some kind of generic object. This isn't unique to our implementation, but rather a general practice. Most of the time, these patterns are attached to an "actor" node,

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Dec 30, 2023

I can't elaberate since I am not very good with behavour trees. I am still learning.
exposing those as signals would definitely be good but as long as you have that actor node passed as a a parameter
your giving new users the idea we should use that.

Well you are not wrong, but it IS highly encouraged to define an actor or even a custom Actor class, so nodes can access and manipulate some kind of generic object. This isn't unique to our implementation, but rather a general practice. Most of the time, these patterns are attached to an "actor" node,

But the actor class is a node which is also the type of the behavior.
So in reality anything that we have the actor class for, emitting signals or the behavior can already do.

The only thing that the actor class is useful for is adding and removing it as children and that can be done though signals.

This isn't unique to our implementation, but rather a general practice. Most of the time, these patterns are attached to an "actor" node,

Also I agree with this statement but most engines that use this pattern use ecs or ec and generic entities.
Godot does not.

@ThePat02
Copy link
Owner

But the actor class is a node which is also the type of the behavior.
So in reality anything that we have the actor class for, emitting signals or the behavior can already do.

There is no dedicated actor class. It is something you make yourself. The toolkit only brings you means to generate behaviour patterns. An actor can be anything. Custom class, CharacterBody2D or even Sprite2D. It does not matter.

The only thing that the actor class is useful for is adding and removing it as children and that can be done though signals.

The "actor" should be the node in your scene, that has the "main script" attached. For example the CharacterBody2D, because it is in this case the "actor. It "acts out" the behaviour.

Also I agree with this statement but most engines that use this pattern use ecs or ec and generic entities.
Godot does not.

I don't think this pattern is specific to ECS. In fact it has nothing to do with it. BehaviourTrees and FSMs heavily rely on inheritance. There are several reasons why Godot isn't an ECS-based game engine and most of the plugins are created with this in mind.

@Shadowblitz16
Copy link
Author

I am going to need to get more experience before discussing this more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants