mud/tests/test_tutorial_zones.py
Jared Miller 56c82700b0
Add tutorial zones (flower and treehouse)
Implements the new player funnel with two tutorial zones:
- Flower: 7x7 sealed zone with translucent petals, spawn at center
- Treehouse: 20x15 platform zone with rope ladder and branch exits

Both zones are bounded (non-toroidal) and include portals for progression.
2026-02-11 22:38:14 -05:00

125 lines
4 KiB
Python

"""Tests for tutorial zones (flower and treehouse)."""
import pathlib
from mudlib.zones import load_zone
def test_load_flower_zone():
"""Load the flower zone and verify basic properties."""
project_root = pathlib.Path(__file__).resolve().parents[1]
flower_path = project_root / "content" / "zones" / "flower.toml"
zone = load_zone(flower_path)
assert zone.name == "flower"
assert zone.width == 7
assert zone.height == 7
assert zone.toroidal is False
assert zone.spawn_x == 3
assert zone.spawn_y == 3
assert len(zone.terrain) == 7
def test_flower_zone_mostly_sealed():
"""Verify flower zone has mostly sealed borders with impassable petals."""
project_root = pathlib.Path(__file__).resolve().parents[1]
flower_path = project_root / "content" / "zones" / "flower.toml"
zone = load_zone(flower_path)
# Verify 'o' is impassable (petals)
assert "o" in zone.impassable
# Count impassable border tiles
border_tiles = []
# Top and bottom rows
for x in range(zone.width):
border_tiles.append((x, 0))
border_tiles.append((x, zone.height - 1))
# Left and right columns (excluding corners already counted)
for y in range(1, zone.height - 1):
border_tiles.append((0, y))
border_tiles.append((zone.width - 1, y))
impassable_border_count = sum(
1 for x, y in border_tiles if not zone.is_passable(x, y)
)
# Most of the border should be impassable (allow for 1-2 openings)
total_border = len(border_tiles)
assert impassable_border_count >= total_border - 2
def test_flower_has_portal_to_treehouse():
"""Verify flower zone has a portal targeting treehouse."""
project_root = pathlib.Path(__file__).resolve().parents[1]
flower_path = project_root / "content" / "zones" / "flower.toml"
zone = load_zone(flower_path)
# Find portals in zone contents
portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"]
assert len(portals) == 1
portal = portals[0]
assert portal.target_zone == "treehouse"
assert portal.target_x == 10
assert portal.target_y == 7
assert "petal" in portal.name.lower() or "opening" in portal.name.lower()
def test_load_treehouse_zone():
"""Load the treehouse zone and verify basic properties."""
project_root = pathlib.Path(__file__).resolve().parents[1]
treehouse_path = project_root / "content" / "zones" / "treehouse.toml"
zone = load_zone(treehouse_path)
assert zone.name == "treehouse"
assert zone.width == 20
assert zone.height == 15
assert zone.toroidal is False
assert zone.spawn_x == 10
assert zone.spawn_y == 7
assert len(zone.terrain) == 15
def test_treehouse_has_portal_to_overworld():
"""Verify treehouse has a portal to the overworld."""
project_root = pathlib.Path(__file__).resolve().parents[1]
treehouse_path = project_root / "content" / "zones" / "treehouse.toml"
zone = load_zone(treehouse_path)
# Find portals
portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"]
# Find the overworld portal
overworld_portals = [p for p in portals if p.target_zone == "overworld"]
assert len(overworld_portals) == 1
portal = overworld_portals[0]
assert portal.target_x == 500
assert portal.target_y == 500
assert "ladder" in portal.name.lower() or "mist" in portal.name.lower()
def test_treehouse_has_portal_to_hub():
"""Verify treehouse has a portal to the hub."""
project_root = pathlib.Path(__file__).resolve().parents[1]
treehouse_path = project_root / "content" / "zones" / "treehouse.toml"
zone = load_zone(treehouse_path)
# Find portals
portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"]
# Find the hub portal
hub_portals = [p for p in portals if p.target_zone == "hub"]
assert len(hub_portals) == 1
portal = hub_portals[0]
assert portal.target_x == 7
assert portal.target_y == 14
assert "branch" in portal.name.lower() or "platform" in portal.name.lower()