File size: 6,701 Bytes
0db945a 16d7054 0db945a 16d7054 0db945a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | """The world map is a contract with the rest of the runtime.
Voyager's placement, navigation and prompts are all pinned to a walkable surface
at Y=64, and generator settings are only read when a world is first created, so
a careless layer edit silently moves the ground under the bot or leaves the old
map in place. These tests lock both properties down.
"""
from __future__ import annotations
import json
import tempfile
from pathlib import Path
import minecraft_stack as mc
# Every ore a farming bot is expected to be able to reach on foot.
FARMABLE_ORES = (
"coal_ore",
"copper_ore",
"iron_ore",
"gold_ore",
"redstone_ore",
"diamond_ore",
"lapis_ore",
"emerald_ore",
)
def _column() -> list[tuple[str, int, int]]:
"""Return (block, lowest_y, highest_y) from the bottom of the world up."""
y = mc.WORLD_FLOOR_Y
column = []
for block, height in mc.WORLD_FLAT_LAYERS:
column.append((block, y, y + height - 1))
y += height
return column
def test_layer_stack_reaches_the_declared_surface():
column = _column()
assert sum(height for _, height in mc.WORLD_FLAT_LAYERS) == (
mc.WORLD_SURFACE_Y - mc.WORLD_FLOOR_Y
)
# The top layer is the walkable surface and its first air block is Y=64.
assert column[-1][0] == "minecraft:grass_block"
assert column[-1][2] == mc.WORLD_SURFACE_Y - 1
assert column[-1][1] == column[-1][2]
def test_surface_has_farmable_soil_over_the_ores():
column = _column()
by_block = {}
for block, low, high in column:
by_block.setdefault(block, []).append((low, high))
# Soil and grass on top so crops and building have something to work with.
assert "minecraft:dirt" in by_block
assert by_block["minecraft:dirt"][-1][1] == mc.WORLD_SURFACE_Y - 2
# A resource band close enough to the surface to mine without a long shaft.
for ore in FARMABLE_ORES:
assert f"minecraft:{ore}" in by_block, f"{ore} missing from the map"
shallow = [span for span in by_block[f"minecraft:{ore}"] if span[0] > 0]
assert shallow, f"{ore} is only in the deepslate band"
assert min(low for low, _ in shallow) >= mc.WORLD_SURFACE_Y - 32, (
f"{ore} sits too deep to mine from the surface"
)
# The deepslate band duplicates the table at the bottom of the column.
for ore in FARMABLE_ORES:
assert f"minecraft:deepslate_{ore}" in by_block, f"deepslate {ore} missing"
assert "minecraft:bedrock" in by_block
def test_every_layer_block_exists_in_minecraft_1_19():
# An unknown block name makes the server refuse to generate the world, which
# would take the whole Space down on boot. The registry shipped in the repo
# is the same minecraft-data dataset the runtime ships to Mineflayer.
registry = json.loads(
(Path(__file__).resolve().parents[1] / "minecraft_ids_1_19.json").read_text(
encoding="utf-8"
)
)
known = {
entry if isinstance(entry, str) else entry.get("name")
for entry in registry["diggable_blocks"]
}
# bedrock is the one layer that is never diggable, so it is absent by design.
known.add("bedrock")
unknown = [
block for block, _ in mc.WORLD_FLAT_LAYERS if block.split(":", 1)[1] not in known
]
assert unknown == [], f"blocks absent from Minecraft 1.19: {unknown}"
def test_generator_settings_match_the_declared_layers():
settings = json.loads(mc.FLAT_GENERATOR_SETTINGS)
assert settings["layers"] == [
{"block": block, "height": height} for block, height in mc.WORLD_FLAT_LAYERS
]
# Lava lakes stay off: they are the only thing `lakes` controls, and they
# would put lava on the surface the bot builds and pathfinds on.
# (minecraft.wiki/w/Superflat/Settings)
assert settings["lakes"] is False
# `features` was previously asserted False on the theory that vegetation
# would sit on the walkable surface. It does not: biome features such as
# trees and grass occupy blocks *above* WORLD_SURFACE_Y, which is unchanged.
# Leaving it off left a plains superflat with no wood at all, so the official
# curriculum kept proposing crafting tasks the bot could not satisfy.
assert settings["features"] is True
# Omitted on purpose: the documented default is "all the structure sets",
# while an empty list disables every structure. This used to pass [].
assert "structure_overrides" not in settings
def test_map_change_uses_a_new_world_directory():
# Generator settings are only applied when level.dat is created, so the map
# can only be replaced by pointing at a directory that has no world yet.
assert mc.WORLD_DIR != mc.PREVIOUS_WORLD_DIR
assert mc.WORLD_DIR.parent == mc.PERSIST_ROOT
def test_carrying_player_saves_keeps_the_human_session_and_resets_the_bot():
with tempfile.TemporaryDirectory() as tmp:
previous = Path(tmp) / "old-world"
current = Path(tmp) / "new-world"
human = f"{mc._offline_player_uuid(mc.ADMIN_USERNAME)}.dat"
bot = f"{mc._offline_player_uuid(mc.BOT_USERNAME)}.dat"
(previous / "playerdata").mkdir(parents=True)
(previous / "playerdata" / human).write_bytes(b"human-save")
(previous / "playerdata" / bot).write_bytes(b"bot-save")
(previous / "playerdata" / "README.txt").write_text("not a save", encoding="utf-8")
current.mkdir(parents=True)
mc._carry_player_saves(previous, current)
carried = sorted(p.name for p in (current / "playerdata").iterdir())
assert carried == [human]
assert (current / "playerdata" / human).read_bytes() == b"human-save"
# A full bot inventory is what pins the official CurriculumAgent to its
# hardcoded full-inventory branch, so the bot must start clean.
assert not (current / "playerdata" / bot).exists()
# Running again on an already-populated world must not resurrect the bot
# save, and must be safe when there is no previous world at all.
mc._carry_player_saves(previous, current)
mc._carry_player_saves(Path(tmp) / "missing", current)
assert sorted(p.name for p in (current / "playerdata").iterdir()) == [human]
if __name__ == "__main__":
test_layer_stack_reaches_the_declared_surface()
test_surface_has_farmable_soil_over_the_ores()
test_every_layer_block_exists_in_minecraft_1_19()
test_generator_settings_match_the_declared_layers()
test_map_change_uses_a_new_world_directory()
test_carrying_player_saves_keeps_the_human_session_and_resets_the_bot()
print("PASS resource map, surface Y=64 and player save carry-over")
|