Coder Social home page Coder Social logo

prismarinejs / mineflayer-statemachine Goto Github PK

View Code? Open in Web Editor NEW
105.0 7.0 24.0 655 KB

A state machine plugin for Mineflayer to aid in designing more complex behavior trees.

Home Page: https://thedudefromci.github.io/mineflayer-statemachine/

License: MIT License

TypeScript 76.24% CSS 1.60% HTML 0.92% JavaScript 21.25%
ai bot minecraft mineflayer state-machine

mineflayer-statemachine's Introduction

Mineflayer-StateMachine

This project is a plugin designed for Mineflayer that adds a high level API for writing state machines. As bot AI code can grow very quickly, writing this code in a finite state machine manner can help keep the code base manageable and improve quality of bot behavior trees.


What is it?

Mineflayer-StateMachine is a plugin for Mineflayer. It aims to add a flexible and customizable state machine API on top of Mineflayer to make it easier to write and scale bots.

Writing a complex bot AI can be difficult, especially if it has to be convincing. Finite state machines make this process much eaiser by offloading the fine details into isolated modules which only serve a single function or behavior. These modules can then be connected together in a top level component to customize how these seperate modules should interact and pass around control of the bot and state machine parameters.

Showcase

Videos

Webserver Demo

Mining Demo

Getting Started

This plugin is built using Node and can be installed using:

npm install --save mineflayer-statemachine

This plugin relies on mineflayer-pathfinder for movement related behaviors. If these behaviors are used, this plugin must be loaded before starting the state machine object.

Simple Bot

The API for Mineflayer-StateMachine aims to be simple and intuitive, requiring minimal effort to setup a working state machine. The example below creates a three-state finite state machine which finds and follows the nearest player, stopping and looking at them when they are close.

// Create your bot
const mineflayer = require("mineflayer");
const bot = mineflayer.createBot({ username: "Player" });

// Load your dependency plugins.
bot.loadPlugin(require('mineflayer-pathfinder').pathfinder);

// Import required behaviors.
const {
    StateTransition,
    BotStateMachine,
    EntityFilters,
    BehaviorFollowEntity,
    BehaviorLookAtEntity,
    BehaviorGetClosestEntity,
    NestedStateMachine } = require("mineflayer-statemachine");
    
// Wait for our bot to login.
bot.once("spawn", () =>
{
    // This targets object is used to pass data between different states. It can be left empty.
    const targets = {};

    // Create our states
    const getClosestPlayer = new BehaviorGetClosestEntity(bot, targets, EntityFilters().PlayersOnly);
    const followPlayer = new BehaviorFollowEntity(bot, targets);
    const lookAtPlayer = new BehaviorLookAtEntity(bot, targets);

    // Create our transitions
    const transitions = [

        // We want to start following the player immediately after finding them.
        // Since getClosestPlayer finishes instantly, shouldTransition() should always return true.
        new StateTransition({
            parent: getClosestPlayer,
            child: followPlayer,
            shouldTransition: () => true,
        }),

        // If the distance to the player is less than two blocks, switch from the followPlayer
        // state to the lookAtPlayer state.
        new StateTransition({
            parent: followPlayer,
            child: lookAtPlayer,
            shouldTransition: () => followPlayer.distanceToTarget() < 2,
        }),

        // If the distance to the player is more than two blocks, switch from the lookAtPlayer
        // state to the followPlayer state.
        new StateTransition({
            parent: lookAtPlayer,
            child: followPlayer,
            shouldTransition: () => lookAtPlayer.distanceToTarget() >= 2,
        }),
    ];

    // Now we just wrap our transition list in a nested state machine layer. We want the bot
    // to start on the getClosestPlayer state, so we'll specify that here.
    const rootLayer = new NestedStateMachine(transitions, getClosestPlayer);
    
    // We can start our state machine simply by creating a new instance.
    new BotStateMachine(bot, rootLayer);
});

Documentation

API

Roadmap

Implemented

  • Web View
  • Look at Entity Behavior
  • Nested State Machines
  • Movement Behaviors
  • Mining/Placing Behaviors
  • Get Nearby Entities
  • Equip Items and Armor

To Do

  • Show Targets in Web View
  • Camera Controls in Web View
  • Collection-based Behaviors
  • Fighting-based Behaviors
  • Conversation-based Behaviors

License

This project uses the MIT license.

Contributions

This project is accepting PRs and Issues. See something you think can be improved? Go for it! Any and all help is highly appreciated!

For larger changes, it is recommended to discuss these changes in the issues tab before writing any code. It's also preferred to make many smaller PRs than one large one, where applicable.

mineflayer-statemachine's People

Contributors

0xjimmy avatar actions-user avatar amoraschi avatar dependabot-preview[bot] avatar dependabot[bot] avatar dustinyschild avatar flowl avatar haze-cmyk avatar kaduvert avatar nicejs-is-cool avatar renovate-bot avatar robbilie avatar sefirosweb avatar shagrat2 avatar thedudefromci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mineflayer-statemachine's Issues

BehaviorFindBlock doesn't work for preventxray = true

In order to check line of sight to a block with mineflayer's bot.findBlock, you have to set checkExtraInfo in the matching options to true, but BehaviorFindBlock doesn't do that and thus it doesn't work. Here is a proof of concept fix:
class BehaviorCustomFindBlock implements sm.StateBehavior {
active = false;
stateName = 'customFindBlock';
blocks:any[]
bot:mf.Bot;
isFinished = false
targets:any = {}
constructor(bot:mf.Bot,targets) {
this.bot = bot
this.targets = targets
}
onStateEntered(): void
{
this.targets.position = this.targets.position = this.bot.findBlock({
matching:(block)=>this.blocks.indexOf(block.stateId)!==-1 && bot.canSeeBlock(block),
useExtraInfo:true,
maxDistance:32,
}).position
}
}

Question declaring optinal values with typescript

Hello! I'm migrating my bot to Typescript for best mantenance,

Currently i'm migrating my custom behaviors,

I have 2 tips:

One of them the default values of X/Y os position of website is not declared?
When i call to set value X / Y typescript is criying these values no exists:

image

Only works when I add manually the X/Y values in types:

image

But they are implemented "StateBehavior" and they have the values,

For correct work I need to add these values on all Behaviors?
if is that i will made a PR

The second: i can't assign "bot" to Behavior Entities, with Typescript show this error:

image

The "bot" value is same type of behavior component, i'm doing anything wrong?

There is no information about BehaviourFindBlock in the API

I've read everything in the API but I couldn't find any information about BehaviorFindBlock. How to specify the block to find in targets.positions ? An example should be added to the examples folder for BehaviorFindBlock. You can use the source of your mining demo video. Also I would like to know how to specify the block if possible .

Add Instant Transitions

Currently, manual transitions only mark the transition as should transition on the next physics tick. Since this is not Instant, many events may be missed or sent to the wrong target.

There should be a method for transitioning instantly.

Supports Node 16.X?

Hello i'm trying to install this package in updated node version and i have error when install this dependency

image

You know if this dependency supports node 16?
From node 14 seems works fine

package.json:
image

unable to install on linux

i cannot install this on manjaro (arch linux based distros) it tells me that the cache folder is containing root-owned files, but it can't because i deleted all .npm folders multiple times after trying the suggested solution of sudo chown -R 65534:1000 "/root/.npm". it throws an error:

node:internal/modules/cjs/loader:928
  throw err;
  ^

Error: Cannot find module 'node-linux-x64/package.json'
Require stack:
- /usr/lib/node_modules/mineflayer-statemachine/node_modules/node/installArchSpecificPackage.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15)
    at Function.resolve (node:internal/modules/cjs/helpers:98:19)
    at ChildProcess.<anonymous> (/usr/lib/node_modules/mineflayer-statemachine/node_modules/node-bin-setup/index.js:18:27)
    at ChildProcess.emit (node:events:376:20)
    at maybeClose (node:internal/child_process:1063:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:295:5) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/usr/lib/node_modules/mineflayer-statemachine/node_modules/node/installArchSpecificPackage.js'
  ]
}

this error seems to be specific to mineflayer-statemachine or a dependency

2021-01-10T00_13_00_096Z-debug.log

Dependency Issue

Mineflayer-statemachine currently depends on mineflayer and mineflayer-pathfinder for optionally used states.

According to the docs: "This plugin relies on mineflayer-pathfinder for movement related behaviors. If these behaviors are used, this plugin must be loaded before starting the state machine object."

I recommend moving mineflayer and mineflayer-pathfinder to devDependencies instead since the plugin does not load them by default. That way there isn't a dependency issue whenever mineflayer updates.

Optimize events (memory usage) for bot._events

Hello, I'm making a bit huge bot with alot of functions

I saw when use a same "behavior" with events on differents parts they acumulate events for each time you use,

Example "behaviorMoveTo" is a common function and I use around 13 times in the code, I saw the bot._events they have 13 listeners,

image

Any idea for load only the events whe goes inside and unload when going outside?

  • I tried to move to bot.on(xxx) when starts the behavior "onStateEntered", but the problem is the onStateExited, some times the bot is moving to differents nested behaviors without passing to "onStateExited", and they don't remove the listener, and they is acumulating alot of eventlisteners
  • I will try to make a simple example for show

Dependencies issue

I'm getting this error when bot needs to scaffold:

const offset = (b && dy > 0.001 && bot.entity.onGround && !stateMovements.emptyBlocks.has(b.type)) ? 1 : 0
^
TypeError: Cannot read properties of undefined (reading 'has')
at Object.bot.pathfinder.getPathFromTo (C:\Users\Desktop\prismarine\mineflayer\node_modules\mineflayer-pathfinder\index.js:83:93)

Here is the code I'm using:


const mineflayer = require('mineflayer');
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder');
//Vec3
const Vec3 = require('vec3');

const bot = mineflayer.createBot({ host: 'mc.blurkit.net', port: 25565, username: 'OneKe' })

//const mcData = require('minecraft-data')(bot.version);

// load plugins
bot.loadPlugin(pathfinder);
bot.loadPlugin(require('mineflayer-pathfinder').pathfinder);




//send helloworld to chat

let loggedIn = false;

var jsonMsg;


bot.on('message', async (jsonMsg) => new Promise((resolve, reject) => {


    if (!loggedIn) {
        setTimeout(resolve, 100)

        bot.once('physicTick', () => {

          

                console.log("starting to login2")
                bot.chat('/login password');

                console.log("starting to login3")

            
        })



        console.log('logging in')

        //if jsonmsg contains "/tpbypass", then write bot.chat('/login password')
        if (jsonMsg.toString().includes("[Β»] Ya has iniciado seciΓ³n!")) {
            //stop this listener
            loggedIn = true;
            bot.removeListener('physicTick', () => { })
        }
    }


    if (jsonMsg.toString() != "" || jsonMsg.toString() != null || jsonMsg.toString() != undefined || !jsonMsg.toString.includes("        ")) {
        console.log("jsonmsg: " + jsonMsg)
        this.jsonMsg = jsonMsg.toString();
    }


}));






// Log errors and kick reasons:
bot.on('kicked', console.log)
bot.on('error', console.log)



//wait for login to complete




//wait for spawn to complete
bot.on('spawn', () => {
    console.log("starting to login5")


    //wait for inventory to complete

    let item = bot.inventory.findInventoryItem('compass')

    //equip hotbar to slot number 5


    bot.inventory.items().forEach(item => {

        console.log(item.name)


        if (item.name === 'compass') {

            //select compass to hotbar
            bot.inventory.updateSlot(item.slot, item)
            //equip compass to hotbar
            bot.equip(item, 'hand')



            bot.activateItem()

            //a menu will pop up, display the menu
            bot.once('windowOpen', (window) => {

                console.log('preparin to click slot')
                bot.clickWindow(13, 1, 0)
                console.log("left click grass block")

                //wait for inventory to complete
                bot.once('windowOpen', (window) => {
                    console.log("windowOpen 2")
                    bot.clickWindow(15, 1, 0)

                    bot.once('spawn', () => {

                        console.log("starting to login6")



                        //display everything inside inventory
                        bot.inventory.items().forEach(item => {
                            console.log("item: " + item.name);
                        }
                        );

                        const {
                            StateTransition,
                            BotStateMachine,
                            EntityFilters,
                            BehaviorFollowEntity,
                            BehaviorLookAtEntity,
                            BehaviorGetClosestEntity,
                            NestedStateMachine } = require("mineflayer-statemachine");

                        //go to nearest player
                        const playerCI = bot.players['vitzel'];
                        const target = playerCI?.entity;
                        //const RANGE_GOAL = 3 // get within this radius of the player
                        //const movements = new Movements(bot, mcData);
                        //bot.pathfinder.setMovements(movements);

                        if (playerCI) {


                            //let { x: playerX, y: playerY, z: playerZ } = target.position

                            //let goal = new goals.GoalNear(playerX, playerY, playerZ, RANGE_GOAL)

                            const targets = {};
                            const getClosestPlayer = new BehaviorGetClosestEntity(bot, targets, EntityFilters().PlayersOnly);
                            const followPlayer = new BehaviorFollowEntity(bot, targets);
                            const lookAtPlayer = new BehaviorLookAtEntity(bot, targets);

                            // Create our transitions
                            const transitions = [

                                // We want to start following the player immediately after finding them.
                                // Since getClosestPlayer finishes instantly, shouldTransition() should always return true.
                                new StateTransition({
                                    parent: getClosestPlayer,
                                    child: followPlayer,
                                    shouldTransition: () => true,
                                }),

                                // If the distance to the player is less than two blocks, switch from the followPlayer
                                // state to the lookAtPlayer state.
                                new StateTransition({
                                    parent: followPlayer,
                                    child: lookAtPlayer,
                                    shouldTransition: () => followPlayer.distanceToTarget() < 2,
                                }),

                                // If the distance to the player is more than two blocks, switch from the lookAtPlayer
                                // state to the followPlayer state.
                                new StateTransition({
                                    parent: lookAtPlayer,
                                    child: followPlayer,
                                    shouldTransition: () => lookAtPlayer.distanceToTarget() >= 2,
                                }),
                            ];

                            // Now we just wrap our transition list in a nested state machine layer. We want the bot
                            // to start on the getClosestPlayer state, so we'll specify that here.
                            const rootLayer = new NestedStateMachine(transitions, getClosestPlayer);

                            // We can start our state machine simply by creating a new instance.
                            new BotStateMachine(bot, rootLayer);


                        }
                    });
                });

            });
        }

    });


});

Use consistant isFinished() options.

Each behavior should use a consistent isFinished() function. As it stands now, some behaviors use isFinished as a variable. Some use it as a function. Many states don't use it at all. This should be tweaked.

Add a way to make triggered transitions universal

I'm writing a bot that can pass from an idle state into a variety of states designed to perform certain activities. When I'm defining the transitions to the idle state, i'd like to be able to define called "returnToIdle" that can have any other state as a parent, to avoid having to write one for each behavior

distanceFilter seems wrong

Hi again, in the documentation the point: API 3.2

I tried to use function distance filter, but seems not working fine:

function distanceFilter(entity)
{
    return bot.position.distanceTo(entity.position) <= 5
        && (EntityFilters().MobsOnly || EntityFilters().PlayersOnly);
}

const getClosestEntity = new BehaviorGetClosestEntity(bot, targets, distanceFilter);

I was done a bit changes and now works perfect:

    function distanceFilter(entity) {
        return entity.position.distanceTo(this.bot.player.entity.position) <= 10 &&
            (entity.type === 'mob' || entity.type === 'player');
    }
    const getClosestMob = new BehaviorGetClosestEntity(bot, targets, distanceFilter);

Your example is fine?

I attach my full nested function

const {
    StateTransition,
    BehaviorIdle,
    BehaviorFollowEntity,
    BehaviorLookAtEntity,
    NestedStateMachine,
    BehaviorGetClosestEntity,
    EntityFilters,

} = require("mineflayer-statemachine");
const BehaviorAttack = require("./../BehaviorModules/BehaviorAttack");

function startWorkFunction(bot, targets) {
    const enter = new BehaviorIdle(targets);
    const exit = new BehaviorIdle(targets);
    const attack = new BehaviorAttack(bot, targets);

    function distanceFilter(entity) {
        return entity.position.distanceTo(this.bot.player.entity.position) <= 10 &&
            (entity.type === 'mob' || entity.type === 'player');
    }
    const getClosestMob = new BehaviorGetClosestEntity(bot, targets, distanceFilter);

    const followMob = new BehaviorFollowEntity(bot, targets);

    const transitions = [
        new StateTransition({
            parent: enter,
            child: getClosestMob,
            name: 'enter -> getClosestEntity',
            shouldTransition: () => true,
        }),

        new StateTransition({
            parent: getClosestMob,
            child: followMob,
            name: 'Found a mob',
            shouldTransition: () => targets.entity !== undefined,
            onTransition: () => bot.chat("Attack mob! " + targets.entity.displayName),
        }),

        new StateTransition({
            parent: getClosestMob,
            child: getClosestMob,
            name: 'Re search found a mob',
            shouldTransition: () => targets.entity === undefined,
        }),

        new StateTransition({
            parent: followMob,
            child: attack,
            name: 'Mob is near',
            shouldTransition: () => followMob.distanceToTarget() < 2 && attack.nextAttack() && targets.entity.isValid,
        }),

        new StateTransition({
            parent: attack,
            child: followMob,
            name: 'Mob is too far',
            shouldTransition: () => followMob.distanceToTarget() > 2 && targets.entity.isValid,
        }),


        new StateTransition({
            parent: attack,
            child: attack,
            name: 'Mob still near continue attack',
            shouldTransition: () => followMob.distanceToTarget() < 2 && attack.nextAttack() && targets.entity.isValid,
        }),

        new StateTransition({
            parent: attack,
            child: getClosestMob,
            name: 'Mob is dead',
            shouldTransition: () => targets.entity.isValid === false
        }),

        new StateTransition({
            parent: followMob,
            child: getClosestMob,
            name: 'Mob is dead',
            shouldTransition: () => targets.entity.isValid === false
        }),



    ];

    const startWorkFunction = new NestedStateMachine(transitions, enter, exit);
    startWorkFunction.stateName = 'startWorkFunction'
    return startWorkFunction;
}


module.exports = startWorkFunction;

Can-reach entity filter.

If would be useful if there was an entity filter for entities that can be reached without moving. This is useful for things such as players and mobs to hit, or armor stands and item frames to add/retrieve items from.

Wildcard exit state for passive actions?

I think it's useful to have exit states that apply to all parent:

new StateTransition({
    parent: null, // apply check to all parents?
    child: eatBehavior,
    shouldTransition: () => (this.bot.food <= 16 || this.bot.food < 20 && this.bot.health <= 16) && !this.bot.inLava()
 }),
new StateTransition({
    parent: eatBehavior, 
    child: this.getPreviousBehaviour(), // not sure about this yet :-)
    shouldTransition: () => eatBehavior.isFinished()
 }),

Currently, I am implementing passive actions either outside of the StateMachine, or very redundant inside multiple NestedStateMachines, neither feels like the best approach yet.

General feedback πŸŽ‰

Just here to say thank you for this brilliant project!

The included behaviors are a very good starting point and the API docs are very straight forward. All methods and properties are well documentated.

I was able to get a bot with a few skills equipped up and running very quickly, thanks to your good work.

Currently I am fixing out minor details, most importantly race conditions (my bot ended up trying to eat shovels and pickaxes πŸ€ͺ because it wanted to eat and mine at the same time, or due to cancelled and improperly handled events.)

It's actually fun to incorporate other useful mineflaye-* plugins into their own states, behaviors and transitions. Even the nesting of compound behaviors is working very nice! πŸ™Œ The webserver with the visual feedback is also very useful in complex setups or even to find a missing transition very efficiently! πŸŽ‰

Improve the behaviors when found an error

I think in the behaviors must have a 2 returns value,

One of "is finished" and another one about found any error,

For example:

https://github.com/PrismarineJS/mineflayer-statemachine/blob/d69786e1f0e36c22d30d0c8f58abb6fa4254c937/src/behaviors/behaviorInteractBlock.ts

In this case if the bot can't "see" block they stops all the bot,

I think need one return for "end of function" if when end of function all is okey, fine but if they found any error for do something (go mo re near of the block, or restart, anything, but no stop all)

What do you think? on my custom behaviors i implemented this for avoid errors, (example error on server transaction on change held block )

Autolayout state machine on connect.

The default state machine layout, a simple circle, is very poor and requires the user to manually reorganize the scene completely after each reloads. This can be annoying.

If the nodes were laid out automatically on connect, this process would be much easier and would require almost no action on the user's part.

Promisify

Since Mineflayer has migrated to using a Promisified codebase, it only makes sense for all Mineflayer plugins to move in that same direction as well.

BehaviorMineBlock stops too much

Java VersiΓ³n Vanilla 1.6.2
Server Windows -> localhost
Node: v14.15.1
Version of mineflayer
"minecrafthawkeye": "^1.0.8",
"mineflayer": "^2.40.1",
"mineflayer-auto-eat": "^1.3.4",
"mineflayer-pathfinder": "^1.3.6",
"mineflayer-statemachine": "^1.5.1",
"mineflayer-web-inventory": "^1.2.0",
"prismarine-viewer": "^1.5.0"

Hello!

I'm trying to use the "BehaviorMineBlock" Behavior, for use is a simply in previos State i set targets.positions = (position)

I see is working but they stops after break 3-4 or 10 blocks (very random)

I think they have bug on the code or something,

I saw they breaks the block but don't "detect the change then the "isFinished" still on false for all time

// full code  https://github.com/sefirosweb/minecraftLegion/blob/master/NestedStateModules/miningFunction.js
  const moveToBlock = new BehaviorMoveTo(bot, targets)
  moveToBlock.stateName = 'Move To Block'

  const mineBlock = new BehaviorMineBlock(bot, targets)
  mineBlock.stateName = 'Mine Block'

...

    new StateTransition({
      parent: moveToBlock, // This is a "Move To Block" label
      child: mineBlock,
      name: 'Move To Block',
      shouldTransition: () => moveToBlock.distanceToTarget() < 3
    }),

    new StateTransition({
      parent: mineBlock, // This is a "Mine Block" label
      child: currentBlock,
      name: 'Go Next Block',
      shouldTransition: () => mineBlock.isFinished
    })

... // for set the position in previus state:

  calculateIsValid () {
    const block = this.getBlockType()
    const isValidBlockType = this.blockType.find(b => b === block.name)
    if (isValidBlockType === undefined) {
      this.targets.position = block.position // I detect is not air / lava / water then go to this position
      return false
    }

    return true
  }

I'm trying what see happens, this also happens for you?

[Question] How transfer data between Nested State Machines

Hello, in your documentation i can't see that,

I have multiples Nested states, but some times I need to transfer data between Nesteds (player / item / other)

Also I have a custom BehaviorModules,

Example:

image

image

PD: Great tool & Documentation!

Remove yarn.lock file

The yarn.lock file should be removed. Yarn should be replaced with npm in the build file, as well.

Extra graphs generated in browser if bot is restarted.

It's a small priority bug, which is quickly fixed by just refreshing the browser.

If the client bot is disconnected, starting a new session will cause another web graph to be created over the top of the old one, resulting in duplicate graphs being run at once. this can be fixed by destroying the graph object propertly when the socket is closed.

Error using your examples

const lookAtPlayersState = new BehaviorLookAtEntities(bot/, EntityFilters().PlayersOnly/);
^

TypeError: BehaviorLookAtEntities is not a constructor

Any idea how to sort the state machines?

My bot starts to have a HUGE number of functions :D I'm proud of that, and I reuse a lot of functions in a lot of things, it saves me time and bugs

BUT I have a little problem, I start to have a tree too much and it does not begin to be clear,

One of the "" problems "" is that when I use the same function in different behaviors they are seen in all, (example take items from the chest / floor)

I don't know from where starts / end the functions

Any advice on how to improve this?
I attach my tree of states

Screenshot_2

I was thinking of making each nested a dropodown / or a rectangle but I don't know if it could be more confusing

npm install fails

npm install fails. running manjaro linux, node v14.3.0

[vek@veks-mbp bot]$ npm install --save mineflayer-statemachine

> [email protected] postinstall /home/vek/Desktop/Projects/bot/node_modules/mineflayer-statemachine
> tsc

Version 3.9.5
Syntax:   tsc [options] [file...]

Examples: tsc hello.ts
          tsc --outFile file.js file.ts
          tsc @args.txt
          tsc --build tsconfig.json

Options:
 -h, --help                                         Print this message.
 -w, --watch                                        Watch input files.
 --pretty                                           Stylize errors and messages using color and context (experimental).
 --all                                              Show all compiler options.
 -v, --version                                      Print the compiler's version.
 --init                                             Initializes a TypeScript project and creates a tsconfig.json file.
 -p FILE OR DIRECTORY, --project FILE OR DIRECTORY  Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.
 -b, --build                                        Build one or more projects and their dependencies, if out of date
 -t VERSION, --target VERSION                       Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'.
 -m KIND, --module KIND                             Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'.
 --lib                                              Specify library files to be included in the compilation.
                                                      'es5' 'es6' 'es2015' 'es7' 'es2016' 'es2017' 'es2018' 'es2019' 'es2020' 'esnext' 'dom' 'dom.iterable' 'webworker' 'webworker.importscripts' 'scripthost' 'es2015.core' 'es2015.collection' 'es2015.generator' 'es2015.iterable' 'es2015.promise' 'es2015.proxy' 'es2015.reflect' 'es2015.symbol' 'es2015.symbol.wellknown' 'es2016.array.include' 'es2017.object' 'es2017.sharedmemory' 'es2017.string' 'es2017.intl' 'es2017.typedarrays' 'es2018.asyncgenerator' 'es2018.asynciterable' 'es2018.intl' 'es2018.promise' 'es2018.regexp' 'es2019.array' 'es2019.object' 'es2019.string' 'es2019.symbol' 'es2020.bigint' 'es2020.promise' 'es2020.string' 'es2020.symbol.wellknown' 'esnext.array' 'esnext.symbol' 'esnext.asynciterable' 'esnext.intl' 'esnext.bigint' 'esnext.string' 'esnext.promise' 
 --allowJs                                          Allow javascript files to be compiled.
 --jsx KIND                                         Specify JSX code generation: 'preserve', 'react-native', or 'react'.
 -d, --declaration                                  Generates corresponding '.d.ts' file.
 --declarationMap                                   Generates a sourcemap for each corresponding '.d.ts' file.
 --sourceMap                                        Generates corresponding '.map' file.
 --outFile FILE                                     Concatenate and emit output to single file.
 --outDir DIRECTORY                                 Redirect output structure to the directory.
 --removeComments                                   Do not emit comments to output.
 --noEmit                                           Do not emit outputs.
 --strict                                           Enable all strict type-checking options.
 --noImplicitAny                                    Raise error on expressions and declarations with an implied 'any' type.
 --strictNullChecks                                 Enable strict null checks.
 --strictFunctionTypes                              Enable strict checking of function types.
 --strictBindCallApply                              Enable strict 'bind', 'call', and 'apply' methods on functions.
 --strictPropertyInitialization                     Enable strict checking of property initialization in classes.
 --noImplicitThis                                   Raise error on 'this' expressions with an implied 'any' type.
 --alwaysStrict                                     Parse in strict mode and emit "use strict" for each source file.
 --noUnusedLocals                                   Report errors on unused locals.
 --noUnusedParameters                               Report errors on unused parameters.
 --noImplicitReturns                                Report error when not all code paths in function return a value.
 --noFallthroughCasesInSwitch                       Report errors for fallthrough cases in switch statement.
 --types                                            Type declaration files to be included in compilation.
 --esModuleInterop                                  Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.
 @<file>                                            Insert command line options and files from a file.
npm WARN enoent ENOENT: no such file or directory, open '/home/vek/Desktop/Projects/bot/package.json'
npm WARN [email protected] requires a peer of ajv@^5.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of eslint@>=4.19.1 but none is installed. You must install peer dependencies yourself.
npm WARN bot No description
npm WARN bot No repository field.
npm WARN bot No README data
npm WARN bot No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: `tsc`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/vek/.npm/_logs/2020-07-01T05_35_54_904Z-debug.log

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.