extends SceneTree const WorldServiceType = preload("res://scripts/world/world_service.gd") const DigestType = preload("res://scripts/core/simulation_digest.gd") var _checks := 0 var _failures := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: print("S1: World Service") _test_bounds_zones_and_footprints() _test_occupancy_validation_and_release() _test_walkability_excavation_and_revisions() _test_connected_support_validation() _test_snapshot_round_trip_and_atomic_restore() _test_snapshot_order_is_deterministic() if _failures == 0: print("PASS: %d checks" % _checks) else: push_error("FAIL: %d of %d checks failed" % [_failures, _checks]) quit(_failures) func _test_bounds_zones_and_footprints() -> void: var world = WorldServiceType.new() _expect(world.reset(_bounds(-2, 2, -2, 2)), "dictionary bounds are accepted") _expect(world.is_in_bounds(Vector3i(-2, -2, 0)), "FRONT minimum corner is in bounds") _expect(world.is_in_bounds(Vector3i(2, 2, 1)), "BACK maximum corner is in bounds") _expect(not world.is_in_bounds(Vector3i(0, 0, 2)), "unknown layer is out of bounds") _expect(not world.is_in_bounds(Vector3i(3, 0, 0)), "x outside bounds is rejected") _expect(world.get_zone(Vector3i(0, 1, 0)) == world.ZONE_ABOVE_GROUND, "positive y is above ground") _expect(world.get_zone(0) == world.ZONE_BOUNDARY, "zero y is boundary") _expect(world.get_zone(Vector2i(0, -1)) == world.ZONE_UNDERGROUND, "negative y is underground") var footprint := world.cells_for_footprint(Vector3i(-1, -1, 1), Vector2i(2, 2)) _expect( footprint == [ Vector3i(-1, -1, 1), Vector3i(0, -1, 1), Vector3i(-1, 0, 1), Vector3i(0, 0, 1), ], "rectangular footprint has stable row-major ordering" ) _expect(world.cells_for_footprint(Vector3i.ZERO, Vector2i.ZERO).is_empty(), "empty footprint is rejected") var before := world.get_bounds() _expect(not world.reset(Rect2i(0, 0, 0, 2)), "invalid reset is rejected") _expect(world.get_bounds() == before, "failed reset preserves the current world") func _test_occupancy_validation_and_release() -> void: var world = WorldServiceType.new() world.reset(_bounds(-3, 3, -2, 2)) var room_cells := world.cells_for_footprint(Vector3i(0, 0, 0), Vector2i(2, 1)) _expect(world.occupy(&"room-b", room_cells, &"facility_small"), "valid entity occupies its footprint") _expect(world.get_occupant(Vector3i(0, 0, 0)) == &"room-b", "cell points back to occupant") _expect(world.get_occupant_kind(Vector3i(1, 0, 0)) == &"facility_small", "occupant kind is retained") _expect(world.get_entity_cells(&"room-b") == room_cells, "entity points to canonical cells") var returned_cells := world.get_entity_cells(&"room-b") returned_cells.clear() _expect(world.get_entity_cells(&"room-b") == room_cells, "returned cell arrays cannot mutate world state") var overlap := world.validate_occupancy([Vector3i(1, 0, 0)], &"room-a") _expect(not overlap[&"ok"] and overlap[&"errors"].has(world.ERROR_OCCUPIED), "overlapping occupation reports OCCUPIED") var revision_before_failure: int = world.revision _expect(not world.occupy(&"room-a", [Vector3i(1, 0, 0)], &"facility"), "overlapping occupy is atomic") _expect(world.revision == revision_before_failure, "failed occupy does not change revision") _expect(not world.occupy(&"room-b", [Vector3i(2, 0, 0)], &"facility"), "same entity cannot occupy twice") var malformed := world.validate_occupancy([ Vector3i(0, 1, 0), Vector3i(0, 1, 0), Vector3i(0, 1, 1), Vector3i(9, 1, 0), Vector2i.ZERO, ]) _expect(malformed[&"errors"].has(world.ERROR_DUPLICATE_CELL), "duplicate cell is reported") _expect(malformed[&"errors"].has(world.ERROR_LAYER_MISMATCH), "layer crossing is reported") _expect(malformed[&"errors"].has(world.ERROR_OUT_OF_BOUNDS), "out-of-bounds cell is reported") _expect(malformed[&"errors"].has(world.ERROR_INVALID_CELL_TYPE), "non-Vector3i cell is reported") _expect(world.release(&"room-b"), "release succeeds for existing entity") _expect(world.get_occupant(Vector3i(0, 0, 0)).is_empty(), "release clears cell-side occupation") _expect(world.get_entity_cells(&"room-b").is_empty(), "release clears entity-side occupation") _expect(not world.release(&"room-b"), "double release is rejected") func _test_walkability_excavation_and_revisions() -> void: var world = WorldServiceType.new() world.reset(_bounds(-1, 1, -2, 2)) var path_cell := Vector3i(0, 1, 0) var cave_front := Vector3i(0, -1, 0) var cave_back := Vector3i(0, -1, 1) _expect(not world.is_walkable(path_cell), "walkability defaults to false") _expect(world.set_walkable(path_cell, true), "walkability can be enabled") _expect(world.is_walkable(path_cell), "enabled walkability is readable") _expect(world.dirty_revision == world.revision, "dirty revision exposes the current world revision") var walk_revision: int = world.revision _expect(world.set_walkable(path_cell, true), "same walkability is a successful no-op") _expect(world.revision == walk_revision, "walkability no-op does not dirty world") _expect(world.is_excavated(Vector3i(0, 0, 0)), "boundary is usable without excavation") _expect(not world.is_excavated(cave_front), "underground defaults to unexcavated") _expect(world.set_excavated(cave_front, true), "underground spatial cell can be excavated") _expect(world.is_excavated(cave_front) and world.is_excavated(cave_back), "excavation is shared by FRONT and BACK") _expect(world.excavation_revision == world.revision, "excavation tracks its dirty revision") _expect(world.get_dirty_cells().has(cave_front) and world.get_dirty_cells().has(cave_back), "both layers become dirty") var dirty := world.consume_dirty_cells() _expect(not dirty.is_empty() and world.get_dirty_cells().is_empty(), "dirty cells can be consumed deterministically") _expect(not world.set_walkable(Vector3i(99, 0, 0), true), "out-of-bounds walkability mutation is rejected") func _test_connected_support_validation() -> void: var world = WorldServiceType.new() world.reset(_bounds(-5, 5, 0, 2)) _expect(world.set_support(Vector3i(0, 0, 0), 3), "explicit support capacity is stored") _expect(world.occupy(&"existing-room", [Vector3i(1, 0, 0)], &"facility_small"), "existing structural load is stored") var supported := world.validate_support([Vector3i(2, 0, 0), Vector3i(3, 0, 0)], 1) _expect(supported[&"ok"], "component capacity covers existing and proposed load") _expect(supported[&"required_weight"] == 3, "support report includes existing structural load") _expect(supported[&"available_capacity"] == 3, "support report exposes finite capacity") var overloaded := world.validate_support([ Vector3i(2, 0, 0), Vector3i(3, 0, 0), Vector3i(4, 0, 0), ], 1) _expect(not overloaded[&"ok"] and overloaded[&"errors"].has(world.ERROR_UNSUPPORTED), "overloaded component is rejected") _expect(overloaded[&"unsupported_cells"].size() == 3, "all proposed cells in failed component are identified") _expect(world.set_support(Vector3i(-2, 0, 1), 0, true), "infinite structural anchor is stored") var anchored := world.validate_support([Vector3i(-1, 0, 1), Vector3i(0, 0, 1)], 99) _expect(anchored[&"ok"] and anchored[&"available_capacity"] == -1, "connected anchor supports any finite weight") _expect(not world.validate_support([Vector3i(0, 0, 0)], 0)[&"ok"], "non-positive proposed weight is rejected") func _test_snapshot_round_trip_and_atomic_restore() -> void: var source = WorldServiceType.new() source.reset(_bounds(-3, 3, -3, 3)) source.occupy(&"warehouse", [Vector3i(1, 0, 1), Vector3i(0, 0, 1)], &"facility_medium") source.set_walkable(Vector3i(-1, 0, 0), true) source.set_excavated(Vector3i(2, -2, 0), true) source.set_excavated(Vector3i(-2, 1, 0), false) source.set_support(Vector3i(0, 0, 0), 5, false) source.set_support(Vector3i(-1, 0, 1), 0, true) var snapshot := source.create_snapshot() var restored = WorldServiceType.new() restored.reset(Rect2i(0, 0, 1, 1)) _expect(restored.restore_snapshot(snapshot), "valid world snapshot restores") _expect(restored.create_snapshot() == snapshot, "world snapshot round trip is exact") _expect(DigestType.compute(restored.create_snapshot()) == DigestType.compute(snapshot), "round trip preserves deterministic digest") var corrupt: Dictionary = snapshot.duplicate(true) corrupt[&"occupancies"].append({ &"entity_id": &"overlap", &"kind": &"facility", &"cells": [Vector3i(0, 0, 1)], }) var before_failed_restore := restored.create_snapshot() _expect(not restored.restore_snapshot(corrupt), "overlapping snapshot is rejected") _expect(restored.create_snapshot() == before_failed_restore, "failed restore is fully atomic") func _test_snapshot_order_is_deterministic() -> void: var first = WorldServiceType.new() var second = WorldServiceType.new() first.reset(_bounds(-2, 2, -1, 1)) second.reset(_bounds(-2, 2, -1, 1)) first.occupy(&"z-entity", [Vector3i(1, 0, 0)], &"decoration") first.occupy(&"a-entity", [Vector3i(-1, 0, 0)], &"decoration") second.occupy(&"a-entity", [Vector3i(-1, 0, 0)], &"decoration") second.occupy(&"z-entity", [Vector3i(1, 0, 0)], &"decoration") first.set_walkable(Vector3i(1, 1, 1), true) first.set_walkable(Vector3i(-1, -1, 0), true) second.set_walkable(Vector3i(-1, -1, 0), true) second.set_walkable(Vector3i(1, 1, 1), true) _expect(first.create_snapshot() == second.create_snapshot(), "snapshot ignores Dictionary insertion order") _expect(DigestType.compute(first.create_snapshot()) == DigestType.compute(second.create_snapshot()), "equivalent worlds have identical digest") func _bounds(min_x: int, max_x: int, min_y: int, max_y: int) -> Dictionary: return { &"min_x": min_x, &"max_x": max_x, &"min_y": min_y, &"max_y": max_y, } func _expect(condition: bool, label: String) -> void: _checks += 1 if condition: print(" ✓ %s" % label) return _failures += 1 push_error(" ✗ %s" % label)