Skip to main content

Farming libraries

require("hexis/skyblock/farming") runs Lua farming recipes, an optional session object and the existing marked-layout helpers.

Use the farming capability for native harvesting. The facade also reads the player through world.entities.read. Default crop presentation requires profit; persistent restart hints require checkpoint. A custom HUD can omit profit entirely.

Inline recipes

An inline recipe describes what to harvest and the allowed inputs:

local recipe = {
crop = {
block_ids = { "minecraft:wheat" },
maturity = { property = "age", at_least = 7 },
},
movement = {
look = { mode = "fixed", yaw = 135, pitch = 0 },
sections = {
{ name = "Upper", passes = { "W", "D" } },
{ name = "Lower", passes = { "A", "S" } },
},
},
tool = { name_patterns = { "Euclid", "Hoe" } },
}

Sections are ordered highest to lowest. For a farm with one set of inputs, supply one section. Four inputs can describe first pass, crossing, return pass, crossing. pattern = "single_lane" requires one input and ends at an observed obstruction. Omitting look, or using { mode = "auto" }, enables startup angle inference. Fixed mode requires both numeric angles and accepts decimals.

Optional health specifies zero_break_seconds, critical and warning. See the generated FarmingRecipe type for the closed fields and limits. Both farming.harvest(recipe, settings) and farming.session({recipe = recipe, config = settings}) use the same settings mapper. It copies the recipe, applies exposed choices and passes only crop/movement/tool/health fields to Java. Missing settings preserve recipe defaults. Current map uses preset angles and passes; Custom uses its configured angles and key cycle. Tool, delay, health and remembering settings override the matching defaults in either mode.

For the default profit HUD, a Lua definition can also include name, products, quantity_groups and byproducts. They stay in Lua. There is no separate crop JSON file. Generic content packs remain available for other script workloads.

Optional project layout

Download the template, or use this layout:

bundle.json
main.lua
farm.lua
hud.lua
activities.lua

main.lua composes ordinary modules:

local farming = require("hexis/skyblock/farming")

function hexis.main()
local result = farming.session({
recipe = require("farm"),
config = hexis.config.snapshot(),
presentation = require("hud"),
activities = require("activities"),
}):run()
hexis.script.stop({ reason = result.message or "Farming stopped" })
end

Splitting files is optional. There are no base classes to extend and filenames grant no special access. The manifest declares capabilities for the whole bundle.

Custom presentation

Customize a farming HUD gives a complete renderer and explains what each edit changes. Choose farming readings explains the source and lifetime of each value.

The renderer receives a native snapshot through presentation:update(snapshot). It can draw a HUD, record readings, or do both. Set presentation = false for no renderer. Omitting it uses the default HUD when the Lua recipe has products.

Snapshots provide phase, resolved look, section/pass, elapsed time, BPS, direct break totals, health and an optional stable checkpoint. Startup omits fields that are not available yet. Counts are local predictions.

The default presentation keeps Bazaar/NPC estimates, historical comparisons and skill ETAs in Lua. A custom renderer can use those APIs differently or leave them out. Rendering must not move, aim or run activities.

Optional activities

Each activity table supplies:

  • id: unique within this session.
  • priority: higher values are checked first.
  • ready(context): a short, nonblocking readiness check.
  • run(context): returns a native action handle without awaiting it.
  • return_to(context): optional return action, also a handle.
  • timeout_seconds: timeout per action, default 60, maximum 300.

The context contains the latest snapshot and configuration. Once admitted, it also includes the pause checkpoint. A readiness function must not take controls.

The session requests a pause, then waits for harvesting to finish with data.reason == "paused". An accepted pause request alone does not mean controls have been released. A drop, turn or recovery can delay the pause. If no stable pause is available within ten seconds, farming stops and the activity is not run.

The wrapper awaits each activity action and cancels it on timeout. Activity failure or cancellation does not resume farming. Before resuming, return within one block horizontally and 0.3 blocks vertically of the checkpoint in the same world. The resumed action requires the checkpoint's recipe and floor to match; it stops before input if that checkpoint has become stale.

The template starts with an empty activity list. Selling, pests and visitors must supply their own actions and return behavior. Their names have no built-in meaning. BPS restarts for each harvest action; the default profit and skill presentation continues across the whole Lua session.

Direct action control

For a custom orchestrator, start hexis.farming.crop.harvest({world_generation, recipe}), read hexis.farming.session.observe({action = action}), and request a cooperative pause with hexis.farming.session.pause({action = action}). Wait for the result before taking controls. When returning from optional work, pass checkpoint and require_checkpoint = true to the next harvest action. Its data.snapshot remains readable after the handle has been consumed by await or select.

Use hexis.cancel for cancellation. Cancellation is never a resumable pause. Persist a native checkpoint with the ordinary checkpoint API if wanted; an incompatible checkpoint cannot bypass startup checks.

Marked layouts

farming.inspect({farm = ...}) validates a marked layout without moving. farming.run({farm = ..., max_seconds = ...}) runs its bounded segments. farming.run_rows(options) anchors a finite row template at the player. These helpers remain available for scripts that want explicit route coordinates. Their implementations are separate under farming/marked/ and are loaded only when called. Ordinary harvesting uses the native action through the session. Authors do not need to import the marked implementation files.

The Camera Angles, Held Input and S-shape Farming development labs still use the ordinary physical-input APIs. The S-shape lab inspects by default and requires a solid, level walking floor. It does not infer a farm or swim across water.

See camera and held input for custom movement contracts.