#minecraft #vanilla

minect

A library that allows a Rust program to connect to a running Minecraft instance without requiring any Minecraft mods

3 releases

0.1.2 Apr 2, 2023
0.1.1 Mar 27, 2023
0.1.0 Jan 29, 2023

#2 in #minecraft-vanilla

Download history 7/week @ 2023-02-06 11/week @ 2023-02-13 16/week @ 2023-02-20 2/week @ 2023-02-27 11/week @ 2023-03-06 6/week @ 2023-03-13 9/week @ 2023-03-20 51/week @ 2023-03-27 16/week @ 2023-04-03 16/week @ 2023-04-10 7/week @ 2023-04-17 8/week @ 2023-04-24 11/week @ 2023-05-01 14/week @ 2023-05-08 15/week @ 2023-05-15 17/week @ 2023-05-22

63 downloads per month
Used in 2 crates

GPL-3.0-or-later

125KB
2.5K SLoC

Minecraft: Java Edition 1.14.1 - 1.19.4 Minecraft: Bedrock Edition unsupported
crates.io

Minect

Minect (pronounced maɪnɛkt as in Minecraft connection) is a library that allows a Rust program to connect to a running Minecraft instance without requiring any Minecraft mods. The idea originated in the Java library Vanilla Injection.

Using Minect a Rust program can execute commands in Minecraft and listen for command output. This way a Rust program can control or be controlled by Minecraft.

The connection requires a building in Minecraft which continuously loads structure files that contain the commands generated by the Rust program. Listening for their output works by polling Minecraft's log file.

Example

let identifier = "MyProgram";
let world_dir = "C:/Users/Herobrine/AppData/Roaming/.minecraft/saves/New World";
let mut connection = MinecraftConnection::builder(identifier, world_dir).build();

println!("If you are connecting for the first time please execute /reload in Minecraft.");
connection.connect().await?;

let events = connection.add_listener();

connection.execute_commands([
  Command::new("scoreboard objectives add example dummy"),
  Command::new("scoreboard players set Herobrine example 42"),
  Command::new(query_scoreboard_command("Herobrine", "example")),
])?;

let output = events
  .filter_map(|event| event.output.parse::<QueryScoreboardOutput>().ok())
  .next()
  .await
  .expect("Minecraft connection was closed unexpectedly");

println!("{}'s score is {}", output.entity, output.score);

Install

In order to set up the building in Minecraft, Minect provides the function MinecraftConnection::connect. While blocked in this function, a player can execute /reload in Minecraft to start an interactive installer.

Configuration

By default connections operate at the maximum rate of 20 executions per second (1 execution per gametick). For slower computers this can be configured by increasing the score update_delay in the scoreboard minect_config. For example to update all connections once per second (once per 20 gameticks) execute the following command:

scoreboard players set update_delay minect_config 20

Connection Identifier

Minect supports operating multiple connection buildings in parallel, each with a unique identifier. A single connection building can be shared between any number of Rust programs, but it is limited to one execution every update_delay gameticks. For optimal performance every Rust program can use a different connection identifier.

Read the Log File

When executing commands that should log their output the following gamerules must be considered:

  1. logAdminCommands: This must be true for Minecraft to write the output of commands to the log file.
  2. commandBlockOutput: This must be true for command blocks and command block minecarts to broadcast the output of their commands.
  3. sendCommandFeedback: This should be set to false to prevent the output to also be written to the chat which would likely annoy players.

To make things easy, Minect provides the function enable_logging_command() to generate a command that sets these gamerules accordingly and reset_logging_command() to reset them to their previous values. By default these two commands are automatically executed before/after all commands passt to execute_commands. For full control, this can be disabled when building a MinecraftConnection.

Datapacks

The output of commands in a datapack (in mcfunction files) are never logged, even if the above mentioned gamerules are set correctly. To get around this Minect provides the function logged_command(). This function takes a command and generates a command that summons a command block minecart with the given command. This way the given command is executed delayed by the command block minecart, so it's outputs can be logged.

Please note that you still need to enable logging. For proper ordering this also has to happen delayed in a command block minecart:

let my_function = [
    logged_command(enable_logging_command()),
    logged_command(query_scoreboard_command("@p", "my_scoreboard")),
    logged_command(reset_logging_command()),
].join("\n");

// Generate datapack containing my_function ...

// Call my_function (could also be done in Minecraft)
connection.execute_commands(["function my_namespace:my_function"])?;

Remove Connection

To remove a connection building in Minecraft a player can execute function minect:disconnect to select a connection to remove.

Uninstall

To completely uninstall Minect in Minecraft a player can execute function minect:uninstall to start an interactive uninstaller.

Alternatively function minect:uninstall_completely will uninstall Minect unconditionally.

Uninstalling Minect in Minecraft will remove scoreboards, connections and disable the datapack. After doing so the following directories still need to be removed from the world directory manually:

  • datapacks/minect
  • generated/minect

Dependencies

~8–14MB
~303K SLoC