question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Code structure changes

See original GitHub issue

Just a breakdown from what I understand of the system so far, and ideas on how to maybe improve it. Please give feedback.

Mineflayer code structure

Overview on the current structure of Mineflayer and some ideas for changes

Current Structure

The structure in use in the repo at the moment, to the best of my understanding

Libraries

Biome

Biome class containing color, name, height, rainfall, temperature

Block

Block class containing type, metadata, light, skyLight, add, biome, position. Also contains name, hardness, displayName, boundingBox, diggable, material, havestTools extracted from the block enum.

Chest

Chest reference class for interacting with a ChestWindow

Conversions

Utility class containing conversions for rotations and notchian data

Dispenser

Dispenser reference class for interacting with a DispenserWindow

Enchantment Table

Enchantment Table reference class for interacting with an Enchantment Table

Entity

Entity class containing id, type, position, velocity, yaw, pitch, onGround, height, potion effects, equipment, heldItem

Furnace

Furnace reference class for interacting with a FurnaceWindow

Item

Item class containing type, count, metadata, nbt. Also name, displayName, stackSize (max) from the appropriate block/item enum

Location

Location class for a position in the world containing floored, blockPoint, chunkCorner, blockIndex, biomeBlockIndex, chunkYIndex

Math

Utility class with clamp, sign, euclidianMod functions

Painting

Painting class containing id, position, name, direction

Recipe

Recipe class storing recipes and information about crafting them. Properties are type, count, metadata, ingredients, requiresTable, as well as some functions and calculated properties

Windows

Windows class providing ChestWindow, CraftingTableWindow, FurnaceWindow, DispenerWindow, EnchantmentTableWindow and BrewingStandWindow. It also exposes the parent class Window that is inherited by the formentioned windows. Window exposes functions that enable clicking and interacting with items on an inventory window, the subclasses provide functions that are window specific.

Plugins

bed

Bed plugin providing sleep and wake functions as well as tracking sleep state

block_actions

Block actions plugin tracking noteblocks, piston movement and chest lid state

blocks

Blocks plugin handles chunk data and block information, it also contains the unexposed Column class for a chunk column

chat

Handles parsing of incomming messages and emitting a chat or whisper event. Also provides chat and whisper functions for sending chat

digging

Digging plugin provides dig and stopDigging functions to the bot, as well as functions to query if a block is indestructable (canDigBlock) and how long the block will take to dig (digTime)

entities

Provides entity tracking including animation information about the entities in the world. This includes tracking players that have joined or left the server. Provides attack, mount, dismount and useOn functions. Exposes players and entities properties

experience

Experience plugin supports experience levels and exposes level, points, progress properties

game

Game plugin tracks level/dimension information and gameMode. Exposes the game property which contains levelType, gameMode, hardcore, dimension, difficulty, maxPlayers.

health

Health plugin tracks death and health packets, exposing health, food, foodSaturation, isAlive.

inventory

Inventory is an overpopulated plugin that ties together the Windows classes, the TileEntity classes e.g. Chest, Furnace, Dispenser, Enchantment Table and handles bot inventory, tracks the currently heldItem and the selected hotbar slot quickBarSlot. Provides functions to (un)equip armour and transfer items around the inventory and between the inventories of other blocks. Also handles windows opening and closing and relays them back and forth between the TileEntity classes and Windows class

kick

Provides kicked event and the ability to nicely leave the server via quit

physics

Provides a simplified implementation of AABB physics, handles movement including jumping and sprinting. Is able to query the passability of a block to determine collisions. Is used by navigation plugins for routing a path

rain

Simply tracks if it is raining or not, exposes isRaining

settings

Handles client settings information from the server and allows changing of settings that are sent back to the server. exposes settings and setSettings. settings has the properties chat, colorsEnabled, viewDistance, difficulty, showCape

spawn_point

Exposes spawnPoint which is set each time the bot spawns

time

Exposes time which has the properties day and age.

Enums

biomes.json

Dictionary of all the biomes keyed by network id, each biome exposes id, color, height, name, rainfall, temperature

blocks.json

Dictionary of all the blocks keyed by id, each block exposes id, displayName, name, hardness, stackSize, diggable, boundingBox, material, havestTools. havestTools is a dictionary of ids that work more efficiently at breaking the block

instruments.json

Dictionary of instrument sounds keyed by network id, exposes id, name

items.json

Dictionary of all the items, keyed by item id, exposes id, displayName, stackSize, name

materials.json

Dictionary of block materials, keyed by material name containing a dictionary of havestTools and efficency multiplier. Used for digTime most likely

recipes

Dictionary of craftable items, keyed by the type to be crafted. Value of each key is an array of possible recipes. Each recipe exposes type, count, metadata, ingredients, inShape. Type, count and metadata is the result. ingredients is an array of required ingredients in the form of id, metadata. ingredients is used for a shapeless recipe (Example: planks from logs). inShape is an array of arrays for the shaped crafting recipe.

Summary

For the most part the bot is very full-featured with a lot of information at it’s disposal. However some structure changes could be made to make the code slightly more managable. My current concerns are Windows, Inventory management, TileEntities, and Entity tracking. As well as splitting core plugins (The ones we provide) with user plugins. A seperate folder is a simple change, but I’m mentioning it anyway.

Windows/Inventories/TileEntities

Currently the structure of these objects is in no way modular, it is spanned across individual objects in lib/, as well as the inventory plugin and the windows object.

I believe the project would benefit from splitting the handling of each individual window in to a seperate file, and restructuring so that the inventory plugin would not decorate the objects in lib (Looking at you deposit and withdraw). But instead a class dedicated to the interaction of a block would be self-contained. inventory would not override such functions and it would not go to windows for the appropriate window.

I think a similar structure to how plugins are done (requireindex) might be a cleaner alternative to the current windows object.

Also the player inventory is a special case and is treated as such by the server, it should be the primary function of the inventory plugin, as well as simply updating the slots in the currently displayed inventory. But it should not be used for opening and closing other windows. That should be handled imo elsewhere.

Entities

The way entities and players are tracked could be slightly improved, I think having some sort of proxy object that uses getters for information would help prevent references being held by the end-user. Currently if a plugin holds a reference to an entity or a player, and that entity/player is removed by the server, the reference still exists. This is something we can not help, but we can provide better means of dealing with this.

Emitting an event on the object is one idea, using an isValid flag and asserting that in all get/set operations (Keeping properties private from the object) is another idea. Forcing the user to use isValid or risk an error.

This would give a very early warning to the user that they are incorrectly holding on to a reference of an entity that is no longer in existance.

NOTE: player names and ids are going away in favour of a new UUID system. This will be very important because starting from MC 1.8, users will be able to change their names to any freely available name. UUIDs will be the only way to determine who a user is when online

All the helpers

I know that core code is something that is really needed to get anything to happen at all, but I don’t see much point in exposing any simple functions like click a slot or pick up an item. I’m aware that high level functions like transfer/deposit/withdraw/toss exist. I’m just putting this here as a point that we should focus strongly on helpers to keep the bot high level, and expose less low level functions.

If a third-party plugin needs access to a low level feature, we are not doing something correctly as a high level API.

More abstraction

I noticed that some high level functions still individually handle and send packets directly to the client. I think this should be avoided because it creates redundant code and increases the points of failure and bugs

Promises?

I, personally, am very fond of Promises (eg. Q). I would like to move a lot of the callback structure over to Promises. I feel that more structured and higher level code can be written by using an API like this. e.g.

bot.findBlock('wheat').then(function(location) {
    return bot.harvestBlockAt(location);
}).then(function(success) {
    if(success) bot.chat('I got some wheat');
    else bot.chat('I couldn't havest the wheat');
}).catch(function(error) {
    bot.chat('I hard failed for some reason, check console.');
    console.log(error.stack);
});

This is just my opinion and I would enjoy feedback on this entire document.

@andrewrk @roblabla

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
rom1504commented, Mar 28, 2015

The promise idea (or something similar) would avoid doing something like https://github.com/andrewrk/mineflayer/blob/ce4b2606b8ff5eafd17b40c9478f73cd2d9935be/test/superflat.js#L105

0reactions
rom1504commented, Apr 28, 2015

I think we dealt with everything in that issue except for one thing that still isn’t done : combining tasks the right way™. I opened a new more specific issue about that point here #275.

So I think we can close that issue that contain too many things.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How should I structure my code, and how do I make it ... - Quora
The aim is to have generic classes that won't change all times modifications are made on the program. It's easier to modify and...
Read more >
Refactoring
Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
Read more >
Code refactoring - Wikipedia
In computer programming and software design, code refactoring is the process of restructuring existing computer code—changing the factoring—without changing ...
Read more >
Codes and Standards - STRUCTURE magazine |
This five-part series discusses significant structural changes to the 2021 International Building Code (IBC) by the International Code Council (ICC).
Read more >
Analyzing and inferring the structure of code change - ProQuest
Analyzing and inferring the structure of code change. Abstract. Programmers often need to reason about how a program evolved between two or more ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found