behavior_tree 0.1.10 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da63d959db3394cf36424a76f36a06d4b30c3ccd97e2f8a0c2dbfabff0b55819
4
- data.tar.gz: d433e361299388c9ad10c2c51f20a71a39dc66927939b748486633f3d3cad645
3
+ metadata.gz: 6eb178547f7b18faf513a60dc91f785a977e5fe7e2884d77ec8f365dd37e55da
4
+ data.tar.gz: 64e1f312b7028ec33749389e8ee13329c33712d35dc85afc9a0ebe84a5edf8a2
5
5
  SHA512:
6
- metadata.gz: 4d7bc4c9956c6b9228bff0c87f843543ab933ad1e58a94f47f83421426eebd56cf91d6e15325eef15359716dce0ac56c6fff0aac0b5ba90b18a077d2a02a25f2
7
- data.tar.gz: 53b998db96a7976336ecb1fc3e6e0315def2c97485aeedfb40fd3d03abc1ec654b781e32f7bc1df14a413f9a3ca8fceb83ec3241f46dd3b1db73d2ac0d1e8444
6
+ metadata.gz: 2f553d35fc13a331543cd1df25a169f20c1bbf0cf8fef526b081e5243411087cd7a0f0cdc797e59e78e83cb070a228c98cbf21fe32cd3206162f9dda1ab8b0c2
7
+ data.tar.gz: 43e2ec00bf7cc6f860dc35852853fbb7e6ae879267ca2848acd7c7c8428c7fefbf6e60ec18f4f79db53cc3bf3623528a413224324cba8f57b1b027397af471c5
data/CODE_OF_CONDUCT.md CHANGED
@@ -59,7 +59,7 @@ representative at an online or offline event.
59
59
  ## Enforcement
60
60
 
61
61
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
- reported to the community leaders responsible for enforcement at felovilches@gmail.com.
62
+ reported to the community leaders responsible for enforcement at developer@chrisvilches.com.
63
63
  All complaints will be reviewed and investigated promptly and fairly.
64
64
 
65
65
  All community leaders are obligated to respect the privacy and security of the
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- behavior_tree (0.1.10)
4
+ behavior_tree (1.1.0)
5
5
  colorize (~> 0.8.1)
6
6
 
7
7
  GEM
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Felo Vilches
3
+ Copyright (c) 2021 Chris Vilches
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -5,7 +5,11 @@
5
5
  A robust and customizable Ruby gem for creating Behavior Trees, used in games, AI, robotics, and more.
6
6
 
7
7
  <p align="center">
8
- <img src="https://github.com/FeloVilches/ruby-behavior-tree/blob/main/assets/logo.png?raw=true" />
8
+ <img src="https://github.com/ChrisVilches/ruby-behavior-tree/blob/main/assets/logo.png?raw=true" />
9
+ </p>
10
+
11
+ <p align="center">
12
+ <img src="https://github.com/ChrisVilches/ruby-behavior-tree/blob/main/assets/tree_animation.gif?raw=true" />
9
13
  </p>
10
14
 
11
15
  ## Quick start
@@ -157,8 +161,8 @@ another_tree.print
157
161
  * [Custom condition](#custom-condition)
158
162
  - [Node API](#node-api)
159
163
  * [Status](#status)
160
- * [tick!](#tick-)
161
- * [halt!](#halt-)
164
+ * [tick!](#tick)
165
+ * [halt!](#halt)
162
166
  * [Status related callbacks and hooks](#status-related-callbacks-and-hooks)
163
167
  - [Add custom nodes to the DSL](#add-custom-nodes-to-the-dsl)
164
168
  - [Troubleshoot and debug your trees](#troubleshoot-and-debug-your-trees)
@@ -181,6 +185,8 @@ In simple words, it's a modular way to describe your program's control flow, in
181
185
 
182
186
  ### Ticking the tree
183
187
 
188
+ The tick is the most important part of using a behavior tree. When you tick the root node of a tree, it will propagate it by ticking its children, which in turn will tick their children. Tasks (leaf nodes) are executed when the tick reaches them. Non-leaf nodes would execute their own logic when they are ticked (e.g. decoration logic, executing a sequence, etc).
189
+
184
190
  ```ruby
185
191
  my_tree.tick!
186
192
 
@@ -191,7 +197,7 @@ my_tree.tick!
191
197
 
192
198
  Each node has a status, which can have three possible values:
193
199
 
194
- 1. `success` which is usually returned by a task when it completes successfully, by conditional nodes when the condition they evaluate is true, or when nodes have never been set to run. Since this is the default status of all nodes, a node is in `success` status if it has never been ticked, or if it has been halted (using `halt!`).
200
+ 1. `success` which is returned in certain situations depending on the node type, but usually indicating that the operation they are in charge of was completed. Tasks usually return `success` when they execute/complete successfully, sequences return `success` when the entire sequence is executed successfully, and so on. Since this is the default status of all nodes, a node is in `success` status if it has never been ticked, or if it has been halted (using `halt!`).
195
201
  2. `running` which is returned by nodes that are currently executing.
196
202
  3. `failure` which is returned to signal that execution failed.
197
203
 
@@ -259,11 +265,11 @@ end
259
265
 
260
266
  #### Control nodes
261
267
 
262
- A control node decides the flow of the execution. In simpler words, it uses a certain logic to decide which branch to execute. This is where most of the similarities with a simple `if-else` come from.
268
+ A control node decides the flow of the execution. In simpler words, it uses a certain logic to decide which branch to execute. It could be one branch, multiple branches, or all of them.
263
269
 
264
270
  A control node cannot be a leaf (i.e. it must have children).
265
271
 
266
- There are two types of control nodes, and custom ones can be easily created ([see examples of custom control nodes](#custom-control-node)).
272
+ By default, there are two types of control nodes, and custom ones can be easily created. (See: [Examples of custom control nodes](#custom-control-node)).
267
273
 
268
274
  1. **Sequence:**
269
275
  a. Begins executing the first child node.
@@ -277,7 +283,7 @@ There are two types of control nodes, and custom ones can be easily created ([se
277
283
  d. If child returns `failure`, then continue with the next child.
278
284
  e. If no node ever returned `success`, then return `failure`.
279
285
 
280
- [Learn about "halting nodes" and what it means.](#halt-)
286
+ [Learn about "halting nodes" and what it means.](#halt)
281
287
 
282
288
  When a control node is ticked, by default it traverses children and ticks them using this logic:
283
289
 
@@ -327,7 +333,7 @@ By default the decorator nodes present in this library are:
327
333
  | Repeater | `BehaviorTree::Decorators::Repeater` | `repeater` or `rep` | Ticks the child again N times while it's returning `success`. |
328
334
  | Retry | `BehaviorTree::Decorators::Retry` | `re_try` | Ticks the child again N times while it's returning `failure`. |
329
335
 
330
- **Example #1: Creating a tree with many decorators**
336
+ **Example #1: Creating a tree with some decorators**
331
337
 
332
338
  ```ruby
333
339
  my_tree = BehaviorTree::Builder.build do
@@ -523,7 +529,7 @@ class AllOrNothing < ControlNodeBase
523
529
  end
524
530
  ```
525
531
 
526
- Note that under the hood, `tick_each_children` uses the strategy defined (i.e. `shuffle` method), and traverses its children while also ticking them. You don't need to send `tick!` manually to the child. The code defined in `on_tick` is executed *right after* the child is ticked.
532
+ Note that under the hood, `tick_each_children` uses the strategy defined (i.e. `shuffle` method), and traverses its children while also ticking them. You don't need to send `tick!` manually to the child. The code in the block given to `tick_each_children` is executed *right after* the child is ticked.
527
533
 
528
534
  ### Custom decorator
529
535
 
@@ -560,7 +566,7 @@ class CustomCondition < BehaviorTree::Decorators::Condition
560
566
  end
561
567
  ```
562
568
 
563
- Or using inline logic in the DSL. When using the DSL, before starting the block (i.e. where the child is defined), you must pass a `lambda` which receives two parameters (both optional), `context` and `node` (the `self` of the condition node).
569
+ Or create condition nodes using inline lambdas in the DSL. When using the DSL, before starting the block (i.e. where the child is defined), you must pass a `lambda` which receives two parameters (both optional), `context` and `node` (which is the `self` of the condition node).
564
570
 
565
571
  ```ruby
566
572
  my_tree = BehaviorTree::Builder.build do
@@ -583,7 +589,7 @@ my_tree.print
583
589
  # └─task success (0 ticks)
584
590
  ```
585
591
 
586
- **Note:** Other behavior tree implementations prefer the use of `sequence` control nodes, and placing conditional nodes as a leaves, but with the role of simply returning `failure` or `success`. Since sequences execute the next node only if the previous one succeeded, this also works as a conditional node. In this implementation, however, both patterns are available and you are free to choose which one to use.
592
+ **Note:** Other behavior tree implementations prefer the use of `sequence` control nodes, and placing conditional nodes as leaves, but with the role of simply returning `failure` or `success`. Since sequences execute the next node only if the previous one succeeded, it would also behave like a conditional node, preventing the next nodes in the sequence from executing if the condition failed. In this implementation, however, both patterns are available and you are free to choose which one to use.
587
593
 
588
594
  ## Node API
589
595
 
@@ -698,12 +704,16 @@ The second line of the output is the `puts` of the actual task logic. The third
698
704
 
699
705
  **on_started_running**
700
706
 
701
- Similar to `on_status_change`, but only triggers when the node has been set to `running`.
707
+ Similar to `on_status_change`, but only triggers when the node has been set to `running` (changed from a status other than `running`.
708
+
709
+ In some implementations, this is called `initialization`.
702
710
 
703
711
  **on_finished_running**
704
712
 
705
713
  Similar to `on_status_change`, but only triggers when the node has been set to a status other than `running`.
706
714
 
715
+ In some implementations, this is called `shutdown`.
716
+
707
717
  ## Add custom nodes to the DSL
708
718
 
709
719
  You can register new nodes to be used in the DSL, take for example the following code:
@@ -790,7 +800,7 @@ my_tree.print
790
800
  The above code generates the following output:
791
801
 
792
802
  <p align="center">
793
- <img src="https://github.com/FeloVilches/ruby-behavior-tree/blob/main/assets/printed_tree.jpg?raw=true" width="400"/>
803
+ <img src="https://github.com/ChrisVilches/ruby-behavior-tree/blob/main/assets/printed_tree.jpg?raw=true" width="400"/>
794
804
  </p>
795
805
 
796
806
  In the example above, you can see that the bottom nodes haven't been ticked at all. Node starvation might occur for various reasons, such as having a `force_failure` node as one of the children of a `sequence` (the nodes after the `force_failure` would all be prevented from executing).
@@ -830,7 +840,7 @@ Keep in mind this is only for development purposes, and the generated trees don'
830
840
 
831
841
  ## Contributing
832
842
 
833
- Bug reports and pull requests are welcome on GitHub at https://github.com/FeloVilches/ruby-behavior-tree. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/FeloVilches/ruby-behavior-tree/blob/main/CODE_OF_CONDUCT.md).
843
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ChrisVilches/ruby-behavior-tree. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ChrisVilches/ruby-behavior-tree/blob/main/CODE_OF_CONDUCT.md).
834
844
 
835
845
 
836
846
  ## License
@@ -839,4 +849,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
839
849
 
840
850
  ## Code of Conduct
841
851
 
842
- Everyone interacting in the Behavior Tree project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/FeloVilches/ruby-behavior-tree/blob/main/CODE_OF_CONDUCT.md).
852
+ Everyone interacting in the Behavior Tree project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ChrisVilches/ruby-behavior-tree/blob/main/CODE_OF_CONDUCT.md).
@@ -5,15 +5,21 @@ module BehaviorTree
5
5
  # If there's at least one node with 'running' status, then iterate starting from there, in order.
6
6
  # Else, iterate all nodes.
7
7
  module PrioritizeRunning
8
+ private
9
+
8
10
  def prioritize_running
9
- idx = @children.find_index { |child| child.status.running? }.to_i
11
+ @first_running_idx = children.find_index { |child| child.status.running? }.to_i if must_recompute_idx?
10
12
 
11
13
  Enumerator.new do |y|
12
- @children[idx..].each do |child|
14
+ children[@first_running_idx..].each do |child|
13
15
  y << child
14
16
  end
15
17
  end
16
18
  end
19
+
20
+ def must_recompute_idx?
21
+ !@first_running_idx || !children[@first_running_idx].status.running?
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -7,6 +7,10 @@ module BehaviorTree
7
7
  # Algorithm to print tree.
8
8
  module Printer
9
9
  def print
10
+ puts to_s
11
+ end
12
+
13
+ def to_s
10
14
  lines = []
11
15
  lines << '∅' # Style for the root node.
12
16
  lines += tree_lines
@@ -15,8 +19,7 @@ module BehaviorTree
15
19
  lines << uniq_nodes_string
16
20
  lines << size_string
17
21
  lines << tree_tick_count_string
18
-
19
- puts lines.join "\n"
22
+ lines.join "\n"
20
23
  end
21
24
 
22
25
  private
@@ -34,7 +37,7 @@ module BehaviorTree
34
37
  space = (0...depth).map { |d| vertical_lines_continues.include?(d) ? '│ ' : ' ' }.join
35
38
  connector = last_child ? '└─' : '├─'
36
39
 
37
- "#{space}#{connector}#{class_simple_name(node)} #{status_string(node)} #{tick_count_string(node)}"
40
+ "#{space}#{connector}#{resolve_display_name(node)} #{status_string(node)} #{tick_count_string(node)}"
38
41
  end
39
42
  end
40
43
 
@@ -83,22 +86,11 @@ module BehaviorTree
83
86
  .downcase
84
87
  end
85
88
 
86
- def class_simple_name(node)
87
- pretty_name snake_case(node.class.name.split('::').last)
88
- end
89
-
90
- # Changes the name of some classes (maps it to a better name).
91
- # Mapping is simply based on taste.
92
- def pretty_name(name)
93
- case name
94
- when 'task_base'
95
- 'task'
96
- when 'force_success'
97
- 'forcesuccess'
98
- when 'force_failure'
99
- 'forcefailure'
89
+ def resolve_display_name(node)
90
+ if node.respond_to?(:display_name)
91
+ node.display_name
100
92
  else
101
- name
93
+ snake_case(node.class.name.split('::').last)
102
94
  end
103
95
  end
104
96
  end
@@ -4,6 +4,10 @@ module BehaviorTree
4
4
  module Decorators
5
5
  # Returns always failure when the child is not running.
6
6
  class ForceFailure < DecoratorBase
7
+ def display_name
8
+ 'forcefailure'
9
+ end
10
+
7
11
  protected
8
12
 
9
13
  def status_map
@@ -4,6 +4,10 @@ module BehaviorTree
4
4
  module Decorators
5
5
  # Returns always success when the child is not running.
6
6
  class ForceSuccess < DecoratorBase
7
+ def display_name
8
+ 'forcesuccess'
9
+ end
10
+
7
11
  protected
8
12
 
9
13
  def status_map
@@ -25,6 +25,10 @@ module BehaviorTree
25
25
  end
26
26
  end
27
27
 
28
+ def display_name
29
+ 'task'
30
+ end
31
+
28
32
  private
29
33
 
30
34
  attr_reader :context
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BehaviorTree
4
- VERSION = '0.1.10'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: behavior_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felo Vilches
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-16 00:00:00.000000000 Z
11
+ date: 2023-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.1
27
- description:
27
+ description:
28
28
  email:
29
29
  - felovilches@gmail.com
30
30
  executables: []
@@ -82,7 +82,7 @@ homepage: https://github.com/FeloVilches/Ruby-Behavior-Tree
82
82
  licenses:
83
83
  - MIT
84
84
  metadata: {}
85
- post_install_message:
85
+ post_install_message:
86
86
  rdoc_options: []
87
87
  require_paths:
88
88
  - lib
@@ -97,8 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  requirements: []
100
- rubygems_version: 3.2.3
101
- signing_key:
100
+ rubygems_version: 3.3.7
101
+ signing_key:
102
102
  specification_version: 4
103
103
  summary: A robust and customizable Ruby gem for creating Behavior Trees.
104
104
  test_files: []