From e50e7963ab1ca3ae9410b6892076b32dd51c5b4c Mon Sep 17 00:00:00 2001 From: Cake <65981767+CakeVR@users.noreply.github.com> Date: Thu, 30 May 2024 13:30:38 +0200 Subject: [PATCH] Improve Creating Extensions. Adds more information about saving and loading an Event. Improves grammar. --- documentation/creating-extensions.md | 92 ++++++++++++++++------------ 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/documentation/creating-extensions.md b/documentation/creating-extensions.md index 8cf31df..7154d41 100644 --- a/documentation/creating-extensions.md +++ b/documentation/creating-extensions.md @@ -1,5 +1,5 @@
-     
Creating Extensions
+
Creating Extensions
*Sometimes Dialogic is just not enough*. @@ -28,18 +28,18 @@ The best way to create an extension is to use the extension creator in the dialo -By clicking the `Create New Extension` button, you can set up an extension folder and custom event script. Enter a name for the new module and select what you would like to add. Then click `Create`. +By clicking the `Create New Extension` button, you can set up an extension folder and a custom event script. Enter a name for the new module and select what you would like to add. Then click `Create`. --- ## 2. The essential part: `index.gd` -The central piece of any extension is the `index.gd` script. It is the only thing your extension is required to have. It has to extend `DialogicIndexer` and can overwrite that class's methods to let Dialogic know about what things to add. +The central piece of any extension is the `index.gd` script. It is the only thing your extension is required to have. It has to extend `DialogicIndexer` and can overwrite that class's methods to let Dialogic know what things to add. For example, this code registers a custom event: ```gdscript func _get_events() -> Array: -    return [this_folder.path_join('event_print.gd')] + return [this_folder.path_join('event_print.gd')] ``` *Check out the `DialogicIndexer`'s other methods to learn how to register other things.* @@ -56,13 +56,13 @@ Often, events work together with subsystems. ## Your custom event -The Extension creator allows you to get a basic event script. It already has set some values for you. +The Extension Creator allows you to get a basic event script. It already set some values for you. These are the things you need to do to make your event fully functional: #### 1. Event settings: -All options of your event should be stored in variables. Define these at the top. +All options for your event should be stored in variables. Define these at the top. ```gdscript var print_text: String = "" @@ -75,12 +75,12 @@ Add whatever should happen when your event is reached in the `_execute()` method ```gdscript func _execute() -> void: -    print(print_text) + print(print_text) -    if in_game and Dialogic.has_subsystem('Text'): -        Dialogic.Text.update_dialog_text(print_text) -    else: -        finish() + if in_game and Dialogic.has_subsystem('Text'): + Dialogic.Text.update_dialog_text(print_text) + else: + finish() ``` *The `finish()` method lets Dialogic know to continue with the next event.* @@ -96,9 +96,14 @@ func _init() -> void: event_category = "Godot" ``` -#### 4. Saving/Loading: +#### 4. Saving & Loading -To implement shortcode saving, return a shortcode identifier in `get_shortcode()` and fill out `get_shortcode_parameters()`: +We will cover working with shortcodes now. They are pretty much the text view of an event inside the timeline. +The following is the shortcode for the Background event. +``` +[background arg="res://Graphics/Backgrounds/sunset.png" fade="1.5"] +``` +To implement saving your shortcuts, return a shortcode identifier in `get_shortcode()` and fill out `get_shortcode_parameters()`: ```gdscript func get_shortcode() -> String: @@ -114,11 +119,18 @@ func get_shortcode_parameters() -> Dictionary: ``` *The above event might be saved as `[print text="Some text to print" in_game="true"]`* -*You can implement a custom saving syntax by overriding `to_text() -> String`, `from_text(@string)` and `is_valid_event(@string) -> bool`. This is what the text-, character-, choice-, condition-, and variable events do, so take a look at them if this is something you are interested in.* + +## 4.1 Custom Saving & Loading Syntax + +You can implement custom saving syntax by overriding the function `to_text() -> String` and `from_text(timeline_event: String)`. +The `is_valid_event(event_name: String) -> bool` needs to be override too, if you want to quickly check if the event name is correct. + +When is custom saving and loading useful? If your shortcode has a special text syntax or is converting between values, map a word to an integer. +This is what the text-, character-, choice-, condition-, and variable events do, so take a look at them if this is something you are interested in. #### 5. Editor fields: -Your event is now fully functional, but in the visual editor, it is still only blank. You will need to override the `build_event_editor()` method to define the fields/texts that will show on the event. +Your event is now fully functional, but in the visual editor, it is still blank. You will need to override the `build_event_editor()` method to define the fields/texts that will appear on the event. ```gdscript func build_event_editor() -> void: @@ -136,22 +148,22 @@ If you would like to learn more about events, I strongly suggest looking at the ## What is a subsystem? -A subsystem is a script that contains useful methods for game execution. Subsystems can be accessed as `Dialogic.SubsystemName.method()` when running the game. They should contain all of your extensions game code. +A subsystem is a script that contains useful methods for game execution. Subsystems can be accessed as `Dialogic.SubsystemName.method()` when running the game. They should contain all of your extension's code. For example, built-in subsystems include `Text, Portraits, Choices, Audio, etc.`. Their methods are used by the built-in events and can be used by your events as well. Additionally, it's good if a subsystem manages dialogic nodes. This could be done like this: ```gdscript func update_my_dialogic_nodes(some_setting): -    for node in get_tree().get_nodes_in_group("dialogic_custom_nodes"): -        node.update_something(some_setting) + for node in get_tree().get_nodes_in_group("dialogic_custom_nodes"): + node.update_something(some_setting) ``` ## Your custom subsystem A subsystem is a script inheriting `DialogicSubsystem`. It can override that class's methods. The most important methods you might want to override are `clear_game_state()` and `load_game_state()` for saving and loading, and `pause()` and `resume()` for pausing. -If you want save-persistent data, store it in the `Dialogic.current_state_info` dictionary. +If you want to save persistent data, store it in the `Dialogic.current_state_info` dictionary. --- @@ -180,16 +192,16 @@ Your animation script should look something like this (`bounce_in`, for example) extends DialogicAnimation func animate(): -    var tween := (node.create_tween() as Tween) -    node.scale = Vector2() -    node.modulate.a = 0 - -    tween.set_ease(Tween.EASE_IN_OUT) -    tween.set_trans(Tween.TRANS_SINE) -    tween.set_parallel() -    tween.tween_property(node, 'scale', Vector2(1,1), time).set_trans(Tween.TRANS_SPRING).set_ease(Tween.EASE_OUT) -    tween.tween_property(node, 'modulate:a', 1.0, time) -    tween.finished.connect(emit_signal.bind('finished_once')) + var tween := (node.create_tween() as Tween) + node.scale = Vector2() + node.modulate.a = 0 + + tween.set_ease(Tween.EASE_IN_OUT) + tween.set_trans(Tween.TRANS_SINE) + tween.set_parallel() + tween.tween_property(node, 'scale', Vector2(1,1), time).set_trans(Tween.TRANS_SPRING).set_ease(Tween.EASE_OUT) + tween.tween_property(node, 'modulate:a', 1.0, time) + tween.finished.connect(emit_signal.bind('finished_once')) ``` ```admonish note @@ -216,9 +228,9 @@ Importantly the name of your animation file will determine if it is a Join, Leav ## What are dialogic nodes? [Dialogic nodes](dialogic-nodes.md) are nodes that, in some way, execute something visibly, logically or audibly. -They are generally managed by a subsystem and are found because they are automatically added to a group. This makes sure it doesn't matter where in the scene tree or how many of them exist. +They are generally managed by a subsystem and are found because they are automatically added to a group. This makes sure it doesn't matter where they are in the scene tree or how many of them exist. -`DialogicNodes` do not need to be added by the `index.gd` file! +`DialogicNodes` does not need to be added to the `index.gd` file! --- @@ -227,14 +239,14 @@ They are generally managed by a subsystem and are found because they are automat An extension might want to add a dialogic settings editor. This is just a UI scene that has a script inheriting `DialogicSettingsPage`. - Overwrite some methods (just the ones that you need) -  - `_get_title()` -  - _get_priority() -> return an int that will influence the order of settings pages -  - _refresh() -> whenever the settings are opened -  - _about_to_close() -> whenever the settings editor closes -  - _get_info_section() -> return a node in your scene that will be used as an info section + - `_get_title()` + - _get_priority() -> return an integer that will influence the order of settings pages + - _refresh() -> whenever the settings are opened + - _about_to_close() -> whenever the settings editor closes + - _get_info_section() -> return a node in your scene that will be used as an info section Settings are usually saved either -  - in the `project settings` in a subcategory of dialogic (e.g. `dialogic/myextension/setting`): -    - `ProjectSettings.set_setting('dialogic/myextension/setting', some_value)` -  - You can also save/load editor settings with `DialogicUtil.set_editor_setting('setting', value)` and `DialogicUtil.get_editor_setting('setting')`. -    - These depend on the project + - in the `project settings` in a subcategory of dialogic (e.g. `dialogic/myextension/setting`): + - `ProjectSettings.set_setting('dialogic/myextension/setting', some_value)` + - You can also save/load editor settings with `DialogicUtil.set_editor_setting('setting', value)` and `DialogicUtil.get_editor_setting('setting')`. + - These depend on the project - Remember that all scripts in this scene must be in @tool mode.