diff --git a/docs/.circleci/circle_urls.sh b/docs/.circleci/circle_urls.sh deleted file mode 100644 index 22729ae..0000000 --- a/docs/.circleci/circle_urls.sh +++ /dev/null @@ -1,4 +0,0 @@ -REPO_ID=$(curl https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME} | jq --raw-output '.id') -echo "Repo ID is ${REPO_ID}" -BASEURL=https://${CIRCLE_BUILD_NUM}-${REPO_ID}-gh.circle-artifacts.com/0/${CIRCLE_PROJECT_REPONAME} -sed -i "26 s,.*,baseurl: $BASEURL,g" "_config.yml" diff --git a/docs/.circleci/config.yml b/docs/.circleci/config.yml deleted file mode 100644 index 36201d4..0000000 --- a/docs/.circleci/config.yml +++ /dev/null @@ -1,50 +0,0 @@ -version: 2.1 - -workflows: - version: 2 - - # The build workflow will build a preview for the site, intended for PRs - build: - jobs: - - build-site: - filters: - branches: - ignore: master - -build_jekyll: &build_jekyll - name: Jekyll Build - command: | - echo "Building RSE Blog for Preview" - cp ~/repo/.circleci/circle_urls.sh ~/repo/circle_urls.sh - cd ~/repo - chmod u+x circle_urls.sh - bash circle_urls.sh - bundle exec jekyll build - -jobs: - build-site: - docker: - - image: circleci/ruby:2.4.1 - working_directory: ~/repo - environment: - - JEKYLL_ENV: production - - NOKOGIRI_USE_SYSTEM_LIBRARIES: true - - BUNDLE_PATH: ~/repo/vendor/bundle - steps: - - checkout - - restore_cache: - keys: - - rubygems-v1 - - run: - name: Bundle Install - command: | - cd ~/repo - bundle check || bundle install - - save_cache: - key: rubygems-v1 - paths: - - vendor/bundle - - run: *build_jekyll - - store_artifacts: - path: ~/repo/_site - destination: docsy-jekyll diff --git a/docs/Gemfile b/docs/Gemfile index 38c3822..d424e25 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -9,20 +9,19 @@ ruby RUBY_VERSION # # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "jekyll", "~> 4.2.2" +# gem "jekyll", "~> 4.2.2" # This is the default theme for new Jekyll sites. You may change this to anything you like. # gem "minima" # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -#gem "github-pages", group: :jekyll_plugins +gem "github-pages", group: :jekyll_plugins # If you have any plugins, put them here! # group :jekyll_plugins do # gem "jekyll-github-metadata", "~> 1.0" # end -gem 'wdm', '>= 0.1.0' if Gem.win_platform? - +gem 'wdm', '>= 0.1.1' gem "webrick", "~> 1.8" diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 1a949bf..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -serve: - bundle exec jekyll serve --livereload diff --git a/docs/_config.yml b/docs/_config.yml index 795cb88..6a5df11 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -15,12 +15,11 @@ # in the templates via {{ site.myvariable }}. title: Godot State Charts -email: your-email@domain.com -author: derkork, Jan Thomä +email: info@godotneers.com +author: Jan Thomä description: > # this means to ignore newlines until "baseurl:" A state charts extension for Godot 4. -# DO NOT CHANGE THE LINE OF THIS FILE without editing .circleci/circle_urls.sh baseurl: "/godot-statecharts" # the subpath of your site, e.g. /blog # This is mostly for testing @@ -61,8 +60,7 @@ themeColor: red # purple, green, blue, orange, purple, grey fixedNav: 'true' # true or false permalink: /:year/:title/ -markdown: kramdown -exclude: [_site, CHANGELOG.md, LICENSE, README.md, vendor] +exclude: [ _site, CHANGELOG.md, LICENSE, README.md, vendor ] # Collections collections: @@ -77,15 +75,14 @@ defaults: type: "docs" values: layout: page - - - scope: + - scope: path: "" type: "pages" values: layout: "page" - - - scope: + - scope: path: "posts" type: "posts" values: layout: "post" + diff --git a/docs/_data/toc.yml b/docs/_data/toc.yml index 2d13fda..5a7a7a2 100644 --- a/docs/_data/toc.yml +++ b/docs/_data/toc.yml @@ -1,20 +1,20 @@ - title: "Home" url: "" -- title: "Instalation" +- title: "Installation & Updating" url: "installation" - title: "Usage" url: "usage" links: - - title: "States" - url: "usage/states" + - title: "Nodes" + url: "usage/nodes" - title: "Events and transitions" url: "usage/events-and-transitions" - title: "Debugging" url: "usage/debugging" -- title: "Stepping Mode" - url: "stepping-mode" -- title: "Tips & Tricks" - url: "tips-and-tricks" + - title: "Stepping Mode" + url: "usage/stepping-mode" + - title: "Tips & Tricks" + url: "usage/tips-and-tricks" - title: "Appendix" url: "appendix" - title: "FAQ" diff --git a/docs/_docs/installation.md b/docs/_docs/01_installation.md similarity index 87% rename from docs/_docs/installation.md rename to docs/_docs/01_installation.md index 29af24b..8a5cc37 100644 --- a/docs/_docs/installation.md +++ b/docs/_docs/01_installation.md @@ -1,13 +1,13 @@ --- layout: page -title: Installation +title: Installation and Updates permalink: /installation description: "Here you can find the installation instructions for the plugin." --- # {{ page.title }} -## Index +## Table of Contents - [Requirements](#requirements) - [Installation with the Godot Asset Library](#installation-with-the-godot-asset-library) - [Manual installation](#manual-installation) @@ -33,7 +33,7 @@ After you installed it, make sure you enable the plugin in the project settings: ## Installation with C# -If you want to use this library with C#, make sure you are using the .NET version of Godot 4. This can be downloaded from the [Godot download page](https://godotengine.org/download). The standard version of Godot 4 does not support C#. If you got Godot from Steam, you have the standard version and need to download the .NET version separately from the Godot website. There are additional installation steps for the Godot .NET version, so make sure you follow the instructions on the [Godot documentation](https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_basics.html). +If you want to use this library with C#, make sure you are using the .NET version of Godot 4. This can be downloaded from the [Godot download page](https://godotengine.org/download). The standard version of Godot 4 does not support C#. **If you got Godot from Steam, you have the standard version and need to download the .NET version separately from the Godot website.** There are additional installation steps for the Godot .NET version, so make sure you follow the instructions on the [Godot documentation](https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_basics.html). After you installed the plugin as described above, you may need to initialize your C# project if you haven't already done so. You can do this by going to the menu _Project_ -> _Tools_ -> _C#_ -> _Create C# solution_. diff --git a/docs/_docs/appendix.md b/docs/_docs/02_appendix.md similarity index 97% rename from docs/_docs/appendix.md rename to docs/_docs/02_appendix.md index cc8af53..a80d0d1 100644 --- a/docs/_docs/appendix.md +++ b/docs/_docs/02_appendix.md @@ -7,7 +7,7 @@ description: "Here you can find the appendix of the documentation." # Appendix -## Index +## Table of Contents - [Order of events](#order-of-events) - [Generic event handling rules](#generic-event-handling-rules) - [Example](#example) @@ -28,7 +28,7 @@ Whenever an event occurs, the state chart will try to find transitions that reac ### Example For this example we will use the following state chart: -![Example state chart for the order of events]({{ site.baseurl }}/assets/img/manual/order_of_events_chart.png) +![Example state chart for the order of events]({{ site.baseurl }}/assets/img/manual/order_of_events_chart.png){:class="native-width centered"} When the program starts, state _B_ is active. Since it is a parallel state, it will automatically activate its child states, _B1_ and _B2_. This is the starting position. diff --git a/docs/_docs/faq.md b/docs/_docs/03_faq.md similarity index 64% rename from docs/_docs/faq.md rename to docs/_docs/03_faq.md index 0636268..701becb 100644 --- a/docs/_docs/faq.md +++ b/docs/_docs/03_faq.md @@ -13,6 +13,10 @@ description: "Below you can find some common questions and answers related to th Make sure you enabled the plugin in the project settings. In the menu go to _Project_ -> _Project Settings_. This opens the project settings dialog. There select the _Plugins_ tab and tick the _Enable_ checkbox near the _Godot State Charts_ plugin. +### How can I find the currently active state? + +In a state chart multiple states can be active at the same time. In general, you should avoid tracking active states in your code - this is the responsibility of the state chart. Your code is responsible for _what_ happens, while the state chart is responsible for _when_ it happens. If you need to know whether a certain state is active, you can get a reference to that state's node (using Godot's built-in `get_node` or `GetNode` functions) and then check the `active` property of that node. + ### Can you backport the library to Godot 3? I'm afraid not. While it technically would be totally possible to do so, I don't have the bandwidth for maintaining two versions of the library. I prefer to focus on the latest version of Godot, which is currently 4. diff --git a/docs/_docs/usage/index.md b/docs/_docs/usage/01_index.md similarity index 90% rename from docs/_docs/usage/index.md rename to docs/_docs/usage/01_index.md index 77e106d..3e0883b 100644 --- a/docs/_docs/usage/index.md +++ b/docs/_docs/usage/01_index.md @@ -7,11 +7,13 @@ description: "The plugin adds a new node type called State Chart." # {{ page.title }} -## Index - +## Table of Contents +- [General usage](#general-usage) - [Examples](#examples) -The plugin adds a new node type called _State Chart_. This node represents your state chart and is the only node that your code will directly interact with. +## General usage + +The plugin adds several new node types to Godot. The main node is the [_State Chart_]({{site.baseurl}}/usage/nodes#the-state-chart-node) node. This node represents your state chart and is the only node that your code will directly interact with. Below this node you can add the root state of your state chart, this will usually be a _Compound State_ or a _Parallel State_. You can add as many states as you want to your state chart, but you can only have one root state. Below each state you can add _Transition_ nodes. These nodes define the transitions between states. You can add as many transitions as you want to any state. @@ -29,7 +31,7 @@ The new UI supports undo/redo, so you can undo the addition of a node or transit ## Examples -The plugin comes with a few examples. You can find them in the `godot_state_charts_examples` folder. To run an example, open and run it's main scene. The examples are: +The plugin comes with a few examples. You can find them in the `godot_state_charts_examples` folder (if you have chosen to import this folder into your project). To run an example, open and run it's main scene. The examples are: - `ant_hill` - a rudimentary ant hill simulation. The ants are controlled by a state chart that handles the different states of the ants such as searching for food, carrying food, returning to the nest, etc. This example shows how state charts can simplify a lot of the if-else logic that is often needed to implement AI. - `automatic_transitions` - an example that shows how to use automatic transitions that react to changes in expression properties. diff --git a/docs/_docs/usage/states.md b/docs/_docs/usage/02_nodes.md similarity index 63% rename from docs/_docs/usage/states.md rename to docs/_docs/usage/02_nodes.md index 1b52797..0019264 100644 --- a/docs/_docs/usage/states.md +++ b/docs/_docs/usage/02_nodes.md @@ -1,17 +1,16 @@ --- layout: page -title: States -permalink: /usage/states +title: Nodes +permalink: /usage/nodes description: "States are the building blocks from which you build your state charts." --- # {{ page.title }} -## Index - +## Table of Contents - [The State Chart Node](#the-state-chart-node) -- [The States](#the-states) -- [Connecting to state signals from code](#connecting-to-state-signals-from-code) +- [States](#states) + - [Connecting to state signals from code](#connecting-to-state-signals-from-code) - [Atomic states](#atomic-states) - [Compound states](#compound-states) - [Parallel states](#parallel-states) @@ -21,9 +20,9 @@ description: "States are the building blocks from which you build your state cha ## The _State Chart_ Node - The _State Chart_ node is your main way of interacting with the state charts. It allows you to send events to the state chart using the `send_event(event)` method. You can also set expression properties with the `set_expression_property(name, value)` function, which can later be used by expression guards to determine whether a certain transition should be taken (see the section on expression guards for more information). +The ![State Chart node icon]({{ site.baseurl }}/assets/img/manual/icons/state_chart.svg){:class="state-icon"} _State Chart_ node is your main way of interacting with the state charts. It allows you to send events to the state chart using the `send_event(event)` method. You can also set expression properties with the `set_expression_property(name, value)` function, which can later be used by [expression guards]({{site.baseurl}}/usage/events-and-transitions#expression-guards) to determine whether a certain transition should be taken (see the section on expression guards for more information). -## The States +## States States are the building blocks from which you build your state charts. A state can be either active or inactive. On start the root state of the state chart will be activated. When a state has child states, one or more of these child states will be activated as well. States provide a range of signals which you can use to react to state changes or to execute code while the state is active. The following signals are available: @@ -37,12 +36,11 @@ States are the building blocks from which you build your state charts. A state c - `state_unhandled_input(input_event)` - called when unhandled input is received while the state is active. Again this is useful to limit input to certain states. - `transition_pending(initial_delay, remaining_delay)` - called every frame while a [delayed transition]({{ site.baseurl }}/usage/events-and-transitions#delayed-transitions) is pending for this state. The initial and remaining delay of the transition in seconds are passed as parameters. This can be used to drive progress bars or cooldown indicators or trigger additional effects at certain time indices during the transition. An example of this can be found in the `cooldown` demo. Note, that this is never called for transitions without a delay. -## Connecting to state signals from code +### Connecting to state signals from code Most of the time you will want to connect signals directly from the editor UI, as this is where you edit your state chart. However, if you wish, you can of course also connect to the signals from code by using the `connect` function like with any other Node in Godot. For example, to connect to the `state_entered` signal you can do the following: ```gdscript - func _ready(): var state: State = %ActiveState state.state_entered.connect(_on_state_entered) @@ -78,15 +76,15 @@ If you want to connect signals from the editor UI you can just do it like you wo ## Atomic states - Atomic states are the most basic type of state. They cannot have child states. Atomic states have no additional properties. +_Atomic states_ ![Atomic State icon]({{ site.baseurl }}/assets/img/manual/icons/atomic_state.svg){:class="state-icon"} are the most basic type of state. They cannot have child states. Atomic states have no additional properties. ## Compound states - Compound states are states which have at least one child state (though having at least two child states makes more sense). Only one child state of a compound state can be active at any given time. Compound states have the following properties: +_Compound states_ ![Compound state icon]({{ site.baseurl }}/assets/img/manual/icons/compound_state.svg){:class="state-icon"} are states which have at least one child state (though having at least two child states makes more sense). Only one child state of a compound state can be active at any given time. Compound states have the following properties: -- _Initial state_ - this property determines which child state will be activated when the compound state is entered directly. You can always activate a child state by explicitly transitioning to it. If you do not set an initial state then no child state will be activated and an error will be printed to the console. +![Compound state properties]({{ site.baseurl }}/assets/img/manual/compound_state.png){:class="native-width centered"} -Compound state properties +- _Initial state_ - this property determines which child state will be activated when the compound state is entered directly. You can always activate a child state by explicitly transitioning to it. If you do not set an initial state then no child state will be activated and an error will be printed to the console. Compound states have two signals in addition to the signals that all states have, which allow you to run common code whenever a child state of the compound state is entered/exited: @@ -95,31 +93,28 @@ Compound states have two signals in addition to the signals that all states have ## Parallel states - Parallel states are similar to compound states in that they can have multiple child states. However, all child states of a parallel state are active at the same time when the parallel state is active. They allow you to model multiple states which are independent of each other. As such they are a great tool for avoiding combinatorial state explosion that you can get with simple state machines. Parallel states have no additional properties. +_Parallel states_ ![Parallel state icon]({{ site.baseurl }}/assets/img/manual/icons/parallel_state.svg){:class="state-icon"} are similar to compound states in that they can have multiple child states. However, all child states of a parallel state are active at the same time when the parallel state is active. They allow you to model multiple states which are independent of each other. As such they are a great tool for avoiding combinatorial state explosion that you can get with simple state machines. Parallel states have no additional properties. ## History states - History states are pseudo-states. They are not really a state but rather activate the last active state when being transitioned to. They can only be used as child states of compound states. They are useful when you temporarily want to leave a compound state and then return to the state you were in before you left. History states have the following properties: +History states ![History state icon]({{ site.baseurl }}/assets/img/manual/icons/history_state.svg){:class="state-icon"} are so-called "pseudo-states". They are not really a state but rather activate the last active state when you transition to them. They can only be used as child states of compound states. They are useful when you temporarily want to leave a compound state and then return to the state you were in before you left. History states have the following properties: +![History state properties]({{ site.baseurl }}/assets/img/manual/history_state.png){:class="native-width centered"} - _Deep_ - if true the history state will capture and restore the state of the whole sub-tree below the compound state. If false the history state will only capture and restore the last active state of its immediate parent compound state. - _Default state_ - this is the state which will be activated if the history state is entered and no history has been captured yet. If you do not set a default state, the history state will not activate any state when it is entered and an error will be printed to the console. - -History state properties - -To use a history state, set up a transition that transitions directly to the history state. This will restore the last known state or activate the default state if no history has been captured yet. If your compound state has a history state as a child but you do not want to restore the history when entering the compound state, you can transition to the compound state directly. This will activate the initial state of the compound state and will not restore the history. Also check the history state example in the examples folder. +To use a history state, set up a transition that transitions directly to the history state. This will restore the last known state or activate the default state if no history has been captured yet. If your compound state has a history state as a child, but you do not want to restore the history when entering the compound state, you can transition to the compound state directly. This will activate the initial state of the compound state and will not restore the history. Also check the history state example in the examples folder. ## Animation tree states -> ⚠️ **Note**: this feature is currently experimental and may change or be replaced in the future. +> ⚠️ **Note**: this feature is currently experimental and may change or be removed in the future. - Animation tree states are a variation of atomic states. They can be linked to an animation tree. When an animation tree state is activated it will ask the animation tree to travel to the same state (the animation tree state and the state inside the animation tree should have the same name). This can be used to control animation trees with the same state chart events that you use to control your game logic. Animation tree states have the following properties: +_Animation tree states_ ![Animation tree state icon]({{ site.baseurl }}/assets/img/manual/icons/animation_tree_state.svg){:class="state-icon"} are a variation of atomic states. They can be linked to an animation tree. When an animation tree state is activated it will ask the animation tree to travel to the same state (the animation tree state and the state inside the animation tree should have the same name). This can be used to control animation trees with the same state chart events that you use to control your game logic. Animation tree states have the following properties: +![Animation tree state properties]({{ site.baseurl }}/assets/img/manual/animation_tree_state.png){:class="native-width centered"} - _Animation tree_ - the animation tree that should be controlled by the animation tree state. - _State Name_ - the name of the state inside the animation tree that should be activated when the animation tree state is activated. This is optional, if you do not set a state name, the animation tree state will activate the state with the same name as the animation tree state. -Animation tree state properties - Animation tree states are usually independent of the rest of the states, so it is usually a good idea to use a parallel state to separate them from the rest of the states. ![Separation of animation tree states]({{ site.baseurl }}/assets/img/manual/animation_tree_state_separation.png) @@ -127,16 +122,15 @@ Animation tree states are usually independent of the rest of the states, so it i ## Animation player states -> ⚠️ **Note**: this feature is currently experimental and may change or be replaced in the future. +> ⚠️ **Note**: this feature is currently experimental and may change or be removed in the future. - Animation player states are similar to animation tree states. They can be linked to an animation player. When an animation player state is activated it will ask the animation player to play the same animation (the animation player state and the animation inside the animation player should have the same name). This can be used to control animation players with the same state chart events that you use to control your game logic. Animation player states have the following properties: +_Animation player states_ ![Animation player state icon]({{ site.baseurl }}/assets/img/manual/icons/animation_player_state.svg){:class="state-icon"} are similar to animation tree states. They can be linked to an animation player. When an animation player state is activated it will ask the animation player to play the same animation (the animation player state and the animation inside the animation player should have the same name). This can be used to control animation players with the same state chart events that you use to control your game logic. Animation player states have the following properties: +![Animation player state properties]({{ site.baseurl }}/assets/img/manual/animation_player_state.png){:class="native-width centered"} - _Animation player_ - the animation player that should be controlled by the animation player state. - _Animation Name_ - the name of the animation inside the animation player that should be played when the animation player state is activated. This is optional, if you do not set an animation name, the animation player state will play the animation with the same name as the animation player state. - _Custom Blend_ - a custom animation blend time. The default is `-1` which will use the animation player's default blend time. - _Custom Speed_ - a custom animation speed. The default is `1.0` which will play the animation forwards with normal speed. You can use negative values to play the animation backwards or values greater than `1.0` to play the animation faster. - _From End_ - if true the animation will be played from the end to the beginning. This is useful if you want to play an animation backwards. Note that you will still need to set the custom speed to a negative value to actually play the animation backwards. -Animation player state properties - Similar to animation tree states, animation player states are usually independent of the rest of the states, so it is usually a good idea to use a parallel state to separate them from the rest of the states. diff --git a/docs/_docs/usage/events-and-transitions.md b/docs/_docs/usage/03_events_and_transitions.md similarity index 86% rename from docs/_docs/usage/events-and-transitions.md rename to docs/_docs/usage/03_events_and_transitions.md index 4e6dacf..e9d5f5f 100644 --- a/docs/_docs/usage/events-and-transitions.md +++ b/docs/_docs/usage/03_events_and_transitions.md @@ -7,8 +7,9 @@ description: "Transitions allow you to switch between states." # {{ page.title }} -## Index +## Table of Contents +- [Transitions](#transitions) - [Multiple transitions on the same state](#multiple-transitions-on-the-same-state) - [Event selection and management](#event-selection-and-management) - [Transition taken signal](#transition-taken-signal) @@ -18,7 +19,8 @@ description: "Transitions allow you to switch between states." - [Expression guards](#expression-guards) - [Event queueing mechanism](#event-queueing-mechanism) - Transitions allow you to switch between states. Rather than directly switching the state chart to a certain state, you send events to the state chart. You can send events to the state chart by calling the `send_event(event)` method. To send an event you first need to get hold of the state chart node. A simple way to do this is to use the `get_node` function: +## Transitions +_Transitions_ ![Transition icon]({{ site.baseurl }}/assets/img/manual/icons/transition.svg){:class="state-icon"} allow you to switch between states. Rather than directly switching the state chart to a certain state, you send events to the state chart. You can send events to the state chart by calling the `send_event(event)` method. To send an event you first need to get hold of the state chart node. A simple way to do this is to use the `get_node` function: ```gdscript # my_node.gd @@ -82,11 +84,11 @@ A single state can have multiple transitions. If this is the case, all transitio Starting with version 0.12.0 the plugin provides a dropdown for events in the editor UI. This dropdown allows you to quickly select an event from a list of all events that are currently used in the state chart. This helps to avoid typos and makes it easier to find the event you are looking for. -![Event dropdown]({{ site.baseurl }}/assets/img/manual/event_dropdown.png) +![Event dropdown]({{ site.baseurl }}/assets/img/manual/event_dropdown.png){:class="native-width centered"} The dropdown also has "Manage..." entry which allows you to rename events that are used in the state chart. This is useful if you want to rename an event that is used in multiple transitions. -![Renaming an event]({{ site.baseurl }}/assets/img/manual/event_rename.png) +![Renaming an event]({{ site.baseurl }}/assets/img/manual/event_rename.png){:class="native-width centered"} In the dialog, select the event you want to rename and enter the new name. All transitions in the current state chart that use the event will be updated automatically. You can undo the renaming by pressing `Ctrl+Z`. Also note, that renaming an event will not rename the event in your code, so you will have to update the event name in your code manually. @@ -100,7 +102,7 @@ The signal is only emitted when the transition is taken, not when it is pending. It is possible to have transitions with an empty _Event_ field. These transitions will be evaluated whenever you change a state, send an event or set an expression property (see [expression guards](#expression-guards)). This is useful for modeling [condition states](https://statecharts.dev/glossary/condition-state.html) or react to changes in expression properties. Usually you will put a guard on such an automatic transition to make sure it is only taken when a certain condition is met. -![Alt text]({{ site.baseurl }}/assets/img/manual/immediate_transition.png) +![Automatic transition]({{ site.baseurl }}/assets/img/manual/immediate_transition.png){:class="native-width centered"} Note that automatic transitions will still only be evaluated for currently active states. @@ -116,11 +118,11 @@ Transition delay is an expression, which means you can not only put in a number A transition can have a guard which determines whether the transition should be taken or not. If a transition reacts to an event the transition's guard will be evaluated. If the guard evaluates to `true` the transition will be taken. Otherwise the next transition which reacts to the event will be checked. If a transition has no guard, it will always be taken. Guards can be nested to create more complex guards. The following guards are available: -- _AllOfGuard_ - this guard evaluates to `true` if all of its child guards evaluate to `true` (logical AND). -- _AnyOfGuard_ - this guard evaluates to `true` if any of its child guards evaluate to `true` (logical OR). -- _NotGuard_ - this guard evaluates to the opposite of its child guard. -- _StateIsActiveGuard_ - this guard allows you to configure and monitor a state. The guard evaluates to `true` if the state is active and to `false` if the state is inactive. -- _ExpressionGuard_ - this guard allows you to use expressions to determine whether the transition should be taken or not. +- _AllOfGuard_ ![AllOfGuard icon]({{ site.baseurl }}/assets/img/manual/icons/all_of_guard.svg){:class="state-icon"} - this guard evaluates to `true` if all of its child guards evaluate to `true` (logical AND). +- _AnyOfGuard_ ![AnyOfGuard icon]({{ site.baseurl }}/assets/img/manual/icons/any_of_guard.svg){:class="state-icon"} - this guard evaluates to `true` if any of its child guards evaluate to `true` (logical OR). +- _NotGuard_ ![NotGuard icon]({{ site.baseurl }}/assets/img/manual/icons/not_guard.svg){:class="state-icon"} - this guard evaluates to the opposite of its child guard. +- _StateIsActiveGuard_ ![StateIsActiveGuard icon]({{ site.baseurl }}/assets/img/manual/icons/state_is_active_guard.svg){:class="state-icon"} - this guard allows you to configure and monitor a state. The guard evaluates to `true` if the state is active and to `false` if the state is inactive. +- _ExpressionGuard_ ![ExpressionGuard icon]({{ site.baseurl }}/assets/img/manual/icons/expression_guard.svg){:class="state-icon"} - this guard allows you to use expressions to determine whether the transition should be taken or not. ## Expression guards Expression guards give you the most flexibility when it comes to guards. You can use expressions to determine whether a transition should be taken or not. Expression guards are evaluated using the [Godot Expression](https://docs.godotengine.org/en/stable/classes/class_expression.html) class. You can add so-called _expression properties_ to the state chart node by calling the `set_expression_property(name, value)` method. @@ -154,14 +156,14 @@ public class MyNode : Node These expression properties can then be used in your expressions. The following example shows how to use expression guards to check whether the player's health is below 50%: -![Example of an expression guard for transitioning into berserk mode when player's health sinks below 50%]({{ site.baseurl }}/assets/img/manual/expression_guard.png) +![Example of an expression guard for transitioning into berserk mode when player's health sinks below 50%]({{ site.baseurl }}/assets/img/manual/expression_guard.png){:class="native-width centered"} > **Note:** all expressions for the expression guards are written in GDScript even if you use C# to interact with the StateChart. It is important to make sure that your code sets any expression property used by the guard before the guard is first evaluated. For example, if your guard uses a `player_health` expression property, you will need to call `set_expression_property('player_health', some_health)` _before_ the guard is evaluated. Otherwise the guard will not be able to evaluate the expression because it has no value for `player_health`. You can set some sane initial values in two ways: 1. Starting with version 0.16.0 you can set initial values for expression properties in the state chart inspector: - ![Setting initial properties in the state chart inspector.]({{ site.baseurl }}/assets/img/manual/initial_property_values.png) + ![Setting initial properties in the state chart inspector.]({{ site.baseurl }}/assets/img/manual/initial_property_values.png){:class="native-width centered"} 2. You can use the `_ready`/`_Ready` method to initialize all expression properties used in your state chart with some sane default value by calling `set_expression_property`. ## Event queueing mechanism diff --git a/docs/_docs/usage/debugging.md b/docs/_docs/usage/04_debugging.md similarity index 91% rename from docs/_docs/usage/debugging.md rename to docs/_docs/usage/04_debugging.md index 167db7d..965c862 100644 --- a/docs/_docs/usage/debugging.md +++ b/docs/_docs/usage/04_debugging.md @@ -7,14 +7,15 @@ description: "When the game is running it is very useful to see the current stat # {{ page.title }} -## Index +## Table of Contents - [Debugging in-game with the state chart debugger](#debugging-in-game-with-the-state-chart-debugger) +- [Changing the watched node at runtime](#changing-the-watched-node-at-runtime) - [Debugging in the editor](#debugging-in-the-editor) ## Debugging in-game with the state chart debugger - When the game is running it is very useful to see the current state of the state chart for debugging purposes. For this, this library contains a state chart debugger that you can add to your scene. You can add it to your scene by pressing the "Instantiate child scene" icon above the node tree and then looking for "debugger": +When the game is running it is very useful to see the current state of the state chart for debugging purposes. For this, this library contains a _State Chart Debugger_ ![State chart debugger icon]({{ site.baseurl }}/assets/img/manual/icons/state_chart_debugger.svg){:class="state-icon"} that you can add to your scene by pressing the "Instantiate child scene" icon above the node tree and then looking for "debugger": ![Adding the state chart debugger]({{ site.baseurl }}/assets/img/manual/add_statechart_debugger.gif) @@ -24,6 +25,8 @@ description: "When the game is running it is very useful to see the current stat The state chart debugger has a property _Initial node to watch_ where you can set a node that should be watched. It doesn't necessarily need to be a state chart node, the debugger will search for a state chart anywhere below the node you set. This is useful when you have the state chart nested in a sub-scene and you want to watch the state chart from the root scene where you don't have access to the state chart node. +## Changing the watched node at runtime + You can also use the `debug_node` function of the state chart debugger to change the node that is being watched at runtime. For example you could add code that changes the debugged node when clicking on a unit or object in your game ```gdscript @@ -96,7 +99,7 @@ Starting with version 0.10.0 the plugin contains an in-editor debugger, which sh This feature is opt-in, so for a state chart to appear in the debugger, you need to set the _Track in Editor_ property of the state chart to `true`. -![Track the current state chart in the editor]({{ site.baseurl }}/assets/img/manual/track_in_editor.png) +![Track the current state chart in the editor]({{ site.baseurl }}/assets/img/manual/track_in_editor.png){:class="native-width centered"} Once this is set, the state chart will appear in the in-editor debugger when the game is running. From there you can select a state chart in the tree on the left and see its current state and history on the right. As with the in-game debugger you have flags to toggle whether events, state changes and transitions should appear in the history. diff --git a/docs/_docs/stepping-mode.md b/docs/_docs/usage/05_stepping_mode.md similarity index 97% rename from docs/_docs/stepping-mode.md rename to docs/_docs/usage/05_stepping_mode.md index 3c32802..2f4b9d8 100644 --- a/docs/_docs/stepping-mode.md +++ b/docs/_docs/usage/05_stepping_mode.md @@ -1,7 +1,7 @@ --- layout: page title: Stepping Mode -permalink: /stepping-mode +permalink: /usage/stepping-mode description: "Here you can find instructions about how to use the stepping mode." --- diff --git a/docs/_docs/tips-and-tricks.md b/docs/_docs/usage/06_tips_and_tricks.md similarity index 92% rename from docs/_docs/tips-and-tricks.md rename to docs/_docs/usage/06_tips_and_tricks.md index 63cb4d3..194c8a4 100644 --- a/docs/_docs/tips-and-tricks.md +++ b/docs/_docs/usage/06_tips_and_tricks.md @@ -1,13 +1,13 @@ --- layout: page title: Tips & Tricks -permalink: /tips-and-tricks +permalink: /usage/tips-and-tricks description: "Here you can find tips and tricks that can help you using the plugin." --- # {{ page.title }} -## Index +## Table of Contents - [Keep state and logic separate](#keep-state-and-logic-separate) - [Remember that events bubble up in the chart tree](#remember-that-events-bubble-up-in-the-chart-tree) - [Give everything meaningful names](#give-everything-meaningful-names) @@ -15,7 +15,7 @@ description: "Here you can find tips and tricks that can help you using the plug ## Keep state and logic separate -State charts work best when you keep the state and the logic separate. This means that the state charts should contain all the rules for changing states while your code should only contain the logic that is executed when being in a state or when entering or leaving a state. You should not track the current state in your code, that is the responsibility of the state chart. The `StateChart` class deliberately does not expose the current state of the state chart for this reason. +State charts work best when you keep the state and the logic separate. This means that the state charts should contain all the rules for changing states while your code should only contain the logic that is executed when being in a state or when entering or leaving a state. You should not track the current state in your code, that is the responsibility of the state chart. Also, be aware that there can be multiple active states at the same time, so there is no single "current state" that you can track in your code. Instead, use the provided state events to trigger logic in your code. Many times you don't even need to write any code. For example if you have a bomb that explodes and you want to play a sound when it enters the _Exploding_ state, you can simply link up the `state_entered` signal of the _Exploding_ state to the `play` function of your audio player. @@ -52,7 +52,7 @@ private void OnJumpEnabledStatePhysicsProcessing(float delta) When you have multiple states that need to react on the same event, you can handle the event in the parent state. For example in the platformer demo, the frog can be in multiple different states while it is airborne. -![Sub-states of the airborne state]({{ site.baseurl }}/assets/img/manual/airborne_substates.png) +![Sub-states of the airborne state]({{ site.baseurl }}/assets/img/manual/airborne_substates.png){:class="native-width centered"} However no matter in which specific airborne state the frog is, once it lands on the ground it always should transition back to the _Grounded_ state. Therefore the transition for handling this has been added to the _Airborne_ state. This way the transition will be taken no matter in which specific airborne state the frog is. Since no sub-state of _Airborne_ (_CoyoteJumpEnabled_, _DoubleJumpEnabled_, _CannotJump_) handles the event, the event will bubble up to the parent state _Airborne_ and the transition will be taken. @@ -64,4 +64,4 @@ Because both states and transitions are nodes, it is very easy to rename them in Godot has a very nice built-in comment field named "Editor Description". Use this to write down some thoughts about why a state or transition exists and how it works in conjunction with other states and transitions. This is especially useful when you have a complex state chart with many states and transitions. Just like you write comments for your code, it is a good idea to write comments for your state charts. -![An example of the editor description]({{ site.baseurl }}/assets/img/manual/editor_description.png) +![An example of the editor description]({{ site.baseurl }}/assets/img/manual/editor_description.png){:class="native-width centered"} diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html index 2d59d45..3d58e5d 100755 --- a/docs/_includes/footer.html +++ b/docs/_includes/footer.html @@ -1,7 +1,7 @@