Skip to content

Commit 482d032

Browse files
Finish absolute build-plan execution and auto-fix flow
1 parent 03750b2 commit 482d032

File tree

4 files changed

+638
-104
lines changed

4 files changed

+638
-104
lines changed

README.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,12 @@ The build-plan tool accepts either:
392392
- a root object that is itself the build plan
393393
- or a wrapper object with top-level `build_plan`
394394

395+
Important top-level planning fields:
396+
- `coordMode`: `player` or `absolute`
397+
- `origin`: in `player` mode this is a relative shift from the player; in `absolute` mode it is an explicit world origin
398+
- `offset`: optional extra relative shift after the base origin
399+
- `autoFix`: allows safe grounding fixes like small auto-lowers and limited support repair
400+
395401
Minimal example:
396402

397403
```json
@@ -418,20 +424,27 @@ Agents should not treat the build planner as a black box. The most important rul
418424

419425
- `minecraft_buildsite` returns terrain deltas relative to the player’s current block Y, not absolute world Y.
420426
- If `maxDy` is negative, the surrounding surface is below the player. A build with floor `y=0` will float unless the plan is lowered or the player moves.
427+
- `coordMode=absolute` is the right choice when the structure needs to stay locked to a specific world location instead of wherever the player happens to be standing.
428+
- If `coordMode=absolute` is used without `origin`, the planner falls back to the player’s block position and reports that fallback in `repairs`.
421429
- `clearPercent` is headroom above sampled surface columns, not proof that the terrain is flat.
422430
- The planner clamps relative X/Z into `[-32, 32]` and relative Y into `[-24, 24]`. If a plan is too large or too far away, the result includes repairs saying it was clamped into the safe build window.
423431
- `steps` should be used for phased builds like foundation -> shell -> roof -> details.
424432
- `clear` volumes remove space before building and use the same bounds formats as cuboids, but without a block id.
425433
- `rotate` accepts `0`, `90`, `180`, `270`, `cw`, and `ccw`, and the result reports the final normalized value in `appliedRotation`.
426434
- `phaseCount` reports how many direct-operation phases were compiled from `clear`, `cuboids`, `blocks`, and `steps`.
427-
- The planner can auto-add support pillars using `minecraft:stone_bricks`, but only up to 24 lowest columns. Beyond that, the agent should add an explicit foundation or split the build into phases.
435+
- The planner now returns structured `issues` identifying floating cuboids or block targets, their `gapBelow`, and a `suggestedY` to ground them correctly.
436+
- The planner only adds support pillars for real unsupported columns and caps auto-support at 24 columns.
437+
- If more than 80% of the lowest build columns are already within 2 blocks of solid ground and `autoFix=true`, the planner can auto-lower the whole build instead of spamming pillars.
438+
- `resolvedOrigin` in the result tells you the exact world origin that was actually used.
439+
- `autoFixAvailable` tells you whether the planner believes a safe grounding fix exists.
428440

429441
If an agent gets a support-pillar failure, the correct response is usually:
430442

431443
1. Re-read `minecraft_buildsite`
432-
2. Lower the build or move the player to the intended surface level
433-
3. Add a foundation phase in `steps`
434-
4. Retry with a grounded plan
444+
2. Inspect `issues` and `suggestedY`
445+
3. Lower the build or move the player to the intended surface level
446+
4. Add a foundation phase in `steps`
447+
5. Retry with a grounded plan
435448

436449
Do not keep retrying the same floating `y=0` structure and assume the JSON schema is wrong.
437450

@@ -445,9 +458,20 @@ For terrain-sensitive or unfamiliar builds, agents should use:
445458
- `repairs`
446459
- `appliedRotation`
447460
- `phaseCount`
461+
- `resolvedOrigin`
462+
- `issues`
448463
- `previewCommands`
449-
4. Revise the plan if needed
450-
5. Then call `minecraft_execute_build_plan`
464+
4. Save the returned `planId` if the preview looks good
465+
5. Revise the plan if needed
466+
6. Then call `minecraft_execute_build_plan`
467+
468+
Best practice is:
469+
470+
```json
471+
{ "executePlanId": "plan-..." }
472+
```
473+
474+
That makes execute run the exact cached preview instead of recompiling a fresh variant.
451475

452476
`minecraft_preview_build_plan` uses the same planner and command validation as the real build path, but it does not mutate the world and does not create an undo batch.
453477

run-mcp-sidecar-node.js

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,20 @@ const TOOLS = {
302302
inputSchema: objectSchema(),
303303
},
304304
minecraft_preview_build_plan: {
305-
description: "Compile and validate a structured voxel build plan without executing it, returning repairs, preview commands, rotation, and phase data.",
305+
description: "Compile and validate a structured voxel build plan without executing it, returning previewCommands, planId, resolvedOrigin, issues, repairs, rotation, and phase data.",
306306
method: "POST",
307307
path: "/v1/actions/preview_build_plan",
308308
inputSchema: {
309309
type: "object",
310-
description: "Either provide build_plan explicitly or pass the build_plan object as the root arguments object.",
310+
description: "Either provide build_plan explicitly or pass the build_plan object as the root arguments object. Supports coordMode=player|absolute, explicit origin, offset, autoFix, clear, cuboids, blocks, and steps.",
311311
additionalProperties: true,
312-
properties: {},
312+
properties: {
313+
build_plan: { type: "object", additionalProperties: true },
314+
coordMode: { type: "string", enum: ["player", "absolute"] },
315+
origin: { type: "object", additionalProperties: true },
316+
offset: { type: "object", additionalProperties: true },
317+
autoFix: { type: "boolean" },
318+
},
313319
},
314320
},
315321
minecraft_highlight: {
@@ -319,14 +325,22 @@ const TOOLS = {
319325
inputSchema: highlightSchema(),
320326
},
321327
minecraft_execute_build_plan: {
322-
description: "Compile and execute a structured voxel build plan using the mod's planner, with validation, rotation, support repair, and undo-aware batching.",
328+
description: "Compile and execute a structured voxel build plan using the mod's planner, with validation, absolute/player origins, support diagnostics, preview parity via planId, and undo-aware batching.",
323329
method: "POST",
324330
path: "/v1/actions/execute_build_plan",
325331
inputSchema: {
326332
type: "object",
327-
description: "Either provide build_plan explicitly or pass the build_plan object as the root arguments object.",
333+
description: "Either provide build_plan explicitly, pass the build_plan object as the root arguments object, or send executePlanId/planId from minecraft_preview_build_plan to execute the exact cached preview unchanged.",
328334
additionalProperties: true,
329-
properties: {},
335+
properties: {
336+
build_plan: { type: "object", additionalProperties: true },
337+
executePlanId: { type: "string" },
338+
planId: { type: "string" },
339+
coordMode: { type: "string", enum: ["player", "absolute"] },
340+
origin: { type: "object", additionalProperties: true },
341+
offset: { type: "object", additionalProperties: true },
342+
autoFix: { type: "boolean" },
343+
},
330344
},
331345
},
332346
minecraft_execute_commands: {
@@ -729,6 +743,10 @@ function buildResponseFieldsForTool(name) {
729743
{ name: "summary", description: "Planner summary of the build." },
730744
{ name: "appliedRotation", description: "Final normalized rotation." },
731745
{ name: "phaseCount", description: "Number of compiled direct-operation phases." },
746+
{ name: "resolvedOrigin", description: "Exact world origin the planner actually used." },
747+
{ name: "issues", description: "Structured floating/grounding issues with cuboid names, gaps, and suggestedY." },
748+
{ name: "autoFixAvailable", description: "Whether the planner believes a safe grounding fix exists." },
749+
{ name: "planId", description: "Cached preview id that execute can reuse unchanged via executePlanId." },
732750
{ name: "previewCommands", description: "The exact validated Minecraft commands that would run." },
733751
];
734752
case "minecraft_execute_build_plan":
@@ -742,6 +760,10 @@ function buildResponseFieldsForTool(name) {
742760
{ name: "summary", description: "Planner summary of what was built or attempted." },
743761
{ name: "appliedRotation", description: "Final normalized rotation used: 0, 90, 180, or 270." },
744762
{ name: "phaseCount", description: "How many direct-operation phases the planner compiled." },
763+
{ name: "resolvedOrigin", description: "Exact world origin the planner actually used." },
764+
{ name: "issues", description: "Structured floating/grounding issues for failed or revised builds." },
765+
{ name: "autoFixAvailable", description: "Whether the planner believed a safe grounding fix was available." },
766+
{ name: "planId", description: "Preview cache id if the build was executed from a cached preview." },
745767
];
746768
default:
747769
return [];
@@ -818,7 +840,10 @@ function buildBuildPlanGuide() {
818840
"## Common Top-Level Fields",
819841
"",
820842
"- `summary`: short description of the structure",
821-
"- `origin` or `offset`: optional relative origin shift",
843+
"- `coordMode`: `player` or `absolute`",
844+
"- `origin`: explicit origin. In `player` mode it is a relative shift from the player. In `absolute` mode it is a real world origin.",
845+
"- `offset`: optional extra relative shift applied after the base origin",
846+
"- `autoFix`: whether the planner may auto-lower near-ground builds and add limited support repair",
822847
"- `rotate`: `0`, `90`, `180`, `270`, `cw`, or `ccw`",
823848
"- `palette`: aliases for block ids, useful for custom mod blocks",
824849
"- `clear`: volumes to clear before building",
@@ -828,11 +853,13 @@ function buildBuildPlanGuide() {
828853
"",
829854
"## Coordinate Rules",
830855
"",
831-
"- Coordinates are relative to the active player unless you intentionally offset them.",
856+
"- `coordMode=player` means the plan is relative to the active player.",
857+
"- `coordMode=absolute` means `origin` is an explicit world coordinate and cuboid/block coordinates are relative to that absolute origin.",
858+
"- If `coordMode=absolute` is used without `origin`, the planner falls back to the player's current block position and reports that fallback in `repairs`.",
832859
"- Positive `x` is east, positive `y` is up, positive `z` is south.",
833860
"- Keep small test structures close to the origin, for example between `-8` and `8` on x/z.",
834861
"- The planner clamps X/Z into `[-32, 32]` and Y into `[-24, 24]`. If you exceed that window, the plan is repaired and reported as clamped.",
835-
"- `origin`/`offset` still remain relative. They do not switch the planner into unrestricted absolute world coordinates.",
862+
"- Absolute `origin` is not clamped into the player's safe window. Relative cuboid/block coordinates still are.",
836863
"",
837864
"## Aligning The Build With Real Terrain",
838865
"",
@@ -841,6 +868,7 @@ function buildBuildPlanGuide() {
841868
"- In that situation, a plan with its floor at relative `y=0` starts nine blocks above nearby surface and will likely trigger support repairs or failure.",
842869
"- Best practice: move the player to the intended build level or lower the foundation/floor phase to match the surface you actually want to build on.",
843870
"- If `clearPercent` is low, do not brute-force retries. Either choose another spot, clear space explicitly, or use a phased plan.",
871+
"- If you want a structure at a stable world location, prefer `coordMode=absolute` with an explicit `origin` rather than relying on wherever the player happens to be standing.",
844872
"",
845873
"## Accepted Geometry Forms",
846874
"",
@@ -988,11 +1016,24 @@ function buildBuildPlanGuide() {
9881016
"",
9891017
"## Foundations And Support Pillars",
9901018
"",
991-
"- After compiling placements, the planner checks whether the lowest occupied columns have solid terrain below them.",
992-
"- If the build is nearly grounded, it can auto-add support pillars using `minecraft:stone_bricks`.",
993-
"- Auto-support is capped at 24 columns. If more would be needed, the planner rejects the build and tells the agent to add an explicit foundation or split the build into phases.",
1019+
"- After compiling placements, the planner checks the lowest support targets, not just the raw command list.",
1020+
"- It returns structured `issues` identifying which cuboids or block targets are floating, their `gapBelow`, and a `suggestedY` for grounding.",
1021+
"- Only columns with real air/fluid gaps below them are considered for auto-support pillars.",
1022+
"- If more than 80% of the lowest-layer columns are within 2 blocks of valid ground and `autoFix=true`, the planner can auto-lower the whole build instead of spamming pillars.",
1023+
"- Auto-support pillars use `minecraft:stone_bricks` and are capped at 24 columns.",
9941024
"- If there is no valid solid ground below some lowest columns at all, the planner rejects the build and tells the agent to lower the build or add a foundation.",
995-
"- This is why repeated retries with the same floating `y=0` plan are the wrong response. Fix the base Y or add a foundation phase instead.",
1025+
"- Repeated retries with the same floating `y=0` plan are the wrong response. Fix the base Y, add a foundation phase, or use preview issues plus `suggestedY` to revise the plan.",
1026+
"",
1027+
"Example issue payload:",
1028+
"",
1029+
"```json",
1030+
"{",
1031+
" \"issues\": [",
1032+
" {\"cuboid\":\"floor\",\"issue\":\"floating\",\"gapBelow\":14,\"suggestedY\":65}",
1033+
" ],",
1034+
" \"autoFixAvailable\": true",
1035+
"}",
1036+
"```",
9961037
"",
9971038
"## Why Agents Should Prefer Build Plans",
9981039
"",
@@ -1008,9 +1049,12 @@ function buildBuildPlanGuide() {
10081049
"",
10091050
"1. `minecraft_buildsite`",
10101051
"2. `minecraft_preview_build_plan`",
1011-
"3. Inspect `repairs`, `appliedRotation`, `phaseCount`, and `previewCommands`",
1012-
"4. Revise if needed",
1013-
"5. `minecraft_execute_build_plan` only after the preview looks sane",
1052+
"3. Inspect `repairs`, `appliedRotation`, `phaseCount`, `resolvedOrigin`, `issues`, and `previewCommands`",
1053+
"4. Keep the returned `planId` if the preview is good",
1054+
"5. Revise if needed",
1055+
"6. Execute either the same payload again or, preferably, `minecraft_execute_build_plan {\"executePlanId\":\"...\"}` so the exact cached preview runs unchanged",
1056+
"",
1057+
"The `planId` path is the strongest option when preview parity matters because preview and execute then use the same compiled command list.",
10141058
"",
10151059
"## Failure Prevention",
10161060
"",
@@ -1032,6 +1076,10 @@ function buildBuildPlanGuide() {
10321076
"- `summary`: human-readable summary of the compiled build",
10331077
"- `appliedRotation`: final normalized rotation",
10341078
"- `phaseCount`: number of compiled direct-operation phases",
1079+
"- `resolvedOrigin`: the world origin actually used after coordMode/origin fallback resolution",
1080+
"- `issues`: structured floating/grounding issues for failing or revised builds",
1081+
"- `autoFixAvailable`: whether the planner believes a safe grounding fix is available",
1082+
"- `planId`: returned by preview so execute can run the exact cached plan",
10351083
"",
10361084
].join("\n");
10371085
}

0 commit comments

Comments
 (0)