120 lines
5.6 KiB
GDScript
120 lines
5.6 KiB
GDScript
extends SceneTree
|
|
## W1 (docs/WORLDLETS_DESIGN.md): choosing a worldlet. The New World and Host
|
|
## Game pages have a "Where" picker listing the worldlets a new world can
|
|
## start in (only the Valley today, so it sits still); a world made from it
|
|
## remembers it; the Load list says where each world is; and a hosted island
|
|
## keeps its worldlet, like its seed, once it's made.
|
|
## Run: godot --headless --path . --script res://tests/test_worldlet_pick.gd
|
|
|
|
const DIR := "user://test_worldlet_pick"
|
|
|
|
var _fails := 0
|
|
var _finished := false
|
|
|
|
func check(cond: bool, what: String) -> void:
|
|
print((" ok " if cond else " FAIL ") + what)
|
|
if not cond:
|
|
_fails += 1
|
|
|
|
func _initialize() -> void:
|
|
_run.call_deferred()
|
|
|
|
func _run() -> void:
|
|
var S: Node = root.get_node("Saves")
|
|
var Net: Node = root.get_node("Net")
|
|
S.root_dir = DIR + "/worlds"
|
|
_rm_tree(DIR)
|
|
DirAccess.make_dir_recursive_absolute(DIR)
|
|
Net.host_config = DIR + "/server/server.json"
|
|
var me = load("res://scripts/net/identity.gd").open(DIR + "/me")
|
|
me.name = "Alice"
|
|
Net.identity = me
|
|
await _body(S, Net)
|
|
check(_finished, "test ran to the end (no script errors)")
|
|
_rm_tree(DIR)
|
|
print("RESULT: %s (%d failures)" % ["PASS" if _fails == 0 else "FAIL", _fails])
|
|
quit(1 if _fails > 0 else 0)
|
|
|
|
func _body(S: Node, Net: Node) -> void:
|
|
var T: Script = load("res://scripts/world/terrain.gd")
|
|
var TS: Script = load("res://scripts/ui/title_screen.gd")
|
|
print("the worldlets to start in")
|
|
var starts: Array = T.starting_worldlets()
|
|
check(starts.size() == 1 and String(starts[0].id) == "valley", "only the Valley (%s; the Cove is reached on the journey)" % [starts.map(func(w): return w.id)])
|
|
check(T.worldlets().all(func(w): return w.has("start")), "every worldlet says whether it's a start")
|
|
check(T.worldlet_name("valley") == "Valley", "the Valley's name, for the menus")
|
|
check(T.worldlet_name("nowhere") == "nowhere", "(an unknown one: its id)")
|
|
check(TS.picked_worldlet(null) == "valley", "nothing picked: the Valley")
|
|
|
|
print("the New World page")
|
|
var title: Node = load("res://scenes/title.tscn").instantiate()
|
|
root.add_child(title)
|
|
for _i in range(3):
|
|
await process_frame
|
|
var release: Array = TS.offered_worldlets(false)
|
|
check(release.size() == 1 and String(release[0].id) == "valley", "normally only the Valley is offered")
|
|
var dev: Array = TS.offered_worldlets(true)
|
|
check(String(dev[0].id) == "valley" and dev.any(func(w): return w.id == "cove" and String(w.name) == "Cove (testing)"),
|
|
"with --dev-worldlets, the Cove too, marked for testing (%s)" % [dev.map(func(w): return w.name)])
|
|
check(not TS.dev_worldlets(), "(this test runs without --dev-worldlets)")
|
|
var pick: OptionButton = title._worldlet_pick
|
|
check(pick == null, "New World has no \"Where\": the journey always begins in the Valley")
|
|
check(TS.picked_worldlet(pick) == "valley", "so a new world is the Valley")
|
|
var id: String = S.create_world("Pick test", 4242, {"worldlet": TS.picked_worldlet(pick)})
|
|
var meta: Dictionary = S.list_worlds().filter(func(w): return w.id == id)[0] if not id.is_empty() else {}
|
|
check(String(meta.get("worldlet", "")) == "valley", "a world made from it remembers the Valley (%s)" % meta.get("worldlet", "-"))
|
|
|
|
print("the Load list")
|
|
title._show("load")
|
|
await process_frame
|
|
check(_texts(title._list).any(func(t): return t.begins_with("Valley · seed 4242")), "says where each world is (%s)" % [_texts(title._list)])
|
|
|
|
print("the Host Game page")
|
|
var hp: OptionButton = title._host_worldlet
|
|
check(hp != null and hp.get_item_text(hp.selected) == "Valley", "a \"Where\" picker too, on the Valley")
|
|
title._show("host")
|
|
await process_frame
|
|
check(hp.disabled and TS.picked_worldlet(hp) == "valley", "a new island: the Valley (the only start; One land mode will widen it)")
|
|
# Once the island exists it keeps its worldlet: the picker shows that one.
|
|
DirAccess.make_dir_recursive_absolute(DIR + "/server/worlds/server-world")
|
|
var f := FileAccess.open(DIR + "/server/worlds/server-world/meta.json", FileAccess.WRITE)
|
|
f.store_string(JSON.stringify({"seed": 7, "worldlet": "valley"}))
|
|
f.close()
|
|
title._show("host")
|
|
await process_frame
|
|
check(hp.disabled and TS.picked_worldlet(hp) == "valley", "an island already made: shows its worldlet, locked")
|
|
check(title._host_seed_label.text == "Seed (kept)", "(like its seed)")
|
|
check(title._host_msg.text.contains("forward UDP 24242 and 24243 (the Cove)"),
|
|
"the Host page says which ports to forward, the Cove's too (%s)" % title._host_msg.text.get_slice("\n", 1))
|
|
var L: Node = root.get_node("Lands")
|
|
check(L.extra_ports("valley", 24242) == [["cove", 24243]], "(the Valley's lands: the Cove on 24243)")
|
|
# A worldlet that isn't a start (an island made elsewhere) is still shown.
|
|
var extra := OptionButton.new()
|
|
extra.add_item("Valley")
|
|
extra.set_item_metadata(0, "valley")
|
|
check(TS.select_worldlet(extra, "valley") == 0, "select_worldlet finds the Valley")
|
|
check(TS.select_worldlet(extra, "nowhere") == -1 and extra.item_count == 1, "and adds nothing for an unknown one")
|
|
extra.free()
|
|
title.queue_free()
|
|
await process_frame
|
|
|
|
print("hosting records the worldlet")
|
|
var C: Script = load("res://scripts/net/server_config.gd")
|
|
check(String(C.open(DIR + "/server/server.json").data.worldlet) == "valley", "server.json's worldlet is the Valley by default")
|
|
_finished = true
|
|
|
|
func _texts(n: Node) -> Array:
|
|
var out: Array = []
|
|
for c in n.find_children("*", "Label", true, false):
|
|
out.append(String(c.text))
|
|
return out
|
|
|
|
static func _rm_tree(d: String) -> void:
|
|
if not DirAccess.dir_exists_absolute(d):
|
|
return
|
|
for f in DirAccess.get_files_at(d):
|
|
DirAccess.remove_absolute(d.path_join(f))
|
|
for s in DirAccess.get_directories_at(d):
|
|
_rm_tree(d.path_join(s))
|
|
DirAccess.remove_absolute(d)
|