
HyDustry Lib
The Open Source Library for Java and for the Node Editor -> Open Source [Github]
for Java programmers
class HyDustryLib
HyDustryLib.AddConsumerMachineOperationType(String Name, Consumer<ConsumerMachineComponent> Function):
Add a new operation format to the machines.
example:
HyDustryLib.AddConsumerMachineOperationType("Essence Extractor", <classname>::Execute);
HyDustryLib.AddConveyorOperationType(String Name, Consumer<ConveyorTransporterComponent> Function):
agrega o reemplaza en el mapa una funcion de operacion para transportadores.
example:
HyDustryLib.AddConveyorOperationType("Rotator Conveyor", <classname>::Execute);
HyDustryLib.get()
Add a new operation format to the machines.
example:
HyDustryLib.getConsumerMachineComponentType()
returns the registered type of getConsumerMachineComponentType.
HyDustryLib.getConveyorTransporterComponentType()
returns the registered type of getConveyorTransporterComponentType.
HyDustryLib.getHarvestingEngineComponentType()
returns the registered type of getHarvestingEngineComponentType.
Main components
ConsumerMachineComponent
Represents a machine that consumes materials and generates products. Its configurable fields include ManufacturingTime, RequireFuel, RequireEnergy, InputItems, OutputItems, and OperationType.
ExecuteBehaviour(): Executes the operation registered forOperationType; uses the default behavior if no operation is found.ExecuteBehaviourDefault(): Validates the time, materials, fuel, and containers; consumes the resources and delivers the configured products when space is available.InitializeConfiguration(Map<String, String[]>): Configures the operation type and stores the block's tags within the component.GetItemsOutput(): Constructs the list of output products based on the machine's configuration.ItemsVerification(boolean): Checks whether the required materials are available.processItems(boolean): Consumes the materials required by the recipe or the active upgrade.getAvailableFuelId()andprocessFuel(String): Check for and consume the configured fuel.ManufacturingAvailability()andRenewManufacturingAvailability(Long): Check and update the manufacturing cooldown/wait time.GetInputItemsHyDustryComponent()andGetOutputItemsHyDustryComponent(): Return the component's input and output containers.
ConveyorTransporterComponent
Represents the state of a conveyor. Velocity controls forward movement; Progress indicates the completion status of a task; ItemsDetected and LookingBehaviour indicate object detection and the current search state.
HarvestingEngineComponent
Represents a harvesting engine. It stores Range, Interval, the current phase, irrigation timing, and the following triggered actions: Water, Harvest, Fertilize, and Accelerate.
Example operation: Extractor
Extractor.Execute(ConsumerMachineComponent)
An operation included for consumer machines. Scans the configured positions, identifies the predominant resource, calculates the output and its multipliers, consumes the required materials, and stores the products if the output container has space.
HyDustryLib.AddConsumerMachineOperationType("Essence Extractor", Extractor::Execute);
Implemented Utilities
EssentialsUtils
getBlockType(World, Vector3i): queries the block type at a given position.getBlockSection(World, Vector3i): retrieves the section containing the position.getBlockRef(World, Vector3i): retrieves the block's entity reference.getBlockRotation(World, Vector3i): retrieves the block's rotation.getGlobalPosition(...): converts a block's local coordinates into world coordinates.
RailsHyDustryLib
OrientRails(Vector3d[], int): rotates waypoints to align with the block's orientation.OrientGlobalPositions(Vector3d[], int): transforms offsets relative to the block's orientation.RailsCalculateNextPosition(Vector3d[], double, int): calculates a position along a path based on progress and smoothing.TagsPathsConversion(Map): converts path tags into vectors.ConvertingTagstoArrays(Map, String)andConvertingTagsPositionstoArrays(Map, String): convert coordinate tags into arrays of vectors.
FarmingHyDustryLib
ProccesingCoopsInRange(...): processes the blocks within the engine's range and applies any enabled care and harvesting actions.AccelerateGrowthInBlock(...): advances the crop toward the next stage of growth.WateringInBlock(...): extends the irrigation duration in a block. tilled soil.WateringAndFetilizedInBlock(...): waters and fertilizes the tilled soil.FetilizedInBlock(...): fertilizes the tilled soil.UpdateGrowthInBlock(...): schedules a growth update for the block.
HarvestingHyDustryLib
HarvestInSimpleContainer(...): collects drops from a block and updates the block or the crop's growth stage.HarvestValidationGatheringInContainer(...): checks whether the drops can be stored in the container.HarvestBlockValidation(...): checks whether the block has a valid harvest configuration.
Item Containers
ItemContainerHyDustryLib combines item-container and simple-container helpers: it can locate an item container at an absolute or configured relative position, check whether an item fits, retrieve the last occupied stack, and remove a full stack or a requested quantity.
Practical guide to the utilities in the Lib folder
Before using these functions
This guide covers the utility classes in src/main/java/Hytale/Modification/hydustrylib/Lib. Check for a valid block reference and component before using a lookup result, and run operations that modify the world or inventories in the appropriate server context.
Getting started
The classes in Lib primarily serve as containers for static methods. They are invoked using the class name; there is no need to create an instance. The examples assume that your mod retrieves the World, CommandBuffer, and block references from the appropriate server context.
import Hytale.Modification.hydustrylib.Lib.EssentialsUtils;
import Hytale.Modification.hydustrylib.Lib.ItemContainerHyDustryLib;
BlockType type = EssentialsUtils.getBlockType(world, blockPosition);
ItemContainerBlock input =
ItemContainerHyDustryLib.GetItemContainerComponent(world, blockPosition);
if (type != null && input != null) {
// Use the block and its inventory within the server context.
}
Several queries will return null if the block, its section, or its component does not exist. Check these results before accessing them. Functions that modify blocks, inventories, or entities must be executed within the appropriate context of the world and its stores.
Block and Coordinate Utilities
EssentialsUtils
Low-level queries for blocks and position conversion. The Vector3i type represents integer block coordinates; the result of getGlobalPosition is a world position.
getBlockType(World world, Vector3i Position): returns theBlockTypeat the position, ornullif it could not be resolved.getBlockSection(World world, Vector3i Position): returns theBlockSectioncontaining the position, ornull.getBlockRef(World world, Vector3i Position): returns the entity reference associated with the block, ornull.getBlockRotation(World world, Vector3i Position): returns the rotation index; returns-1if the section cannot be retrieved.getGlobalPosition(BlockStateInfo, CommandBuffer<ChunkStore>): calculates the world position using the block state's index and section.getGlobalPosition(Vector3ic localPosition, BlockStateInfo, CommandBuffer<ChunkStore>): converts an explicit local position; returnsnullif the section cannot be retrieved.GetComponentType(World, Vector3i, ComponentType): retrieves the requested component from the block at an absolute position, ornullif the block reference is unavailable.getRelativePosition(World, Vector3i, Vector3d): rotates a block-relative offset and resolves filler blocks; honors theHyDustryUtility.Verticaltag.getValidRelativePosition(World, Vector3i, Vector3d): resolves a relative position in the same way and returns it only when a block with data exists there.
Example: querying type and rotation
BlockType type = EssentialsUtils.getBlockType(world, position);
int rotation = EssentialsUtils.getBlockRotation(world, position); if (type != null && rotation >= 0) {
Map<String, String[]> tags = type.getData().getRawTags();
}
The last line requires that type.getData() not be null. A coordinate outside of a loaded section may not yield a valid reference or result.
FillerBlocksHyDustryLib
CalculateRealPositionUsingFillerBlocks(World world, Vector3i Position): if the position belongs to a filler block, it attempts to return the position of the main solid block. If it cannot be resolved, it returns the original position.
It is advisable to apply this function before querying a block that might be part of a multi-block structure.
Vector3i realPosition =
FillerBlocksHyDustryLib.CalculateRealPositionUsingFillerBlocks(world, hitPosition);
BlockType type = EssentialsUtils.getBlockType(world, realPosition);
RailsHyDustryLib: orientation and movement
OrientRails(Vector3d[] points, int direction): returns a copy of the points rotated around the horizontal center of the block. Horizontal direction indices are mapped to four orientations; some indices between 8 and 63 also invert the Y-coordinate.OrientGlobalPositions(Vector3d[] points, int direction): rotates relative displacements. Used for transforming offsets around a block, not for orienting absolute world-space points.RailsCalculateNextPosition(Vector3d[] rotatedPoints, double progressPercent, int smoothing): interpolates between the first three points. Progress is clamped to 0–100; smoothing is clamped to 0–10. If fewer than three points are provided, it returns the center(0.5, 0.5, 0.5).TagsPathsConversion(Map<String, String[]> Tags): converts theHyDustryUtility.Pathstag into vectors. If the tag is missing or empty, it returns a single center point.ConvertingTagstoArrays(Map, String Tag): reads theHyDustryUtility.<Tag>tag as comma-separated coordinates (e.g.,1,0,0). Returnsnullif no values are present.ConvertingTagsPositionstoArrays(Map, String Tag): equivalent to the above, but handles coordinates that may be enclosed in parentheses.vectorArrayToString(Vector3d[] vectors): converts an array into a text format with coordinate triplets enclosed in parentheses; anullor empty array is converted to[].
Example: obtaining an object's position along a path
Map<String, String[]> tags = blockType.getData().getRawTags();
Vector3d[] path = RailsHyDustryLib.TagsPathsConversion(tags);
Vector3d[] orientedPath = RailsHyDustryLib.OrientRails(path, rotation);
Vector3d pointOnBlock =
RailsHyDustryLib.RailsCalculateNextPosition(orientedPath, progressPercent, 0);
Vector3d worldPosition = new Vector3d(position.x, position.y, position.z)
.add(pointOnBlock.x, pointOnBlock.y, pointOnBlock.z);
The path must contain at least three points for interpolation. For offsets relative to the machine, use OrientGlobalPositions instead of OrientRails; both functions apply different conventions.
Utilities for finding block components
EssentialsUtils provides generic component lookup at an absolute position and helpers for rotating relative offsets, resolving filler blocks, and checking that a destination block exists. Relative lookups honor the HyDustryUtility.Vertical tag.
ItemContainerHyDustryLib
GetItemContainerComponent(World, Vector3i): retrieves anItemContainerBlockat an absolute position.GetItemContainerComponent(World, Vector3i, Vector3d): resolves the relative offset from a base block, including rotation and filler blocks, then retrieves the container.ValidationItemForAdding(ItemContainerBlock, ItemStack)andValidationItemForAdding(SimpleItemContainer, ItemStack): check for an empty slot or a compatible stack with room.getLastItem(ItemContainerBlock): returns the last occupied stack in a block container.getLastItem(SimpleItemContainer, int count): returns a copy of up tocountitems from the last occupied stack without changing the container.removeLastItem(ItemContainerBlock): removes the last occupied stack from a block container.removeLastItem(SimpleItemContainer, int count): removes up tocountitems from the last occupied stack.
ConsumerMachineHyDustryLib
ConsumerMachineValidatorComponent(World, int, Vector3i, Map<String, String[]>, Vector3d): searches for a consumer machine at the relative position and returns itsConsumerMachineComponent, or null if it does not exist.
Lookups return null when the requested block or component cannot be resolved. They do not create or add components. Supply a base position and relative offset for relative lookups.
Example: retrieving a relative container
ItemContainerBlock input =
ItemContainerHyDustryLib.GetItemContainerComponent(
world,
machinePosition,
new Vector3d(0, 0, -1)
);
if (input != null && input.getItemContainer() != null) {
// Query or modify the inventory within a valid server context.
}
Inventories
Example: removing one unit without modifying it before inspection
ItemStack preview =
ItemContainerHyDustryLib.getLastItem(container, 1);
if (preview != null && isValidDestination(preview)) {
boolean removed =
ItemContainerHyDustryLib.removeLastItem(container, 1);
if (removed) {
// Transfer preview to the destination.
}
}
ValidationItemForAdding only checks whether there is capacity; it does not add the object or reserve space. Between validation and addition, re-verify the state if other operations might modify the inventory.
Object Entities
EntityHyDustryLib
EntityIsValid(Ref<EntityStore> ref): checks that the reference is valid, has a Store, and possesses aUUIDComponent.ToggleBehaviourInteractionItems(TransformComponent transform, boolean BH, Store<EntityStore> store, Ref<EntityStore> ref): ifBH == false, it adds components that prevent merging and pickup; ifBH == true, it removes them and adjusts the object's position.
This function directly alters the entity's components and transform. Call it only when it is appropriate to temporarily change the object's behavior.
Farming and Harvesting
FarmingHyDustryLib
ProccesingCoopsInRange(CommandBuffer<ChunkStore>, HarvestingEngineComponent, Vector3i, int range, int Phase): iterates through the area around the engine and applies irrigation, fertilizer, growth acceleration, or harvesting, depending on the component's settings.AccelerateGrowthInBlock(CommandBuffer<ChunkStore>, Ref<ChunkStore>, World, BlockType): advances the crop's progress toward the next stage.WateringInBlock(CommandBuffer<ChunkStore>, Ref<ChunkStore>, World, float WateringTime): extends the irrigation duration and delays the degradation of tilled soil.WateringAndFertilizedInBlock(...): performs irrigation and also marks the soil as fertilized.FertilizedInBlock(CommandBuffer<ChunkStore>, Ref<ChunkStore>): marks tilled soil as fertilized.UpdateGrowthInBlock(CommandBuffer<ChunkStore>, Ref<ChunkStore>, World): schedules an update for the crop component.AccelerateCropGrowth(Vector3i, World): a variant that directly retrieves block references and advances growth to the next stage; it is marked@Insecure.ScheduleInstantUpdate(CommandBuffer<ChunkStore>, Ref<ChunkStore>, World): schedules a new tick for the block; it is marked@Insecure.
Functions marked @Insecure require special care regarding block references and components. Prefer the variants that accept a CommandBuffer when the system already has one available.
HarvestingHyDustryLib
HarvestInSimpleContainer(Vector3i blockPosition, World world, ItemContainerBlock container): retrieves harvest drops and adds them to the inventory; it may reset a crop to its subsequent growth stage or replace the harvested block with air. Returns a boolean indicating the outcome of the harvest operation.HarvestValidationGatheringInContainer(Vector3i, World, ItemContainerBlock): checks the harvest configuration and whether the inventory can accept any of the drops.HarvestBlockValidation(Vector3i, World): checks whether the block has a drop configuration and if its crop configuration allows it to be processed.
Before harvesting, check the block type and the inventory. The harvest function may modify both the world and the container; do not use it as a read-only query.
API Annotations
@safe(reason = "..."): a source-level annotation used to identify methods or constructors considered stable by the library.@Insecure(reason = "..."): a source-level annotation used to warn that a method or constructor requires caution.
These annotations do not replace runtime validation, nor do they automatically apply any protections. Their retention is SOURCE, meaning they are not preserved as metadata at runtime.
for Node Editor programmers
Guide for configuring blocks, components, and tags using the Hytale Node Editor
Scope and Warnings
This guide outlines the keys and fields that are read or registered by the current code in HyDustry Lib. Tags represent block data, while components are distinct data elements added to a block via the editor. Not all tags are required for every block. Any keys not mentioned here are not currently used in the reviewed code.
Important: The current code looks for keys that begin with HyDustryUtility.. A key named HyDustry.Behaviour is not equivalent to HyDustryUtility.Behaviour and will not trigger the conveyor behavior described in this guide.
How a Tag Is Represented
HyDustry Lib receives block tags as a Map<String, String[]>: each entry consists of a text key mapped to an array of text values. In Hytale source files, the format looks like this:
{
"HyDustryUtility.Machine.Behaviour": ["Essence Extractor"],
"HyDustryUtility.Machine.Scanner.Positions": ["0,0,-1", "1,0,-1"]
}
- Tag names and all elements within their arrays are strings, even if they represent numbers or booleans.
- The order of values matters in parallel lists: the element at index 0 corresponds to the value at index 0 of its associated tag.
- Coordinates are written as
x,y,z. Use a decimal point for fractions—for example,0.5,0.5,1.0. - Do not include comments within the JSON. Snippets in this guide containing
//are for explanation only and are not part of the data. - A "flag" type tag can be activated simply by being present, regardless of the text it contains. For these, using
["true"]is recommended.
Rule of thumb: Tags vs. Components
Tags: Describe configuration that the code reads from a block's raw tags. Examples include recipes, scanner positions, paths, and input/output offsets.
Components: Store the state and options for HyDustry Lib systems. The plugin registers three components: ConsumerMachineComponent, ConveyorTransporterComponent, and HarvestingEngineComponent. Add these to the appropriate block via the editor and configure their fields in the component panel. Do not convert these fields into tags, unless the code explicitly indicates that it reads a tag.
The component examples below show the editable fields registered by the codec, not the entire Hytale block file wrapper. The exact way in which the Node Editor serializes or references components depends on the Hytale block format and should not be inferred from the tag map.
Summary of recognized tags
| Full tag | Usage | Expected type |
|---|---|---|
HyDustryUtility.Machine.Behaviour |
Name of the machine operation, for example Essence Extractor. |
A name within an array of strings. |
HyDustryUtility.Machine.Output.Items / HyDustryUtility.Machine.Output.Counts |
Direct products of the default machine behavior. | Parallel lists: item IDs and integer quantities. |
HyDustryUtility.Machine.Requiere.Items / HyDustryUtility.Machine.Requiere.Counts |
Required ingredients. The code literally uses Requiere, with that exact spelling. |
Parallel lists: IDs and integer quantities. |
HyDustryUtility.Machine.Fuel.Items / HyDustryUtility.Machine.Fuel.Counts |
Available fuels and the quantity of each. | Parallel lists: IDs and integer quantities. |
HyDustryUtility.Machine.Fuel.Upgrades.N.* |
Ingredients and production time for upgrade level N. | See the "Fuel and Upgrades" section. |
HyDustryUtility.Machine.Scanner.Require.Items |
Its presence triggers the verification and consumption of ingredients in the Extractor. |
A flag; the content is not read. |
HyDustryUtility.Machine.Scanner.Positions |
Relative offsets of the blocks to be scanned by the extractor. | A list of coordinate strings. |
HyDustryUtility.Machine.Scanner.Blocks |
An ordered list of drop IDs recognized by the extractor. The index determines the output group. | A list of ID strings. |
HyDustryUtility.Machine.Output.Items.N / HyDustryUtility.Machine.Output.Counts.N |
The output recipe associated with index N of Scanner.Blocks. |
Parallel lists: item IDs and integer quantities. |
HyDustryUtility.Machine.Output.Items / HyDustryUtility.Machine.Output.Multiplicator |
In the extractor, this links the detected ID to its multiplier. | Parallel lists: resource IDs and decimal multipliers. |
HyDustryUtility.Machine.Output.Multiplicator.Timer.ID |
Time values indexed by the quantity detected for the specified ID. | An array of millisecond values (as strings); see the note regarding indexing. |
HyDustryUtility.Machine.Output.Timer.N |
A key read by an auxiliary helper for index N. | An integer (as a string); currently not used by Extractor.Execute. |
HyDustryUtility.Machine.Fuel.Scanner.Upgrades.N.Items / ...Multiplicator |
Scanner multipliers unlocked via a fuel upgrade. | Parallel lists of IDs and decimal values. |
HyDustryUtility.Paths |
Local path points followed by objects on a conveyor belt. | Ordered list of coordinate strings. |
HyDustryUtility.Behaviour |
A flag that allows the listener to treat the block as a conveyor belt surface; the value itself is not read. | Presence-based flag. |
HyDustryUtility.Behaviour.Loocking |
Activates a continuous search state for the conveyor belt when an object touches it. Note: the key is spelled Loocking in the code. |
Presence-based flag. |
HyDustryUtility.Items.Load.Positions |
Relative offsets where the conveyor belt searches for containers to pick up items. | List of coordinate strings. |
HyDustryUtility.Items.Save.Positions |
Relative offsets where the conveyor belt attempts to deposit an item upon completing its path. | List of coordinate strings. |
HyDustryUtility.Vertical |
Instructs neighboring block validators to use a vertical offset instead of the expected horizontal displacement. | Presence-based flag; the value is not read. |
ConsumerMachineComponent
Add this component to the block representing a processing machine. The input and output containers are references/data from ItemContainerBlock that must be configured in the component's fields via the Node Editor; they are not object IDs within the tags.
| Component field | Type | Current usage |
|---|---|---|
Manufacturing time (1s -> 1000mls) |
long | Base manufacturing time in milliseconds. |
It requires energy |
boolean | Stored, but the current implementation does not verify an energy source. |
It requires fuel |
boolean | If true, the code searches for and consumes the configured fuel. |
Type of operation |
string | Operation name; must match a registered operation. The plugin registers Essence Extractor. |
InputItemsContainer |
ItemContainerBlock | Container that provides ingredients and fuel. |
OutputItemsContainer |
ItemContainerBlock | Container that receives the products. |
Position by single check [PBSC] |
string | Internal positioning field; updated by the system. |
SystemRaw [System] |
string | Internal serialization of raw tags; initialized by the listener. |
LastManufacture [System] |
string | Internal timestamp for the cooldown period. Do not configure manually. |
1. Machine with default behavior
Set the operation to Default and add the tags for products and requirements. Quantities that are missing or cannot be read are interpreted as 1. This behavior verifies the ingredients before manufacturing.
Raw tags:
{
"HyDustryUtility.Machine.Behaviour": ["Default"],
"HyDustryUtility.Machine.Requiere.Items": ["Ingredient_Crystal", "Ingredient_Dust"],
"HyDustryUtility.Machine.Requiere.Counts": ["2", "3"],
"HyDustryUtility.Machine.Output.Items": ["Refined_Crystal", "Byproduct_Dust"],
"HyDustryUtility.Machine.Output.Counts": ["1", "2"]
}
Component fields in Node Editor:
Type of operation: "Default"
Manufacturing time (1s -> 1000mls): 5000
It requires energy: false
It requires fuel: false
InputItemsContainer: assign the input container
OutputItemsContainer: assign the output container
The example requires two units of Ingredient_Crystal and three of Ingredient_Dust to produce one unit of Refined_Crystal and two of Byproduct_Dust. The IDs are examples; replace them with valid IDs from your mod.
2. Extractor with multiple resource types
The extractor scans positions relative to the block, identifies harvestable blocks whose drops are listed in Scanner.Blocks, counts the matches, and uses the most frequent resource. The index of each resource in Scanner.Blocks corresponds to its respective output tags, Output.Items.N and Output.Counts.N.
{
"HyDustryUtility.Machine.Behaviour": ["Essence Extractor"],
"HyDustryUtility.Machine.Scanner.Positions": [
"0,0,-1",
"1,0,-1",
"-1,0,-1",
"0,0,-2"
],
"HyDustryUtility.Machine.Scanner.Blocks": [
"Ore_Copper",
"Ore_Iron"
],
"HyDustryUtility.Machine.Output.Items.0": ["Ingot_Copper"],
"HyDustryUtility.Machine.Output.Counts.0": ["2"],
"HyDustryUtility.Machine.Output.Items.1": ["Ingot_Iron"],
"HyDustryUtility.Machine.Output.Counts.1": ["1"],
"HyDustryUtility.Machine.Output.Items": ["Ore_Copper", "Ore_Iron"],
"HyDustryUtility.Machine.Output.Multiplicator": ["1.5", "2.0"]
}
In this example, index 0 in Scanner.Blocks is Ore_Copper; therefore, its recipe uses Output.Items.0. Index 1 is Ore_Iron. If four copper blocks are detected, the system uses the primary product and the scanner's base quantity, combined with the configured multiplier. The final result may be rounded, as the extractor converts the calculated value into an integer.
If Scanner.Positions is not specified, the extractor attempts to use a single default position: 0,0,-1.
Without Scanner.Blocks, there is no list of accepted resources to associate with the outputs.
Optional Extractor Ingredients
To require the extractor to have specific materials before processing, include the tag HyDustryUtility.Machine.Scanner.Require.Items. Its value is not checked—the mere presence of the key is sufficient. The quantities and IDs are read from the key labeled Requiere.
{
"HyDustryUtility.Machine.Scanner.Require.Items": ["true"],
"HyDustryUtility.Machine.Requiere.Items": ["Catalyst"],
"HyDustryUtility.Machine.Requiere.Counts": ["1"]
}
In the extractor, if the Scanner.Require.Items flag is absent, the Requiere ingredients are neither checked nor consumed. In the Default behavior, however, ingredient verification is part of the production flow and does not depend on that flag.
3. Fuel and Upgrade Levels
To use fuel, enable It requires fuel in the component and configure the lists. The code searches for the fuel...the one that appears later in the list and for which a sufficient quantity is available. The upgrade level is determined by the fuel's position: the first fuel corresponds to level 1, the second to level 2, etc. The levels must be consecutive, starting from 1.
{
"HyDustryUtility.Machine.Fuel.Items": ["Fuel_Basic", "Fuel_Advanced"],
"HyDustryUtility.Machine.Fuel.Counts": ["1", "2"],
"HyDustryUtility.Machine.Fuel.Upgrades.1.Items": ["Catalyst"],
"HyDustryUtility.Machine.Fuel.Upgrades.1.Counts": ["1"],
"HyDustryUtility.Machine.Fuel.Upgrades.1.ManufacturingTime": ["CraftTime"],
"HyDustryUtility.Machine.Fuel.Upgrades.1.TimeCounts": ["4000"],
"HyDustryUtility.Machine.Fuel.Upgrades.2.Items": ["Catalyst", "Shard"],
"HyDustryUtility.Machine.Fuel.Upgrades.2.Counts": ["2", "1"],
"HyDustryUtility.Machine.Fuel.Upgrades.2.ManufacturingTime": ["CraftTime"],
"HyDustryUtility.Machine.Fuel.Upgrades.2.TimeCounts": ["2000"],
"HyDustryUtility.Machine.Fuel.Scanner.Upgrades.1.Items": ["Ore_Copper"],
"HyDustryUtility.Machine.Fuel.Scanner.Upgrades.1.Multiplicator": ["2.5"]
}
When an upgrade time needs to be read, the code takes the first numerical value from TimeCounts. The text CraftTime is a parallel key required by the parser, not an object ID consumed by the system. Regarding scanner upgrades, the multiplier for a given resource replaces the standard multiplier if active fuel is present and the corresponding upgrade is found.
The Fuel.Upgrades.N.ManufacturingTime tag is processed using the same pair-parsing logic employed for IDs and quantities. It requires at least one element in both arrays and an integer in TimeCounts; only the first resulting value is used as the duration. Please test this configuration within your target version of Hytale before distributing it.
Time multiplier based on scanned quantity
The extractor can look up a dynamic tag for each resource: HyDustryUtility.Machine.Output.Multiplicator.Timer.<ID>. The system attempts to select a duration based on the quantity of the predominant resource. If no valid value is found, it defaults to the component's Manufacturing time.
{
"HyDustryUtility.Machine.Output.Multiplicator.Timer.Ore_Copper": [
"1000",
"2000",
"3000",
"4000",
"5000"
]
}
Important note on the current code: For a detected quantity N, the value at index N-1 is read—but only if the array contains more than N elements. Consequently, the current implementation requires an extra value: to support up to 4 blocks, the array must contain at least 5 values. This behavior is likely a boundary error in the code and should not be interpreted as an intentional requirement of the Node Editor format.
While HyDustryUtility.Machine.Output.Timer.N can be accessed via a helper utility, Extractor.Execute does not utilize that helper.
For the current extractor, the active key is Output.Multiplicator.Timer.<Resource ID>.
ConveyorTransporterComponent
Add this component to the conveyor block so that the ticking systems can update its progress and search for or deposit items.
| Component Field | Usage |
|---|---|
Velocity |
The progress increment applied per tick while an item is moving. The code adds this value until it reaches 100; adjust and test the value based on the desired speed. |
Progress (Only Tags) |
The travel state, ranging from 0 to 100. This is updated by the system; it is not a raw tag with that specific name. |
ItemsDetected (Only Tags) |
A temporary indicator triggered by the item listener. The system reads it and then clears it. |
Looking Behaviour (Only Tags) |
A temporary state triggered by the tag HyDustryUtility.Behaviour.Loocking. |
Only Velocity is a recommended direct configuration option; the other three fields represent execution status.
Tags for a tape with route and loading/unloading
{
"HyDustryUtility.Behaviour": ["true"],
"HyDustryUtility.Behaviour.Loocking": ["true"],
"HyDustryUtility.Paths": [
"0.5,0.5,0.0",
"0.5,0.5,0.5",
"0.5,0.5,1.0"
],
"HyDustryUtility.Items.Load.Positions": [
"0,0,-1",
"1,0,0"
],
"HyDustryUtility.Items.Save.Positions": [
"0.0,1"
]
}
Behaviour allows the object to recognize the block as part of the path. Looking causes the conveyor to continue moving in search mode after a detection. The listener uses default loading positions—0,0,-1, 1,0,0, and -1,0,0—if no loading tag exists; for unloading, it uses 0,0,1 if no unloading tag is present.
Loading/unloading offsets are interpreted relative to the conveyor's rotation and are used to locate neighboring blocks containing containers or machines. The Paths points define the object's position within the block; at least three distinct points must be defined to create a path that includes a start, a curve, and an end.
Component fields in the Node Editor:
Velocity: 1.0
Progress (Only Tags): 0.0
ItemsDetected (Only Tags): false
Looking Behaviour (Only Tags): false
Leave the progress at 0 and the indicators set to false when creating the conveyor belt. The system will update them during operation.
HarvestingEngineComponent
Add this component to the agricultural engine block. No HyDustryUtility.Machine.* tags are required to trigger its actions; these options are configured within the component itself.
| Field | Type | Current Usage |
|---|---|---|
Range |
long | Search radius applied across the X, Y, and Z axes; the area it is a cube, not a sphere. |
Interval |
long | Interval between actions, in milliseconds. |
DecayWatering |
int | Passed as the duration for watering; the current method calculates approximately 60 seconds per unit. |
Water |
boolean | Activates watering. |
Fertilize |
boolean | Activates fertilization. |
Accelerate |
boolean | Activates growth acceleration. |
Harvest |
boolean | Activates the search for and harvesting of blocks around the engine. |
Fase |
long | Incremented and reset by the listener, but the current processor does not use it to change actions. |
DecayAccelerate |
float | Stored, but does not affect the current acceleration calculation. |
LastActionTime |
string | Internal marker for scheduling the next action. Keep the initial value; it is updated by the system. |
Example configuration: care engine
{
"Fase": 0,
"Range": 3,
"Interval": 5000,
"DecayWatering": 10,
"DecayAccelerate": 1.0,
"Water": true,
"Harvest": false,
"Fertilize": true,
"Accelerate": true,
"LastActionTime": "1970-01-01 00:00:00"
}
With this example, the engine inspects a cube of 7x7x7 blocks; it attempts to perform an action every 5000 ms—watering, fertilizing, and accelerating crops—but it does not harvest. DecayWatering is converted into seconds using the formula already present in the code. Fase and DecayAccelerate are included because the component exposes them, even though they do not currently affect the processing outcome.
Example configuration: harvester
{
"Fase": 0,
"Range": 2,
"Interval": 10000,
"DecayWatering": 0,
"DecayAccelerate": 1.0,
"Water": false,
"Harvest": true,
"Fertilize": false,
"Accelerate": false,
"LastActionTime": "1970-01-01 00:00:00"
}
Harvesting places drops into the engine's local container when available. It verifies that the engine block has a compatible inventory and that the target blocks have harvest/collection data configured.
Vertical Tag and Neighboring Block Validators
Input/output validators, containers, and neighboring components check for the presence of HyDustryUtility.Vertical. If it is absent, they apply the expected horizontal offset after rotating the block. If it is present, they leave the X/Z coordinates unchanged and apply a vertical (Y) offset, with the sign determined by the rotation index.
{
"HyDustryUtility.Vertical": ["true"]
}
The tag does not specify the vertical distance:The code uses exactly one block’s distance upward or downward. This behavior is specific to HyDustry Lib validators; it does not apply to all machines or the scanner.
Common Errors
- Using the wrong prefix: writing
HyDustry.Behaviourinstead ofHyDustryUtility.Behaviour. - Using an incorrect ingredient key: the code expects
Machine.Requiere.Items—notMachine.Require.ItemsorMachine.Requires.Items. - Forgetting the component: tags describe positions and recipes, but they do not automatically add the
ConsumerMachineComponent,ConveyorTransporterComponent, orHarvestingEngineComponent. - Confusing quantities with JSON numbers: tag arrays are
String[]; write["2","5"], not[2,5]. - Misaligning lists: ensure the index-based correspondence is maintained between
ItemsandCounts, as well as betweenScanner.Blocksand the recipe’sOutput.Items.N/Output.Counts.N. - Using an incomplete path: movement is interpolated across the first three points; you must define a start, an intermediate point, and an end.
- Expecting functional energy:
It requires energyis serialized, but it is not currently checked by the logic. - Setting the wrong auxiliary timer:
Output.Timer.Ndoes not currently controlExtractor.Execute; The key referenced by that operation isOutput.Multiplicator.Timer.ID.
Checklist before testing
- Confirm that the keys use the exact prefix
HyDustryUtility.. - Add the corresponding component to the block via the Node Editor.
- Configure the input/output containers within the machine component, rather than as text tags.
- Ensure that each tag contains an array of strings and that the parallel lists maintain the same order.
- Verify that the configured operation matches the registered name exactly—for example,
Essence Extractor. - Begin testing with a small number of items, short distances, and a moderate interval; verify in-game that the offsets and rotations align with the block's orientation.

