# 无窗口游玩验证记录 日期:2026-10-18(Asia/Shanghai) 环境:Windows 11 · DSH Desktop 0.2.1-rc.2 · Java 25(`java-runtime-epsilon`)· Minecraft Java 26.1.2 ## 结论 `mc_headless` + `mc_bot` 在**没有任何 Minecraft 客户端窗口**的情况下,完成了启动服务端、复制现有世界、机器人加入、移动、转视角、挖掘、聊天、执行命令、寻路、优雅退出。 ## 1. 启动(世界来源:现有单人存档) 调用: ```json { "action": "start", "version": "26.1.2", "worldSource": "E:\\Minecraft\\.minecraft\\versions\\26.1.2\\saves\\新的世界 (1)", "memoryMb": 2048 } ``` 结果(节选): ```json { "ok": true, "mode": "local", "windowless": true, "botProtocolVersion": "26.1", "server": { "version": "26.1.2", "port": 25599, "java": "C:\\Users\\Gary\\AppData\\Roaming\\.minecraft\\runtime\\java-runtime-epsilon\\bin\\java.exe", "javaMajor": 25, "worldCopied": true, "worldSource": "E:\\Minecraft\\.minecraft\\versions\\26.1.2\\saves\\新的世界 (1)", "ready": true, "startupMs": 14263 }, "bot": { "connected": true, "username": "DSHBot", "health": 20, "food": 20, "position": { "x": -8.5, "y": 70, "z": 9.5 }, "dimension": "overworld", "gameMode": "survival" } } ``` 服务端日志: ```text Starting minecraft server version 26.1.2 Preparing level "headless-world" Done (0.494s)! For help, type "help" DSHBot[/127.0.0.1:64112] logged in with entity id 20 at (-8.5, 70.0, 9.5) DSHBot joined the game ``` 关键点: - 只复制存档,原存档 `E:\...\saves\新的世界 (1)` 未被修改; - 服务端只监听 `127.0.0.1`,`online-mode=false`; - `worldCopied=true`,服务端内部世界名为存档中的 `新的世界`。 ## 2. 命令 ```json { "action": "command", "text": "/time set day" } ``` 机器人聊天记录: ```text Set minecraft:overworld to time marker minecraft:day ``` ## 3. 移动 ```json { "action": "move", "direction": "forward", "durationMs": 1500 } ``` 结果: ```json { "from": { "x": -8.5, "y": 70, "z": 9.5 }, "to": { "x": -8.5, "y": 67.31, "z": 16.35 }, "distance": 7.36 } ``` ## 4. 视角 / 挖掘 / 聊天 ```json { "action": "look", "dx": 90, "dy": 15 } { "action": "dig" } { "action": "chat", "text": "hello from windowless minecraft" } ``` 结果: ```json { "dig": { "block": "grass_block", "position": { "x": -9, "y": 62, "z": 16 } }, "chatLog": [ { "text": "Set minecraft:overworld to time marker minecraft:day" }, { "text": " hello from windowless minecraft" } ] } ``` 服务器日志: ```text [DSHBot: Set minecraft:overworld to time marker minecraft:day] [Not Secure] hello from windowless minecraft ``` ## 5. 寻路 ```json { "action": "goto", "x": -4, "y": 63, "z": 17, "range": 1, "timeoutMs": 30000 } ``` 结果: ```json { "ok": true, "position": { "x": -4.66, "y": 63, "z": 17.5 }, "target": { "x": -4, "y": 63, "z": 17 }, "range": 1 } ``` ## 6. 停止 ```json { "action": "stop" } ``` 结果: ```json { "ok": true, "bot": { "disconnected": true }, "server": { "stopped": true, "graceful": true } } ``` 停止后 `java.exe` 进程消失,端口释放。 ## 7. connect 模式 另起一个 26.1.2 测试服务端(25597)后: ```json { "action": "start", "mode": "connect", "host": "127.0.0.1", "port": 25597, "version": "26.1.2" } ``` 机器人成功连接,出生 `(-5.5, 71, -0.5)`;`mc_headless stop` 只断开机器人,不停止外部服务端(`server.stopped=false`)。 ## 8. F3 信息(mc_debug) ```json { "f3Text": "Minecraft 26.1.2 (protocol 775) windowless\noverworld dark_forest\nXYZ: -4.66 / 63 / 17.499\nBlock: -5 63 17\nChunk: -1 1 [11 1] in -1 0\nFacing: south (Towards positive Z) (yaw 5.7 / pitch -73.8)\nLight: 0 (sky 15)\nTime: 7228 (13:13) day 0\nHealth: 20 Food: 19 XP: 0\nServer: 127.0.0.1:25599 ping 0ms players 1\nEntities: 178 loaded chunks: 136\nFPS/memory/render distance: n/a (headless protocol bot)", "version": { "minecraft": "26.1.2", "protocolVersion": 775, "protocolBot": "26.1", "serverBrand": "vanilla" }, "biome": "dark_forest", "light": { "block": 0, "sky": 15 }, "facing": { "name": "south", "axis": "positive Z", "yawDeg": 5.7 }, "entities": { "total": 178 }, "unavailable": ["fps (no renderer in windowless mode)", "render distance / chunk render stats (no renderer)", "JVM memory display (not exposed by the protocol)"] } ``` 还验证了 `look { yaw: 180, pitch: 30 }` 返回 `Facing: north (Towards negative Z)`,说明工具参数使用 F3/vanilla 朝向约定。 ## 9. 周围方块状态(mc_blocks) `looking`(视线射线): ```json { "mode": "looking", "maxDistance": 10, "distance": 3.21, "face": 3, "block": { "name": "dark_oak_log", "displayName": "Dark Oak Log", "stateId": 155, "biome": "dark_forest", "light": 0, "skyLight": 15, "hardness": 2, "diggable": true, "material": "mineable/axe", "properties": { "axis": "y" } } } ``` `at`(脚下方块): ```json { "mode": "at", "position": { "x": -5, "y": 62, "z": 17 }, "loaded": true, "block": { "name": "grass_block", "stateId": 9, "biome": "dark_forest", "properties": { "snowy": false }, "hardness": 0.6, "material": "mineable/shovel", "boundingBox": "block" } } ``` `scan`(半径 3、垂直 2,非空气方块,limit 15):扫描 245 个位置,匹配 140 个,计数: ```json { "dirt": 53, "grass_block": 45, "leaf_litter": 30, "dark_oak_log": 12 } ``` `find`(`name: "dirt"`,半径 10,count 3):返回 3 个最近泥土方块(距离 2.09 / 2.46 / 2.52),每个都带完整方块状态。 ## 10. 放置 / 攻击 / 丢弃 - `place`(使用手持泥土,参考坐标 `(1,-1,0)` 的草地,face 上表面)→ 成功;再用 `mc_blocks at (-4,63,17)` 确认该位置变为 `dirt`; - `/summon minecraft:pig ~ ~ ~2` 后 `attack radius 6` → 命中 `pig`,距离 2.69; - `drop { item: "dirt", count: 1 }` → 成功。 ## 限制 - 只使用 vanilla 服务端;Fabric/Forge 模组不加载,模组世界复制后可能缺内容。 - 无画面:状态只能通过 JSON(坐标、血量、物品栏、聊天)观察,没有截图。 - F3 的 FPS/渲染距离/JVM 内存等渲染器字段不存在;`mc_debug` 返回其余可用字段并标注 unavailable。 - 方块数据来自已加载区块;未加载区块返回 `unloaded` 计数或 `loaded: false`。 - 首次启动下载约 60 MB 服务端 jar;需要网络。 - 本机测试出现过 `Can't keep up!` 警告(CPU 竞争),操作仍成功。