Metadata-Version: 2.4
Name: minescript
Version: 1.1.9
Summary: Python helper module for the local Minescript Fabric bridge
Keywords: minecraft,fabric,automation,minescript
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# MinePyScript

MinePyScript is the installable Python client for the Minescript Fabric mod. It talks to the running Minecraft client over a local HTTP bridge and exposes a Python-first API for player control, inventory automation, world queries, events, and Litematica integration.

This package does not contain Minecraft logic by itself. It is a transport and convenience layer on top of the running Minescript mod.

## Contents

- What this package is
- Installation and build
- How the bridge works
- Runtime requirements and environment variables
- Quick start examples
- API reference
- Litematica guide
- Events and long-running scripts
- Return values, errors, and compatibility notes

## What This Package Is

MinePyScript gives you two ways to talk to the mod:

1. High-level helper functions such as `getplayerpos()`, `sendchat()`, `movetoposition()`, and `getnearestmissingblock()`.
2. Dynamic bridge access through `methods()`, `call()`, and attribute fallback like `minescript.somebridgemethod(...)`.

The package is designed so that newer or slightly renamed bridge methods can still work when possible. Several helpers inspect the live method list exposed by the mod and resolve the best matching RPC name at runtime.

## Installation And Build

Install from the local package source:

```text
py -m pip install .
```

Build source and wheel distributions:

```text
py -m build
```

## Runtime Requirements

- The Minescript Fabric mod must be installed in Minecraft.
- Minecraft must be running with the bridge available.
- The Python package connects to `http://127.0.0.1:<port>/invoke`.
- The default port is `47641`.

### Environment Variables

- `MINESCRIPT_PORT`
    Sets the local bridge port. Use this if your mod is not listening on `47641`.

- `MINESCRIPT_CONTROL_PREFIX`
    Prefix used for stdout control messages that are sent back to the Java runner.

- `MINESCRIPT_MENU_CLOSE_COMMAND`
    Control command name used by menu-close fallback logic. Default is `close_menu`.

## How The Bridge Works

Every helper eventually sends a JSON request like this to the local mod bridge:

```json
{
    "method": "getplayerpos",
    "args": {}
}
```

The mod replies with JSON that is decoded into regular Python objects.

### Key Runtime Behaviors

- `methods()` asks the mod for the full list of currently exposed bridge methods.
- `call(name, *args, **kwargs)` uses the live bridge metadata to bind positional arguments to the correct parameter names.
- Accessing an unknown attribute on the module falls back to dynamic bridge invocation. That means `minescript.foo(...)` will try to call the bridge method `foo`.
- Some helpers such as the Litematica compatibility functions use runtime method discovery so they can survive bridge naming differences across mod versions.
- `closecurrentmenu()` first prefers a real bridge method and falls back to local control behavior when necessary.

## Quick Start

### Basic Example

```python
import minescript

print(minescript.getmodinfo())
print(minescript.getplayerpos())
print(minescript.gettargetblock())
minescript.sendchat("Hello from Python")
```

### Discovering The Live Bridge Surface

```python
import minescript

for method in minescript.methods():
        print(method["name"], method.get("params", []))
```

### Calling A Bridge Method Dynamically

```python
import minescript

result = minescript.call("movetoposition", 100, 64, 200, tolerance=0.5, sprint=True)
print(result)
```

### Using Attribute Fallback

```python
import minescript

print(minescript.getdimension())
print(minescript.listmethods())
```

## API Reference

This section documents the public helpers exposed by `minescript.__init__`.

### Discovery And Dynamic Invocation

#### `methods(force=False)`

Returns metadata for every bridge method exposed by the running mod.

Use it when:

- You want to inspect capabilities at runtime.
- You need the exact parameter names for `call()`.
- You want to support multiple mod versions.

#### `call(method, *args, **kwargs)`

Invokes any bridge method dynamically.

Behavior:

- If the method is known from `methods()`, positional arguments are mapped to the bridge parameter names automatically.
- If the method is unknown to the cached metadata and you pass only keyword arguments, it still attempts a direct bridge call.
- If required arguments are missing, it raises `TypeError` before making the request.

Example:

```python
import minescript

minescript.call("lookat", x=120, y=68, z=-30)
```

#### `litematicamethods(force=False)`

Returns bridge methods whose names or aliases look related to Litematica or schematics.

Use it to confirm what your installed mod exposes before relying on a helper.

### Chat, Logging, And Control Messages

#### `getchat(limit=20)`

Returns the most recent captured chat lines.

#### `sendchat(message)`

Sends a chat message or command exactly as if the local player typed it.

Examples:

```python
minescript.sendchat("Hello world")
minescript.sendchat("/time set day")
```

#### `log(message)` and `error(message)`

Emit structured log control messages back to the Java runner.

These do not directly call the HTTP bridge. They print a prefixed control payload to stdout so the runner can mirror or process the message.

#### `enablelog()` and `disablelog()`

Enable or disable mirroring future script output into Minecraft chat.

#### `emitcontrol(payload)`

Sends a raw control payload to the Java runner over stdout.

The payload must be a `dict`.

Example:

```python
minescript.emitcontrol({"command": "flash_overlay", "color": "red"})
```

### Player Identity, Position, And View

#### `getmodinfo()`

Returns Minescript mod metadata plus current player identity information.

#### `getplayerpos()`

Returns local player position, rotation, and block coordinates.

Typical fields depend on the mod version, but this is the main helper for obtaining the player anchor used by navigation and distance logic.

#### `lookat(x, y, z)`

Rotates the local player to face the world-space target position.

### Clicks, Item Use, And Held Input

#### `leftclick()`

Performs a normal left-click attack or block hit.

#### `rightclick()`

Performs a normal right-click interaction.

#### `useitem()`

Uses the held main-hand item directly.

#### `placeblock(face=None)`

Places the held block using the dedicated bridge method.

Behavior:

- If `face` is omitted, the mod decides the placement face from the current target context.
- If `face` is provided, it is forwarded as the bridge `face` argument.
- The accepted face names depend on the running mod implementation, but values like `"up"`, `"down"`, `"north"`, `"south"`, `"east"`, and `"west"` are the intended shape.

Example:

```python
import minescript

minescript.placeblock()
minescript.placeblock("up")
```

#### `holdleftclick(state=True)` and `holdrightclick(state=True)`

Press or release the attack or use-item input.

These require matching bridge support in the installed mod. If that support is missing, the helper raises a clear compatibility error.

#### `useitemfor(seconds, interval=0.1)`

Timed hold for default item-use behavior.

#### `useitemrightfor(seconds, interval=0.1)`

Timed right-click hold.

#### `useitemleftfor(seconds, interval=0.1)`

Timed left-click hold for mining or attacking.

#### `useitem_right_for(seconds, interval=0.1)` and `useitem_left_for(seconds, interval=0.1)`

Snake-case aliases for the timed helpers.

### Movement And Navigation

#### `jump()`

Makes the local player jump once.

#### `moveforward(state=True)`, `moveback(state=True)`, `moveleft(state=True)`, `moveright(state=True)`

Press or release the movement keys.

#### `forward(state=True)`, `back(state=True)`, `left(state=True)`, `right(state=True)`

Aliases for the movement helpers above.

#### `stopmoving()`

Releases scripted movement inputs.

#### `sneak(state=True)` and `sprint(state=True)`

Enable or disable sneaking and sprinting.

#### `movetowards(x, y, z, stop_distance=1.0, sprint=False)`

Turns toward a target and holds forward movement until you are within `stop_distance`.

#### `movetoposition(x, y, z, tolerance=1.0, sprint=False, timeout_ms=15000)`

Walks toward a target position until it is reached or the timeout expires.

#### `navigatetoposition(x, y, z, tolerance=1.0, sprint=False, timeout_ms=20000)`

Like `movetoposition()`, but with simple recovery behavior for getting stuck.

Use `navigatetoposition()` when pathing is slightly messy and `movetoposition()` is too brittle.

### Inventory, Hotbar, And Menus

#### `getobjectatinventorryslot(slot)`

Returns item data for a visible inventory slot.

The function name keeps the original misspelling for compatibility.

#### `getinventory()`

Returns the visible slots from the current screen handler.

Inventory item payloads now include a `lore` field containing the rendered lore lines for each slot item.

#### `getitemlore()`

Returns the lore lines for the item in the currently selected hotbar slot.

This uses `getselectedhotbarslot()` and then reads the current slot item payload.

#### `getitemloreatslot(slot)`

Returns the lore lines for a visible inventory slot.

`slot` can be:

- a raw integer slot index
- a dictionary containing a `slot` field

Example:

```python
import minescript

print(minescript.getitemlore())
print(minescript.getitemloreatslot(13))
```

#### `clickslot(slot, button=0, action_type="PICKUP")`

Performs a slot click using Minecraft slot action semantics.

Useful `action_type` values depend on the mod and the screen, but `PICKUP` is the default.

#### `quickmoveslot(slot)`

Shift-clicks a slot.

#### `dropslot(slot)`

Drops the item stack in the given slot.

#### `swapslots(slot_a, slot_b)`

Swaps two slots using a pickup sequence.

#### `getselectedhotbarslot()`

Returns the selected hotbar slot index.

#### `selecthotbarslot(slot)`

Selects a hotbar slot by index `0..8`.

#### `closecurrentmenu()`

Closes the active menu if one is open.

Behavior:

- Uses `closecurrentmenu` if the bridge exposes it.
- Falls back to `closemenu` if that older bridge method is available.
- Falls back again to local control behavior when no bridge method exists.

On Windows, the final fallback sends a native `Esc` keypress.

On other runners, the default control message is:

```python
{"command": "close_menu"}
```

#### `closemenu()`

Alias for `closecurrentmenu()`.

#### `set_menu_close_handler(handler=None)`

Registers a Python callback used when no native bridge menu-close method is available.

Example:

```python
import minescript

def my_close_handler():
        minescript.emitcontrol({"command": "close_menu_via_java"})

minescript.set_menu_close_handler(my_close_handler)
```

### World, Target, And Status Queries

#### `gettargetblock()`

Returns block information for the current crosshair target, or `None`.

#### `getnearestblockdata(block_id=None, radius=8)`

Returns the nearest matching non-air world block around the player.

#### `getblocksinrange(block_id=None, radius=8, limit=256)`

Returns nearby world blocks sorted by distance.

#### `gettargetentity()`

Returns entity information for the current crosshair target, or `None`.

#### `gethealth()`, `gethunger()`, `getarmor()`

Return the player health, hunger, saturation, and armor state.

#### `getdimension()` and `getbiome()`

Return the current dimension identifier and current biome identifier.

#### `getnearbyentities(radius=16.0)`

Returns nearby entity data.

#### `getnearbyplayers(radius=16.0)`

Returns nearby player data including facing, velocity, and held-item information when available.

#### `getleaderboard()`

Returns the sidebar scoreboard title and entries.

#### `getleaaderboard()`

Compatibility alias for the original misspelled helper.

## Litematica Guide

Litematica support in this package comes in three layers:

1. Compatibility helpers that find the correct bridge method at runtime.
2. Higher-level helpers built on top of the generic reflection bridge.
3. Direct reflection access when you need something not wrapped yet.

### Placement Queries

#### `getnearestschematicplacement(radius=32.0)`

Returns the nearest placed schematic exposed by the running mod.

#### `getnearbyschematicplacements(radius=32.0, limit=64)`

Returns nearby placed schematics.

These functions search the live bridge method list and choose the best matching method name, which is why they can work across compatible mod revisions with slightly different RPC names.

### Schematic Block Queries

#### `getschematicblockat(x, y, z)`

Returns block information from the rendered schematic world at the exact coordinates, or `None` for air.

#### `getnearestschematicblock(block_id=None, radius=8)`

Returns the nearest non-air schematic block around the player.

#### `getschematicblocksinrange(block_id=None, radius=8, limit=256)`

Returns schematic blocks sorted by distance from the player.

### Render Layer Queries And Control

#### `getlitematicarenderlayer()`

Returns the current Litematica render layer state. The result includes:

- `mode`
- `axis`
- `single`
- `above`
- `below`
- `range_min`
- `range_max`
- `layer_min`
- `layer_max`
- `current`

#### `raiselitematicalayer(amount=1)`

Moves the current render layer upward by the requested number of steps and returns the updated layer state.

#### `lowerlitematicalayer(amount=1)`

Moves the current render layer downward by the requested number of steps and returns the updated layer state.

#### `getschematicblocksonlayer(layer=None, axis=None, placement=None, block_id=None, limit=4096)`

Enumerates non-air schematic blocks on a placement layer.

Behavior:

- Uses the selected placement by default.
- Uses the current Litematica render layer by default.
- If Litematica is in `ALL` mode, you must pass `layer=` explicitly.
- If `block_id` is set, the result is filtered to that block identifier.
- If `limit` is set, enumeration stops when that many matches are found.

Important note:

This helper walks the placement box coordinate by coordinate and calls `getschematicblockat()` for each position. It is accurate, but it can be slow for large layers.

### Verifier Helpers

These helpers depend on the selected Litematica placement having verifier data available.

#### `getselectedschematicplacementhandle()`

Returns a reflected handle to the currently selected placement, or `None`.

#### `getselectedschematicverifierhandle()`

Returns a reflected handle to the selected placement verifier, or `None`.

#### `getschematicverifierstats()`

Returns aggregate verifier counts such as:

- `missing`
- `extra`
- `wrong_block`
- `wrong_state`
- `diff_block`
- `correct_state`
- `total_errors`
- `active`
- `finished`

#### `getschematicmismatchoverview(mismatch_type="ALL", limit=None)`

Returns mismatch buckets from the verifier overview.

Supported `mismatch_type` values:

- `ALL`
- `MISSING`
- `EXTRA`
- `WRONG_BLOCK`
- `WRONG_STATE`
- `DIFF_BLOCK`

Each entry contains:

- `type`
- `expected`
- `found`
- `count`

#### `getnearestschematicmismatch(mismatch_type="ALL")`

Returns the nearest mismatch position relative to the player and includes expected and found block-state data when available.

#### `getnearestmissingblock()`

Shortcut for `getnearestschematicmismatch("MISSING")`.

#### `getnearestwrongblock()`

Shortcut for `getnearestschematicmismatch("WRONG_BLOCK")`.

#### `getnearestwrongstateblock()`

Shortcut for `getnearestschematicmismatch("WRONG_STATE")`.

### Generic Litematica Reflection Bridge

These helpers are the escape hatch for advanced use. They let you access allowed Litematica and malilib classes directly without waiting for a new wrapper release.

#### Handle Model

When Java returns a reflected object instead of a primitive, enum, block position, collection, or map, the bridge serializes it as a handle object like this:

```python
{
        "__handle__": 12,
        "type": "fi.dy.masa.litematica.schematic.placement.SchematicPlacement",
        "string": "..."
}
```

That handle can then be passed back into other reflection helpers.

#### `litematicahandle(handle)`

Wraps an integer handle id or handle dict into the shape expected by reflection arguments.

Use this when one reflected method expects another reflected object as an argument.

#### `litematicainspect(class_name=None, handle=None, include_inherited=True)`

Inspects a class or reflected object and returns method and field metadata.

You must provide either `class_name` or `handle`.

#### `litematicacallstatic(class_name, method, *args)`

Calls a static method on an allowed class.

#### `litematicacall(handle, method, *args)`

Calls an instance method on a reflected handle.

#### `litematicagetstaticfield(class_name, field)`

Reads a static field from an allowed class.

#### `litematicagetfield(handle, field)`

Reads a field from a reflected handle.

#### `litematicarelease(handle)`

Releases a single reflected handle allocated by the mod.

#### `litematicaclearhandles()`

Releases every reflected handle currently tracked by the bridge.

Example:

```python
import minescript

placement = minescript.getselectedschematicplacementhandle()
print(minescript.litematicainspect(handle=placement))
print(minescript.litematicacall(placement, "getName"))
minescript.litematicarelease(placement)
```

### Events And Long-Running Scripts

MinePyScript can run background event polling in a daemon thread.

#### `on_chat(handler)`

Registers a handler for chat events.

#### `on_tick(handler)`

Registers a handler for tick events.

#### `on_join_world(handler)`

Registers a handler for world-join events.

Handlers receive the raw event dictionary returned by the bridge.

Example:

```python
import minescript

@minescript.on_chat
def handle_chat(event):
        print("CHAT:", event)

minescript.wait_forever()
```

#### `stop_events()`

Stops the background event polling thread.

#### `wait_forever(interval=0.1)`

Keeps the script alive so background handlers can continue running.

Use this for scripts that rely on event callbacks instead of immediate one-shot RPC calls.

## How The Event System Works

- The first call to `on_chat()`, `on_tick()`, or `on_join_world()` starts a background daemon thread.
- That thread repeatedly calls `pollevents` on the bridge.
- Returned events are dispatched to the registered Python handlers.
- Exceptions inside handlers are logged and do not stop the event thread.

## Return Values

Most helpers return plain Python values decoded from bridge JSON:

- `dict` for structured objects
- `list` for collections
- `str`, `int`, `float`, `bool` for primitives
- `None` for JSON null or absent results

Some common patterns:

- Position-like objects usually contain `x`, `y`, and `z`.
- Block-like objects often contain `block_id`, `block_state`, and `properties`.
- Reflection helpers may return handle dictionaries when the underlying Java value cannot be flattened into JSON directly.

## Errors And Compatibility Notes

The package raises `RuntimeError` when the bridge request fails or the mod reports an error.

Common causes:

- Minecraft is not running.
- The Minescript mod is not installed or not listening on the expected port.
- The helper expects a newer bridge method than the installed mod exposes.
- A Litematica helper was called without a selected placement or without verifier data.

Compatibility behavior built into the package:

- Menu closing automatically falls back across multiple strategies.
- Litematica placement and schematic helpers resolve method names dynamically when possible.
- Old misspelled helper names remain available for compatibility.

## Practical Examples

### Move To A Target And Interact

```python
import minescript

minescript.movetoposition(120, 64, -45, tolerance=1.0, sprint=True)
minescript.lookat(121, 64, -45)
minescript.rightclick()
```

### Scan Nearby Blocks

```python
import minescript

blocks = minescript.getblocksinrange(block_id="minecraft:chest", radius=12, limit=16)
for block in blocks:
        print(block)
```

### Work With The Current Schematic Layer

```python
import minescript

print(minescript.getlitematicarenderlayer())
for block in minescript.getschematicblocksonlayer(limit=20):
        print(block)
```

### Find The Nearest Missing Schematic Block

```python
import minescript

missing = minescript.getnearestmissingblock()
print(missing)
```

### Inspect Litematica Classes Dynamically

```python
import minescript

print(minescript.litematicainspect(class_name="fi.dy.masa.litematica.data.DataManager"))
print(minescript.litematicacallstatic("fi.dy.masa.litematica.data.DataManager", "getRenderLayerRange"))
```

## Summary

Use MinePyScript when you want Python to drive a live Minecraft client through the Minescript mod. Start with the high-level helpers when they exist. Drop down to `methods()`, `call()`, and the Litematica reflection bridge when you need features the wrapper has not specialized yet.
