Accomplishing something like multiple inheritance

What I want to do is have scenes for characters, for example, that are constructed piece by piece.

What I mean is that I could add an animation child node, or sprite, or even other nodes which give some behavior to my base node (for instance I implemented several “navigation” nodes - InputNavigation, AimlessNavigation, FollowNavigation, etc. - that I can just append to a node and they do their thing).

I’m stuck at sprites. I have a sprite component (node) that I can drop on a node, and get the parent’s sprite id, like so

func _ready() -> void:
	var id = get_parent().sprite_id
	texture = ResourceManager.get_character_frames(id)

Currently the parent script actually exports the sprite_id, but what if I want another type of node (like an object, not a character) to have a sprite? I’d have to export the sprite_id there too.

And this is a simple example, what if I want a behavior that will add even more code to the parent component, that will then have to be duplicated in some other type of node where I want the same behavior?

The problem is that these child nodes can’t export properties themselves, and they can’t make the parent export them either. So all the stuff I want to expose in the inspector has to be in the parent script, where I can’t just extend MovingBodyComponent, SpriteComponent, etc..

What is the godot way for this?

I’m assuming this is in the context of packed scene instances. What’s your reason for wanting to expose the parameters, for all your child objects, in the parent node?

Using composition (i.e. components) to add functionality to a node requires you to configure each of those child nodes. If you want the parent to define an additional parameter that controls how these child nodes affect it, you can definitely do that. However, if your base node is starting to need to copy the parameters for most children, something is wrong.

Could you explain why you’re exporting this script_id instead of just adding a Sprite2D node to your object?

sprite_id*, my bad.

But regardless, idk if it’s crazy but I plan to manage all my “story nodes” in a manager that loads up a json config with all the states and events.

“Story node” as in anything, that might interact with the story, like characters of course, but also stuff like a building (so the building may be a node with 2 states, and based on event - let’s say a certain dialog finished - a transition is made to the next state, which changes some parameters - let’s say the sprite - goes from standing to destroyed or something), or a tree, etc.

I also might want to construct my scenes directly from the json at runtime (which idk if it’s a terrible idea), so I basically can change the game by changing a config.

Now, aside from this craziness, if I want to have an NPC scene, that I just place in a scene, how do I change the sprite in a simple way in the inspector? The parent node isn’t a sprite, so I can’t change the texture there. I’d have to have x different NPC scenes - basically presets - for x different NPC type? What if all my NPCs are unique?

Alright, I think I understand your setup a little better now. Just so we are on the same page, I’m going to briefly describe what I think the context of your problem is, and then what your approach could/should be.


If I understand you correctly, you’re creating a framework for your game’s narrative elements: dialogue, animation and other stuff. You want this framework to be capable of handling the states for any given “story node”, and you may even want to build these “story nodes” dynamically at runtime based on the contents of a .json file.

If any of this is incorrect let me know.


With regards to your NPC scene problem, I think you might be going about it the wrong way. Presumably, you currently only have a single NPC scene which you then configure on a per-instance basis; and you don’t want to face a scenario where every unique NPC is its own scene.

In this case I think it’s important to define what is implied by the term unique here. Are your NPCs unique in terms of functionality, or is it primarily the visuals that differ between them? If they differ in functionality, you almost need to make separate scenes due to the use of composition (what you describe as multiple inheritance). If only the visuals differ, I think you can get away with simply exposing a Sprite-variable on the base node.

That said, you did say that you want to avoid such an approach since it would require you to add the variable over multiple scripts. In the context of the framework, that I assume you have, I have a question:

You provided the example that multiple scripts would need the sprite_id since you have, or will have, multiple types of objects that are part of the framework.

However, what about these objects requires the need for multiple scripts?

The objects in the narrative framework wouldn’t need to perform unique behaviour as it is all controlled by what I assume is just a timeline of events (i.e. an animation). Even if you do have multiple scripts, you could make use of inheritance to avoid duplicate code (such as your sprite_id variable).

But argh – I’m kinda guessing since I’m not familiar with how you carry out these “stories”. Perhaps you could provide relevant material on how your system works (code snippets, node tree setup etc.)?

2 Likes

Hm, so you’re saying that because I’m attaching behavior at runtime, the nodes might as well be a single node. Even for buildings, they’re essentially NPCs with weird looking sprites and no movement - even the player scene is essentially the NPC scene but with InputNavigation attached, while a NPC might have AimlessNavigation attached by the NavigationManager, so I might end up deleting it if it will turn out I really don’t need the player to do any special stuff. Maybe I will need to export stuff related to navigation, so the NPC node would extend CharacterBody2D, SpriteHolder, NavigationHolder (or some better names lol)

But for buildings, I might actually want a separate scene where I have an extra Area2D that teleports the player upon entering (to an inside scene or whatever), and I might want to export the scene name, or some coordinates. So the building node would extend StaticBody2D, SpriteHolder, PortalHolder - this is where I’m duplicating the @export for sprite_id.

So yea essentially I’m thinking of having a couple of scenes, that are presets, stitched from several components that require the parent node to export a few configs for them.

Honestly I’m working on a proof of concept and barely just started it, so at this point I’m not even sure how I want to do things.

I guess because we’re just talking about exporting a few variables it’s not that big of a deal to duplicate the code, but it just smelled bad to me, so I wanted to know in what other ways I could do it.

1 Like