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

Override variables from extended class #19113

Closed
GammaGames opened this issue May 23, 2018 · 3 comments
Closed

Override variables from extended class #19113

GammaGames opened this issue May 23, 2018 · 3 comments

Comments

@GammaGames
Copy link

GammaGames commented May 23, 2018

Say I have a script, Entity.gd. It looks like:

extends KinematicBody2D

var speed = 0
var health = 3

func _ready():
    connect("",  self, "signal")

Now I want to extend that script into Enemy.gd. I want to change its health and speed, in order to do that I have to set them in the _ready function like so:

extends 'res://Entity.gd'

func _ready():
    speed = 5
    health = 5
    ._ready()

This seems like a somewhat hacky way to set variables in your base class, having to set your variables in _ready and then calling the parent's function if necessary.

I am proposing a small change to allow setting variables in a similar way to the base class, just using the onready keyword. The documentation says (referring to storing references to nodes):

For this, GDScript has the onready keyword, that defers initialization of a member variable until _ready is called

So onready is already used for a similar purpose in its current state. This suggestion would allow Enemy.gd to be written like:

extends 'res://Entity.gd'

onready speed = 5
onready health = 5

It would let scripts look more consistent when extending base classes, if you wanted to change one of the base class's variables you could do it in the same area that it was done in both scripts. _ready will be called just like in the base script.

Thoughts?

@GammaGames
Copy link
Author

I found out you could use _init, so now both scripts look like:

Entity.gd:

extends KinematicBody2D

var speed = 0
var health = 3    

_init(_speed = 0, _health = 3).():
    speed =_speed
    health = _health

Enemy.gd:

extends 'res://Entity.gd'
_init().(5, 5):
    pass

Which seems better, but I still think setting variables above would look nicer. Maybe with an oninit keyword?

@vnen
Copy link
Member

vnen commented May 23, 2018

I thought I commented here already, but it seems it did not register... Let me try again.

This seems like a somewhat hacky way to set variables in your base class, having to set your variables in _ready and then calling the parent's function if necessary.

This is not hacky, it's the way OOP works in pretty much every language. However, I believe _ready() is in a multilevel call, so the parent will be called automatically.

In my lost comment I said that you can use _init() pretty much in the same way. You don't need _ready() unless you need something from the tree.

The thing is, you shouldn't expect this to work:

extends 'res://Entity.gd'

speed = 5
health = 5

So adding an onready keyword there should not magically make it work. This is not used in any language I know of, and it's not GDScript business to invent new constructs IMO. onready is a simple convenience to avoid creating a function when you only need to set up a few variables (so you don't need to declare in one place and initialize in another).

I think such shorthand can be quite cryptic, because the difference between declaration and parent override is just a var keyword that can be easily missed. I understand the appeal but IMO it's more confusing than useful.

@GammaGames
Copy link
Author

This is not hacky, it's the way OOP works in pretty much every language.

It more felt hacky because I thought there should be a better way to change inherited variables, and using _init is a better way IMO.

I think such shorthand can be quite cryptic, because the difference between declaration and parent override is just a var keyword that can be easily missed. I understand the appeal but IMO it's more confusing than useful.

Those were my concerns as well, and there aren't really any arguments against them. Setting the values in _init sounds like it would work well, I'll use that. Thank you!

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