W2: several lakes per worldlet, a beach block shelving into the sea with a current that turns swimmers back; testbay test worldlet through the water, edge and boundary suites; the two ways to play (journey, one land) recorded

This commit is contained in:
Paul Bailey
2026-11-06 16:48:20 +00:00
parent 68e6d814d9
commit 9b88a10609
9 changed files with 400 additions and 43 deletions

View File

@@ -4,34 +4,63 @@ extends SceneTree
## the invisible wall, falls off the map, or ends up stuck below the waterline
## (in a pit near the edge).
##
## Then the same on a worldlet with a beach (W2, tests/worldlets/testbay.json):
## off the beach you swim out into the sea, and the current must turn you back
## before the wall (being afloat in the open sea there is fine).
##
## Run: godot --headless --path . --fixed-fps 30 --script res://tests/test_boundary.gd
const DIRECTIONS := 24
const BAY_DIRECTIONS := 8 # (spread over the beach and its headlands)
const SECONDS_PER_TRY := 25.0
var _failures := 0
var _tries := 0
func _initialize() -> void:
_run.call_deferred()
func _run() -> void:
var S: Node = root.get_node("Saves")
S.root_dir = "user://test_boundary_worlds"
for w in S.list_worlds():
S.delete_world(w.id)
print("the Valley")
await _escape_all(DIRECTIONS, -1.0)
print("a beach (testbay)")
S.current_id = S.create_world("Bay", 1337, {"worldlet": "testbay"})
await _escape_all(BAY_DIRECTIONS, 90.0)
for w in S.list_worlds():
S.delete_world(w.id)
DirAccess.remove_absolute(S.root_dir)
print("RESULT: %s (%d/%d directions held)" % ["PASS" if _failures == 0 else "FAIL", _tries - _failures, _tries])
quit(1 if _failures > 0 else 0)
## Walks out in `count` directions: all round, or (beach_deg >= 0) across the
## beach's arc and a little past it either side.
func _escape_all(count: int, beach_deg: float) -> void:
var world: Node3D = load("res://scenes/world.tscn").instantiate()
root.add_child(world)
_run.call_deferred(world)
func _run(world: Node3D) -> void:
for _i in range(10):
await physics_frame
var terrain: Node3D = world.get_node("Terrain")
var player: CharacterBody3D = world.get_node("Player")
var failures := 0
var tick := 1.0 / Engine.physics_ticks_per_second
for i in range(DIRECTIONS):
var ang := TAU * i / DIRECTIONS
var pulled := 0
for i in range(count):
var ang := TAU * i / count
if beach_deg >= 0.0:
ang = deg_to_rad(beach_deg + lerpf(-65.0, 65.0, float(i) / (count - 1)))
var out := Vector3(cos(ang), 0.0, sin(ang))
var start: Vector3 = out * (terrain.play_radius - 12.0)
start.y = terrain.sample_height(start.x, start.z) + 1.0
start.y = maxf(terrain.sample_height(start.x, start.z), terrain.water_level) + 1.0
player.global_position = start
player.velocity = Vector3.ZERO
player.rotation = Vector3(0.0, atan2(-out.x, -out.z), 0.0)
Input.action_press("move_forward")
var escaped := false
var max_d := 0.0
var in_current := false
var frames := int(SECONDS_PER_TRY / tick)
for f in range(frames):
if f % 12 == 0:
@@ -41,17 +70,28 @@ func _run(world: Node3D) -> void:
await physics_frame
var p := player.global_position
max_d = maxf(max_d, Vector2(p.x, p.z).length())
in_current = in_current or terrain.current_at(p.x, p.z) > 0.2
if not terrain.inside_boundary(p.x, p.z, -1.5) or p.y < terrain.min_height - 5.0:
escaped = true
break
Input.action_release("move_forward")
Input.action_release("jump")
var p := player.global_position
if not escaped and p.y < terrain.water_level - 0.5:
var at_sea: bool = world.water_at(p.x, p.z).get("type", "") == "sea"
if not escaped and p.y < terrain.water_level - 0.5 and not at_sea:
escaped = true # stuck in a pit below the waterline
print("dir %2d (%3d deg): %s max radius %.1f final (%.1f, %.1f, %.1f)" % [
i, int(rad_to_deg(ang)), "FAILED" if escaped else "held", max_d, p.x, p.y, p.z])
if in_current:
pulled += 1
print("dir %2d (%3d deg): %s max radius %.1f final (%.1f, %.1f, %.1f)%s" % [
i, int(rad_to_deg(ang)), "FAILED" if escaped else "held", max_d, p.x, p.y, p.z,
" (the current turned them back)" if in_current else ""])
_tries += 1
if escaped:
failures += 1
print("RESULT: %s (%d/%d directions held)" % ["PASS" if failures == 0 else "FAIL", DIRECTIONS - failures, DIRECTIONS])
quit(1 if failures > 0 else 0)
_failures += 1
if beach_deg >= 0.0 and pulled == 0:
print("FAILED: nobody swam far enough out to meet the current")
_failures += 1
_tries += 1
world.queue_free()
for _i in range(3):
await process_frame