dialogic-godot / dialogic Goto Github PK
View Code? Open in Web Editor NEW๐ฌ Create Dialogs, Visual Novels, RPGs, and manage Characters with Godot to create your Game!
Home Page: https://dialogic.pro
License: MIT License
๐ฌ Create Dialogs, Visual Novels, RPGs, and manage Characters with Godot to create your Game!
Home Page: https://dialogic.pro
License: MIT License
Writing text requires to use the cursor way too many times, so I'll be adding a few hotkeys for better keyboard navigation.
Shift
+ Enter
: Create a new text event with the same settings as this one? (or maybe alternating between this and the previous, so you can create a conversation between two characters easily)Tab
: Jump to the next Text Event text edit fieldShift
+ Tab
: Jump to the previous Text Event text fieldAlt
+ up
/ Alt
+ down
: Move selected event up or downThe dialog should be able to be displayed at any size, so instead of the fixed hard-coded control node it should be dynamic.
When I was first looking for dialogue solutions this never appeared in my searches, mainly because all docs use the word "dialog" and I was looking for "dialogue". (i.e search for "dialogue" in Godot's asset library)
Both spellings are correct, but maybe if you find a way to include the second word somewhere you may improve your discoverability.
Nice work, though.
I got two errors of the following:
Windows 10 x64 (RAM 4Gb, Intel HD graphics 4000)
While using the plugin, I noticed that my computer was working slower than usual. I assumed it was just windows background tasks (because windows y'know). After closing them, the slow work still there, so i opened up the task manager and notice something interesting:
My ram being drowned by Godot. Things goes worse when i excecute only a Node
with Dialog.tscn
as child:
Note: % is the CPU usage.
(Just to be clear, i used the same scenary for all my test. An open Scene
as the main scene with a Node
as root and a Dialog.tscn
as child of Node
. This is usually the consumed ram without the plugin and the consumed ram without the plugin but Dialog.tscn
as child)
Playing a little with the code, I managed to solve this problem (kinda):
Node
as rootDialog.tscn
child of Node
As can be seen on the gif, the Timeline's questions are set up one way, but the parser takes more than it's supposed to and bugs out.
The timelines used for testing this:
timelines.zip
Version: master, commit 83a7a0e
Not sure how I will set up this one, but if I had to add one a simple opacity fade could work.
When questions are nested, pressing on one of the buttons can cause a bug
Invalid type in function 'set_mouse_mode' in base 'InputDefault'. Cannot convert argument 1 from Nil to int.
Seems like it's simply trying to set a mouse mode to "Null" which gives an error. A simple null check might fix it.
Version: master, commit 83a7a0e
Just taking a look at Mark Brown's Designing for Disability series where he discusses subtitles and the like. I figure you can do a couple of things, like...
This issue is just to throw some ideas out there. Could be used to catalog other more specific issues of implementing a particular solution for one of the problems mentioned in Mark's YouTube series.
It's saved in json as 'endchoice' and is called that internally (in code) despite being "EndBranch" in editor and working with conditionals.
Suggested refactor should still be able to read the 'endchoice' in json but transform it to correct 'endbranch' naming automatically for backwards compatibility/migration to new method.
Todo:
print('-------------------------\n', dialog_resource.nodes)
This line errors. After removing it works fine.
Maybe I haven't caught up? I'm on v0.6, but still watching video 1...
Input in Dialogic (input_next) is handled by the _process() method and not _Input.
This means the scene tree method set_input_as_handled() cannot be called. The result is if the underlying game is not paused then the input event is propagated down to the rest of the game that may handle _input, so if the same key handling input in Dialogic is handled in the game it is still called.
I'm not too hot on gui input in Godot but I had to fix the above problem by moving the _process() code handling input into the following similar code:
func _input(event: InputEvent) -> void:
if Input.is_action_just_pressed(input_next):
get_tree().set_input_as_handled()
i.e. after dialogic has processed the next screen key, it cancels input, otherwise Godot will just send the key to the rest of the game regardless.
Apologies if this version has already addressed this, I was using a slightly older version, but a quick scan of the code shows the same input being used.
Please excuse me if I am making a really basic beginner error, but I am unable to get Dialogic to show up as a plugin in Godot! I have followed the documentation -- i.e. opening a new project, then downloading the zip, unzipping it and copying the 'addons' folder over to my empty Godot project, then checking in Project Settings>Plugins -- but Dialogic isn't listed there as a plugin to enable?
I have tried both the very latest build (0.8) and also v0.7 and it's not showing up in either.
I'm using Godot 3.2.3 on a Mac (Catalina 10.15.6).
There are 3 distinct things that appear with the script icon:
There should be distinct icons for each of these purposes, imo.
The only one right now is moving up and down.
In this original layout, you have many different parts of the UI present on the left-hand panel. But we've mixed together navigation, dialogue operations, and modifying the content of the dialogue all together in one place.
Here is a revised prototype of the UI:
In this case, the "events" stuff is all added to a sticky bottom "event" block that contains the buttons to add more blocks.
A toolbar is added to the top of the panel which would contain the script and folding ToolButtons.
Script: should show "add a script" icon when no script exists for the dialogue and the generic "script" icon (which it currently shows) to open the script in the ScriptEditor.
Folding: should be a toggleable ToolButton. If any 1 collapsable block is not collapsed, then the button displays a "fold" icon and clicking it will fold all blocks, after which, it displays the "unfold" icon. Clicking the button while in the "unfold" state will unfold all blocks and subsequently change it to the "fold" icon.
This paves the way for more making more fully-featured navigation options on the left, and creates more space for executing more dialogue-level operations in the above toolbar. I would reserve the higher toolbar for tabs, as you've done so. However, it might look better to give it more prominence with a full-fledged TabContainer or something. That way you can directly see the subsections of the dialogue editor laid out for you rather than the "tabs" looking like some sort of operations you can click on to execute. You could, in the long run, use it as a place to switch between minor editors for all kinds of pieces of data related to the story.
A theme editor should be able to change the basic properties of the text and the dialog box where the final dialog is going to be displayed.
I never used C# yet but it seems like a good time to try it out.
From what I can tell, you used to use your character resources for data, but you've since migrated to using JSON for everything.
However, there are distinct pros and cons to each data format.
Resources:
JSON:
It'd be better if multiple serialization options could be supported simultaneously, presenting users with options to suit their preference/scenario.
I can also see that you manually parse and put together the data in the editor_view.gd
script which performs many other tasks as well. Might I suggest the following changes?
inst2dict
and dict2inst
to automatically convert resources to and from JSON formats.editor_view.gd
just create an instance of the DialogicDB class and initialize it. This will help clean up the editor_view.gd
script.Also, long-term, because editing arrays of resources in the Inspector kinda sucks, we could consider implementing a spreadsheet-like editor in the bottom panel for editing multiples of these resources at once (with each row being a different instance), at which point, the entire collection of resources could be saved into a single dialog_db.tres
file. Give people the option of saving each resource out to a separate file in a directory, but also give the option to just have it all saved to a single resource file that stores an array of the other resources internally. There's actually already a proposal I wrote about it at godotengine/godot-proposals#13. Not a requirement of the above changes though.
Currently, Dialogic interface is hard-coded and difficult to expand with extra systems any developer would like to have (for example, my attempts to implement an Ace Attorney cross-examination system are hell right now.)
example of current hard-coded nature
My proposal is to expand and unhardcode the system in such a way that it's split into several digestible scenes, all of which can be replaced and overriden by developers while Dialogic still provides out-of-the-box default versions of the behaviors. This way, beginners will have an immediately working interface - what Dialogic is very good at right now - and also provide an alternative for advanced users who want to use the backend of Dialogic while handling the frontend themselves.
example of a dynamic and nice version
In simple terms, the parser node is the big focus of this issue report. A very good principle to hold for this is as such:
example how a parser node only acts as an intermediary for anything connected to it to interpret the data
This approach will also solidify Dialogic's position in the Godot plugin scene and might even make it the #1 go-to plugin for dialogue interfaces ๐ค
When you get to the final dialog of a timeline, some games display a different icon instead of the "continue" one, so It would be nice to be able to customize that in case someone needs to show it in a game.
Hello,
If you move your embedded JSON sample script (in dialog_node.gd) to a file then it fails to load because it is not valid JSON. In addition, your file() method performs no checks on the parsed JSON to see if it's valid, it simply returns null back to your code.
I know this is all WIP and not ready, just trying to help in case you didn't have these in your list of things to do.
Hope this helps ;-)
In the following the comma after 'face' should not be there, it's invalid JSON
{
'character': 'Kubuk',
'text': 'Maybe... Now that you mention it, I can actually see your face!',
},
None of your single quotes are valid, they should be double:
{
"character": "Kubuk",
"text": "Maybe... Now that you mention it, I can actually see your face!"
},
In your file() method, you may want to check the dict is valid, i.e. as below is simply check for null.
if typeof(p.result) == TYPE_ARRAY:
btw, I think it looks a lot neater moving all that json sample in the dialog script to a separate json file...
As in any narrative based games, there are few functions or effects that are missing in this wonderful plugin.
Point 1-3, I coded these manually and it's not that hard but for the sake of completeness of this awesome plugin, it would be nice if they come out of the box.
Thanks for this awesome plugin. Cheers!
Hello,
load_dialog() expects dialog_script to be an array.
If you use dialog_json export variable and provide a json file (e.g. as created by the new GUI front-end), then it stores the Dictionary inside dialog_script.
It then fails.
As in the title, it will allow e.g. background animations.
It seems to save on every letter typed in the Text Block, which is excessive file I/O.
Instead, why not make it only save on every switch between timelines, whenever a new element is added to the timeline, or the game is about to be launched using the "Play the Project"/"Play the Scene" buttons?
Additionally, there might be a related issue to current saving being problematic:
#39
Hi, whenever I import and enable the plugin in a project the following error appears:
res://addons/dialogic/Editor/EditorTheme.gd:43 - Invalid get index 'theme_font' (on base: 'Dictionary').
I tried it both on the current stable version of Godot and on the latest beta version. I also tried it on multiple projects and the result is always the same.
Cheers
Some variations from the official GDScript style guide. I would recommend making changes to the codebase to match its specifications, for better cross-maintainability and consistency with the overall Godot community.
With just a quick glance at editor_view.gd
, I noticed two issues already:
Derived from a YouTube comment I made on your first devlog.
divert
to another dialogue sequence.diverted-to
dialogue to pull data from the diverted-from
dialogue, such as...
This would necessarily require occupying screen space on the left-hand side that is currently being used for events, folding, and script attachment. See #7 for more details on modifying the UI to accommodate things (including more complex navigation).
With this setup:
Whenever the game is launched, the dialog node appears disappeared - however, it is simply incorrectly sized. This is caused by resize_main()
being called in _ready():
When looking into the scene structure using the Scene/Remote
tab in the engine, it appears that the dialogue node was not destructed, however, it's size is incorrect and way bigger than it is supposed to:
Hi,
when using a "emit signal" the timeline paused processing the next event.
Maybe an go_to_next_event() in line 311 from dialog_node.gd is missing.
Line 311 in dialog_node.gd
{'emit_signal'}: print('[!] Emitting signal: ', event['emit_signal']) emit_signal("dialogic_signal", event['emit_signal']) go_to_next_event()
btw, dialogic is really great. :)
Whenever I try to add a character to my Dialogic project, I get the following error message and nothing happens:
ERROR: File must be opened before use. At: core/bind/core_bind.cpp:2216
Do I need to add some specific file to my project in order to make it work? (Other than the plugins subdirectory)
I'm on Windows, Godot 3.2.3 stable, Dialogic 0.8.
Haven't tried it yet on Linux but if you think that might help I can give it a shot.
Let me know if you need an example project to reproduce this.
People requested the swap of styles in game, so I'll have to create a "theme selector" event for the timeline and save each theme into different files so they are individually editable.
Putting the "addons" folder inside my project and then going to:
Project > Project Settings > Plugins
Doesn't work. The list is empty.
I'm using version 0.4
Hi, @coppolaemilio I and Vaasref are making our own Dialogue system called Rakugo with rollback and save feature.
We are now chaing it a lot. So maybe you want to join? Here is discord project: https://discord.gg/K9gvjdg
When exporting a project that contains a dialog_node the node only displays the default text even when supplied with a timeline and only uses the default settings. The node works when loading in the editor however where it displays the correct text and uses the correct settings
Error as reported by godot debug output(image attached):
SCRIPT ERROR: load_theme: Invalid get index 'theme_font' (on base: 'Dictionary').
At: res://addons/dialogic/Nodes/dialog_node.gdc:441
SCRIPT ERROR: load_dialog: Invalid call. Nonexistent function 'has' in base 'Nil'.
At: res://addons/dialogic/Nodes/dialog_node.gdc:191
Maybe the title had to be renamed to get_character_position() returns null
If you create a Join
event with a character but without position, it gives you an error and breaks your game.
This is due a problem with the dialog_node
function get_character_position()
. This returns null if all positions are false
, but it should be returning an string to pass that to the init
function of Portrait
node, because the second parameter of init
expects an string, but the dialog_node
pass a null reference (because that's the actual behaviour).
Playing with the code I got 2 possible solutions
Let the function get_character_position()
return something:
func get_character_position(positions) -> String:
if positions['0']:
return 'left'
if positions['1']:
return 'center_left'
if positions['2']:
return 'center'
if positions['3']:
return 'center_right'
if positions['4']:
return 'right'
return 'none'
And then handle that string inside the init
function of Portrait
node
func init(expression: String = '', position_offset = 'left') -> void:
if position_offset == 'none':
return # This line will not work as expected
or modify the positions
variable
var positions: Dictionary = {
'left': Vector2(-400,0),
'right': Vector2(+400,0),
'center': Vector2(0,0),
'center_right': Vector2(200,0),
'center_left': Vector2(-200,0),
'none': Vector2.ZERO # or whatever you like
}
Handle the null value directly inside the init
function of Portrait
node
func init(expression: String = '', position_offset = 'left') -> void:
if position_offset is null:
return # This line will not work as expected
If you ask to me, I prefer the first option modifying the positions variables
Initial work for this one has been done. This will be a tracker now of the things left to translate:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.