0.1.0 • Published 3 months ago

behavey v0.1.0

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
3 months ago

behavey

==========

A behavior tree framework for JavaScript & TypeScript (BETA)

To Install

npm add behavey

# or

yarn add behavey

How It Works

behavey consists of several pieces:

  • LambdaArgs: a common and extensible data structure used by behavey to help manage and control behavior.
  • Operation: a common function that utilizs LambdaArgs to execute behavioral patterns.
  • Tree: a common interface to host Operation constructs, both subroutine and coroutine based.
  • Mode: a way to manage multiple Tree constructs to support shared (MinorMode) and situational behaviors (MajorMode).
  • Executor: a mechanism to manage multiple Modes, switch between them, as well as capture events and manage LambdaArgs.
  • EventDispatcher: a simple and powerful call-based method of registering and dispatching events.

Together you can use them to construct and execute a behavior tree:

const exec = create_executor_builder<MyMetaData>()
  .add_major_mode(seek_threat)
  .add_major_mode(attack_threat)
  .create_major_mode(major =>
    major
      .set_name('idle-roam')
      .create_tree(tree =>
        tree
          .set_root(
            sel(
              seq(
                threat_detected,
                play_alert_bark,
                emt('bark-alert'),
                tsn('seek-threat'),
              ),
              seq(have_path, follow_path, set_walk),
              seq(choose_random_location, determine_path, brk()),
              idf(
                choose_random_idle_pose,
                set_stand_idle_1,
                set_stand_idle_2,
                set_stand_idle_3,
              ),
            ),
          )
          .build(),
      )
      .create_minor_mode(minor =>
        minor
          .set_name('alertable')
          .add_event('bark-alert')
          .add_event('explosion-alert')
          .add_event('alarm-alert')
          .set_tree(respond_to_alerts)
          .build(),
      )
      .add_minor_mode(play_animation_track)
      .build(),
  )
  .set_default_mode('idle-roam')
  .build();

// execute the behavior passing your meta data
exec.behave(myData);

Operations

behavey provides a number of Operations that represent logical constructs, such as:

  • smf - run a function and store the returned result in a location in memory.
  • chk - check if a location in memory has a specific value.
  • inv - invert an Operation so that its result is flipped: i.e., true becomes false and vice-versa.
  • seq - run a sequence of Operations, only returning true if all operations were successful.
  • sel - run a sequence of Operations, returning true when the first succeeds.
  • idf - run a function that returns a number that is used to index into an array of Operations.
  • lpv - run an Operation in a loop for as long as a memory location is true.

There are also concurrent variations of Operations that will evuate over several calls

import { coroutine, CResult, fnb_c, fnc, fnr_c, make_args, seq_c } from 'behavey';

const args = make_args();

// seq_c takes several `LambdaGenrators` and evaluates them over the course of several calls
const root = seq_c(
    // `fnb_c` takes a `BooleanLambda` and turns it into a `LambdaGenerator`
    fnb_c(()=> true),
    // `fnr_c` takes a `ResultLambda` and turns it into a `LambdaGenerator`
    fnr_c(()=> CResult.SUCCESS),
    fnb_c(()=> true),
);

// `coroutine` takes a `LambdaGenerator` and turns it into a `Coroutine`
// it can then be successively called to progress the evaluation.
const cor = coroutine(root);

cor(args); // 1st `fnb_c` evaluated, returns `CResult.RUNNING`
cor(args); // 1st `fnr_c` evaluated, returns `CResult.RUNNING`
cor(args); // 2nd `fnb_c` evaluated, returns `CResult.RUNNING`
cor(args); // `seq_c` evaluated, returns `CResult.SUCCESS`

// coroutines can also be wrapped in a `fnc` to make them behave as if they were a `BooleanLambda`
const root = fnc(
  seq_c(
    // `fnb_c` takes a `BooleanLambda` and turns it into a `LambdaGenerator`
    fnb_c(() => true),
    // `fnr_c` takes a `ResultLambda` and turns it into a `LambdaGenerator`
    fnr_c(() => CResult.SUCCESS),
    fnb_c(() => true),
  ),
  2, // max iterations per call
  4, // how many iterations must ocurr before the coroutine is reset
  false, // how `CResult.RUNNING` should be interpreted
);

root(args); // two iterations, returns `false`
root(args); // two iterations, returns `true`
root(args); // coroutine was reset, two iterations, returns `false`
root(args); // two iterations, returns `true`
0.1.0

3 months ago

0.0.2

3 months ago

0.0.1

4 months ago