GymCraft Python RPC Client
Install dependencies:
cd src\main\python
uv sync
Generate Python gRPC stubs from the mod proto files, then build the wheel:
# from repository root
.\gradlew generatePythonStubs
.\gradlew packagePython
Or build directly with uv:
cd src\main\python
uv build
Create an environment in-game with the env tool, then connect by entity UUID:
from gymcraft import GymCraftEnv
from gymcraft.gym.action.components import noop_pb2
env = GymCraftEnv("entity-uuid-here")
obs, reset_info = env.reset(options={
"disable_vanilla_ai": True,
"allow_multiple_actions": True,
}) # Disable vanilla AI only while waiting between actions; defaults to False.
self_state = obs["gymcraft:self"]
obs, reward, terminated, truncated, step_info = env.step({
"timeout_seconds": 0.0, # seconds; <= 0 means no limit
"actions": [
{"component_id": "gymcraft:noop", "payload": noop_pb2.ProtoNoop()},
],
})
env.close()
reset() returns (observation, info) and step() returns (observation, reward, terminated, truncated, info) (Gymnasium-style). The observation is the unpacked Observation dict: a header plus component keys that are full registration ids such as gymcraft:self, gymcraft:nearby_blocks, gymcraft:menu. A step receives an ordered ActionBatch; each action has exactly one component_id and protobuf payload, and the server executes the list serially under one shared timeout_seconds. make_action() packs one action into ProtoMcAction, while unpack_observation() converts a raw ProtoMcObservation back to an Observation.
allow_multiple_actions 默认为 True。在 reset options 中设为 False 后,每个 step 最多接受一个 action;多 action 批次会整体失败且不产生动作副作用,空批次 noop 仍可使用。
gymcraft:update_interesting_blocks 可通过 add_block_ids / remove_block_ids 批量维护当前 Agent 关注的方块类型;gymcraft:interesting_blocks 返回附近匹配类型的可见 ProtoBlockView。
Typecheck the Python client:
cd src\main\python
uv run mypy src debug demos tests
GitHub Actions runs stub generation, mypy, packaging, and uploads the built distributions as the gymcraft-python-dist artifact.
LLM Agent 工具包
gymcraft.llm 将 LLM 相关能力拆成可独立复用的组件:
ObservationTextFormatter:将 protobuf 观测转换为紧凑、稳定的行式文本;ActionDslParser/encode_action_batch:解析模型回复中的命令 DSL,并编码为现有Action;ConversationHistory/ContextAssembler:组装通用 Chat Completions 消息;LLMGymCraftEnv:只负责串联上述组件与底层GymCraftEnv,所有组件都可替换或单独使用。
内置 system prompt、命令说明和动作纠错反馈均使用英文。观测只渲染决策所需的原生字段,不生成相对坐标等派生状态;附近实体、普通方块和感兴趣方块默认各最多 10 条。action-result 不包含服务端 details。
ConversationHistory 按 history_turns 分批保留完整历史;当前批次满载后,下一轮会折叠整批历史并作为新批次的第一轮重新积累,不再逐轮滚动淘汰最旧上下文。
最小 wrapper 示例:
from gymcraft import GymCraftEnv
from gymcraft.llm import LLMGymCraftEnv
base_env = GymCraftEnv("entity-uuid-here")
env = LLMGymCraftEnv(base_env, task="走到最近的箱子旁并打开它。")
context, info = env.reset(options={"disable_vanilla_ai": True})
# context["messages"] 可直接交给任意 Chat Completions 兼容 API。
model_text = """我先靠近箱子。
```gymcraft-action
/timeout 10
/move_to 12 64 -3 1
```
"""
context, reward, terminated, truncated, info = env.step(model_text)
env.close()
动作块位于回复末尾,每个非空行是一条 Minecraft 风格命令。一个动作块可以包含多个动作,服务端严格按文本行顺序串行执行,并允许重复同一组件。多条 move_menu_item 会保留为一个组件原生批量负载。调用 ActionDslParser.command_reference() 可以取得当前环境支持的完整命令表。
LLM 可用一条原子命令同时增删兴趣类型,例如 /update_interesting_blocks add minecraft:diamond_ore mod:target_block remove minecraft:stone。匹配结果会在后续观测的 interesting_blocks 段中按距离排序;其文本裁剪上限由 ObservationFormatConfig.max_interesting_blocks 控制。
连接已创建的 simple_mob 环境进行真实 DSL/gRPC 调试:
uv run python debug/interesting_blocks_debug.py <entity_uuid> --add minecraft:diamond_ore
格式错误不会推进游戏状态。wrapper 会把错误和模型原文加入上下文,默认允许两次原地纠正,连续第三次非法输出会截断当前 rollout。服务端返回的 reward、terminated 和 truncated 不会被 Python 任务逻辑改写。
Chat Completions 闭环 Demo
Chat Completions 客户端是可选依赖:
uv sync --extra openai
运行 demo;base_url、API key 和模型均可替换为任意兼容服务提供的值:
$env:LLM_BASE_URL = "https://api.openai.com/v1"
$env:LLM_API_KEY = "your-api-key"
$env:LLM_MODEL = "your-model-id"
uv run --extra openai demos/llm_chat_completions_demo.py `
<entity_uuid> `
--task "找到最近的箱子并查看其中的物品"
demo 使用通用的 client.chat.completions.create(model=..., messages=...) 接口,不启用 Responses API、厂商工具调用或服务端会话存储。
连接 gymcraft:iron_mining 环境可运行完整生存工具链 demo:
uv run --extra openai demos/iron_mining_llm_demo.py `
<entity_uuid> `
--max-steps 64 `
--trace traces/iron-mining.jsonl
该 demo 内置从空手采集原木、使用 self 菜单 $2\times2$ 合成、放置工作台、制作石镐并拾取粗铁的任务提示。--task 可覆盖提示,--trace 可保存完整 JSONL 轨迹。
人工终端交互
uv run debug/llm_terminal.py <entity_uuid> --task "测试菜单和移动动作"
终端中可直接输入一条或多条 /command,空行提交;工具会自动补上 gymcraft-action 围栏。输入 :obs 查看最新观测、:context 查看实际消息历史、:quit 退出。
检查
uv run python -m unittest discover -s tests -v
uv run mypy src debug demos tests
Release files for gymcraft 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gymcraft-1.2.0.tar.gz | 54.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gymcraft-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 161.8 kB
Release files / gymcraft-1.2.0.tar.gz
| Download URL | gymcraft-1.2.0.tar.gz |
|---|---|
| Size | 54.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0cd612fd6f488ee2ff8fb1a3383e3fe5280cdc853cc4849090170dd4615c2292
|
|
BLAKE2b-256 checksum How to use checksums |
e367933b0ffe7df34de700ae9223ceed7156cfb4486aed65c7f1ae283d3bfbcd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / gymcraft-1.2.0-py3-none-any.whl
| Download URL | gymcraft-1.2.0-py3-none-any.whl |
|---|---|
| Size | 107.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
55fb5575eca231e888d5632f31fae81f459d8e26c0e301ad63a7b1daa0510085
|
|
BLAKE2b-256 checksum How to use checksums |
fc13a2bca1be89e808f57876f443c83dbcb6eff193db4f6effdbb0ca8a2f97be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|