Godot: Gdscript: It's impossible to override _process function

Created on 15 Sep 2016  Â·  18Comments  Â·  Source: godotengine/godot

Operating system or device - Godot version:
Godot 2.1 stable

Issue description (what happened, and what was expected):
When you override _process method in script that's an offspring, and the ancestor have it's own implementation of _process both implementation will be called (first the offspring then ancestor).

Steps to reproduce:
Extend script with logic inside _process and override this method. Both implementations will be called.

Link to minimal example project (optional but very welcome):
OvverrideProcess.zip

archived

Most helpful comment

I still think it would be better to not call the parent callback automatically. The current behavior is not flexible and you can't count which function will be called first, if the parent or the child. In my experiments, _process is called by the child class first but _ready runs in parent class first.

I can see the use in doing something like this:

func _process(delta):
    # prepare stuff for parent calculations
    ._process(delta) # call parent process
    # process something with parent's results

This has the same problem as _init() and hinders the possibilities of OOP design.

All 18 comments

Well, that's fully intended :smile:

This is a feature, not a bug (it's documented) you can try calling another
function
from _process and override that

On Thu, Sep 15, 2016 at 12:45 PM, kubecz3k [email protected] wrote:

_Operating system or device - Godot version:_
Godot 2.1 stable

_Issue description_ (what happened, and what was expected):
When you override _process method in script that's an offspring, and the
ancestor have it's own implementation of _process both implementation
will be called (first the offspring then ancestor).

_Steps to reproduce:_
Extend script with logic inside _process and override _process(delta)

_Link to minimal example project_ (optional but very welcome):
OvverrideProcess.zip
https://github.com/godotengine/godot/files/475028/OvverrideProcess.zip

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/6500, or mute the thread
https://github.com/notifications/unsubscribe-auth/AF-Z26k4fzzzqnQHgTjQeWKLe3taDhYlks5qqWgegaJpZM4J-BpP
.

callbacks get called at all levels, back when we had Squirrel programmers
used to forget calling the parent functions all the time for callbacks they
handled different and it was kind of a mess.

On Thu, Sep 15, 2016 at 12:55 PM, Juan Linietsky [email protected] wrote:

This is a feature, not a bug (it's documented) you can try calling another
function
from _process and override that

On Thu, Sep 15, 2016 at 12:45 PM, kubecz3k [email protected]
wrote:

_Operating system or device - Godot version:_
Godot 2.1 stable

_Issue description_ (what happened, and what was expected):
When you override _process method in script that's an offspring, and the
ancestor have it's own implementation of _process both implementation
will be called (first the offspring then ancestor).

_Steps to reproduce:_
Extend script with logic inside _process and override _process(delta)

_Link to minimal example project_ (optional but very welcome):
OvverrideProcess.zip
https://github.com/godotengine/godot/files/475028/OvverrideProcess.zip

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/6500, or mute the thread
https://github.com/notifications/unsubscribe-auth/AF-Z26k4fzzzqnQHgTjQeWKLe3taDhYlks5qqWgegaJpZM4J-BpP
.

What I can say? All that time I'm writing in gdscript and was not aware of that. I believe I had problem with this in the past... will need to recheck my projects :P

I found notion of this feature only in one place

However, remember that functions such as _init, and most notifications such as _enter_tree, _exit_tree, _process, _fixed_process, etc. are called in all base classes automatically, so this should be only for calling functions you write yourself.

I think, it needs to be written in big red caps letters

I still think it would be better to not call the parent callback automatically. The current behavior is not flexible and you can't count which function will be called first, if the parent or the child. In my experiments, _process is called by the child class first but _ready runs in parent class first.

I can see the use in doing something like this:

func _process(delta):
    # prepare stuff for parent calculations
    ._process(delta) # call parent process
    # process something with parent's results

This has the same problem as _init() and hinders the possibilities of OOP design.

In parents I use something like this

func _on_process(delta):
    pass

func _process(delta):
    _on_process(delta)

And in subclasses I still can forget to call ._on_process()
It would be better to not call the parent callback automatically, but if it is really necessary, maybe it would be better just to forbid overriding of special methods like _process

If processing order of inherited and parent functions is unpredictable then that should be classified as a bug.

How about separate keyword for special methods?

method _ready(delta):
     # I will call parent _ready automatically
     pass

func _my_ready(delta):
     # I will call parent _my_ready manually
     ._my_ready(delta)

I wonder why this is closed, it looks quite relevant to me.

I honestly find it quite counter intuitive. And I find what @vnen said to be much better as it is very explicit and you don't have to search and go into the rabbit hole that is godot issues page to find why it works the way it does.

this is a confusing "feature", is not intuitive, and is illogical in a OOP mindset. i got frustrated a lot before i discover this is intended.

I'm lucky I stumbled across this issue. I've spent days trying to figure out why something wasn't working properly and it turns out this is the problem. This is completley unintuitive considering it's the opposite of how every other engine and OOP in general works.

I can understand the reasoning and I do support the way these functions are called, but it still causes serious problems when trying to extend engine classes. Because you have no chance to control if and when the hard coded super class methods will be called. As a result, _extending engine classes in GDScript is barely supported_ in the moment, see also this issue.

I thought quite a bit about it, and from the various options available, I think this one might be the best: introduce a new keyword override:

override func _process(delta):
  if we_want:
    ._process(delta)

So essentially, override will prevent to super classes' implementations of this function to be called. The user opts-in to that behavior and is then able to call the super method when/if he wants.

I might open another ticket with this proposal, since extending engine-classes is something that is essentially broken in godot the moment.

@vnen Do you have plans to touch this topic for your big (and great!) 4.0 refactorings?

What about the following solution:

  1. We could leverage annotations (https://github.com/godotengine/godot-proposals/issues/828) to opt-out from auto base calls. For instance, your example would become:
@no_auto_basecall
func _process(delta):
    # prepare stuff for parent calculations
    ._process(delta) # call parent process
    # process something with parent's results

This would also allow to completely omit the base call, achieving true override semantics.

  1. Methods without @no_auto_basecall would still have an implicit base call, but ideally in a well defined order, i.e., consistently parent class first, or child class first. By defaulting to the old behavior, the feature should be largly backwards compatible.

@bluenote10 This behavior was already removed in the GDScript rewrite. The documentation has been updated accordingly. There's now a super keyword you can use to reference parent methods: super.some_method()

@Calinou Thanks for the hint. I've indeed found some code on the godot/master branch, which indicate the change you mention. But on godot-docs/master the gdscript_basics.rst still seems to document the 3.2 behavior with implicit super calls.


Relevant section


image

Would be curious to read up on the planned solution.

@bluenote10 The pull request updating the documentation hasn't been merged yet, that's why. I think we'll wait for a bit before merging it to avoid confusing people reading the master branch of the documentation even though they're using Godot 3.2.

Was this page helpful?
0 / 5 - 0 ratings