dialogic-godot / dialogic

💬 Create Dialogs, Visual Novels, RPGs, and manage Characters with Godot to create your Game!
https://dialogic.pro
MIT License
3.89k stars 233 forks source link

Dialogic interactions with the scene it is in #1965

Closed TinMarkovic closed 7 months ago

TinMarkovic commented 9 months ago

Is your feature request related to a problem? Please describe.

I'm attempting to plug in my other gameplay systems into Dialogic, but I'm meeting resistance. I'm trying to have the rest of my UI interact with the Dialogic scene, and I don't see straightforward ways to achieve this.

This might just be a documentation issue.

I'm trying to:

Describe the solution you'd like

All the above are things I'd expect to be able to manage/control when using Dialogic with Godot. I might just be lacking specific knowledge or some design patterns I'm not aware of.

I'm not a Godot expert (not by a long shot), but I've got a lot of generalist programming experience. I'd be more than willing to help and document any of the above as I learn how Dialogic work, and make some PRs to the documentation :)

Jowan-Spooner commented 9 months ago

This is multiple problems:

Dialogic is not aware of the scene it is triggered from.

This means it cannot easily access that scripts variables. An Autoload is the most simple solution. You could also have an autoload that has a reference to a scene and you update that reference when starting dialogic. E.g.:

# Autoload script
extends Node

var scene : Node = null

Then when starting dialogic you can do

func _on_something_something():
     Dialogic.start("MyTimeline")
     Autoload.scene = self

And then you can access the scripts variables in dialogic timelines like this: {Autoload.scene.variable}

This is not something we intend to change as coupling with a changing scene (the same timeline COULD be called from multiple different scripts) is a risky thing to do.

Tooltips

I'm not entierly sure what kind of tooltips we are talking about. The glossary might be worth checking out. Alternatively you might mean certain parts of the layout. In that case you will have to modify the layout scenes directly.

Order of UI elements

The order of UI elements in godot is mainly influenced by CanvasLayers (Godot Docs). Dialogics default styles use a canvas layer of 1 to appear above all other game elements, but if you add a canvas layer with a higher layer set somewhere in your tree, anything in it will appear on top of dialogic and have a higher priority. This is the intended godot way of designing UI, so this will not be changed


I hope this helps. If you have further questions, then emilios discord is always a good place to ask.

TinMarkovic commented 9 months ago

Thanks Jowan, much appreciated. Let me respond in turn.

Dialogic is not aware of the scene it is triggered from.

This should work! I'm not at my desktop at the moment so I can't test it, but it's a great workaround.

Are you opinionated about this as maintainers? The boilerplate could be avoided by Dialogic itself storing the caller's scene, no? Then exposing it as Dialogic.current_scene or something. Would avoid boilerplate.

Either way, IMHO it's a common enough pattern/workflow that it should be worth noting in the docs. If it's a non-change, I can take some time to move this example to your docs.

Tooltips

Alternatively you might mean certain parts of the layout.

Yup, the dialogue choices having tooltips was what I had in mind. Sorry for the unclear text above.

Is there a way to achieve this that's straightforward-ish, or a guide somewhere? I'm not sure modifying layout scenes would be practical as a 1-off, as I'd like those UI elements to be dynamic and depend on the option itself. Could be worth adding to Dialogic itself.

Order of UI elements

Noted. I must've been doing something wrong with my composition for it not to be working properly. I'll give it another go and make sure I use a higher Canvas Layer. Thanks for the info!


The discord? Is there a link I can find somewhere? I've looked through the website, here, and even Emilio's personal web, but I couldn't find it. Would love to have a place where I could chat to other users in realtime :)

Jowan-Spooner commented 9 months ago

@TinMarkovic

Are you opinionated about this as maintainers? The boilerplate could be avoided by Dialogic itself storing the caller's scene, no? Then exposing it as Dialogic.current_scene or something. Would avoid boilerplate.

Well, if there is an easy way to get the caller of a method then we could do this, but I don't know how we can know from where Dialogic.start() is called. If you know, feel free to point me there. I'm just not aware of this being possible.


Is there a way to achieve this that's straightforward-ish, or a guide somewhere? I'm not sure modifying layout scenes would be practical as a 1-off, as I'd like those UI elements to be dynamic and depend on the option itself. Could be worth adding to Dialogic itself.

I'm not entierly against adding tooltips to the core, but customizing a layout doesn't necessarily mean it looses flexibility. With the recent introduction of layout layers (alpha 12 released today) you could simply make a custom choices layer scene in which you change the tooltips of the choices. This doesn't stop the choices from being dynamic.


The discord? Is there a link I can find somewhere? I've looked through the website, here, and even Emilio's personal web, but I couldn't find it. Would love to have a place where I could chat to other users in realtime :)

Hmm, we might have to add a link to the readme. There is a link on the plugin home page (in editor): grafik

Here is the link: https://discord.com/invite/2hHQzkf2pX

TinMarkovic commented 9 months ago

Hmmm. Encountered a "bug" or something unexpected.

While the {Autoload.scene.variable} works in templates and if statements, it breaks the do Foo.bar() syntax in the text editor.

I've tried do Autoload.active_scene.foo_method("argument") and it broke with:

[Dialogic] Call event failed: Autoload doesn't have the method 'active_scene'.

Not sure if this is worth fixing/figuring out - but wanted to keep it here for posterity. I can probably work around it myself (just assign results to variable and use the curly-brace syntax), but it is inconsistent with other behaviour. Most likely due to the UI coupling? From what I can see do Foo.bar() assumes it's not a chained call :)

Edit: I've gotten an alternative to work with: set {result} = {Autoload.active_scene.foo_method("argument")}

TinMarkovic commented 9 months ago

Well, if there is an easy way to get the caller of a method then we could do this, but I don't know how we can know from where Dialogic.start() is called. If you know, feel free to point me there. I'm just not aware of this being possible.

I couldn't find a straightforward way. The best I could come up with is an argument to the start() function: Dialogic.start('chapterA', '', self). Not quite sure how warm I'm to expanding the signature, though.

I'll see about adding the examples you've taught me here to the docs.

Jowan-Spooner commented 9 months ago

Ah I didn't think about the call event. It does indeed only work with methods that are directly on the autoload. We probably could just use the Expression logic of the set event there too, just have to figure out the UI for it. glad you found a temporary work-around.

Yeah not too fond of adding a new argument to .start() either, maybe good examples can just solve it for now.