T2 tutorial: all five chapters with Old Tam, scripted dusk and demo wolf, rabbits for the hunt, title-screen Tutorial entry, pause-menu skip/leave, goodbye card; full bot playthrough test

This commit is contained in:
Paul Bailey
2026-11-05 14:43:00 +00:00
parent 5b5dd3d609
commit f93ebe1bea
11 changed files with 976 additions and 36 deletions

View File

@@ -9,6 +9,8 @@ var _pages: Dictionary = {} ## name -> Control
var _name_edit: LineEdit
var _seed_edit: LineEdit
var _rot_pick: OptionButton
## The page to open on (the tutorial's "Start your own world" sends you to "new").
static var start_page := ""
## [setting, what the New World page calls it]
const ROT_CHOICES := [["normal", "Normally (raw meat lasts 2 days)"], ["slow", "Slowly (twice as long)"], ["off", "Never"]]
var _list: VBoxContainer
@@ -100,7 +102,8 @@ func _ready() -> void:
Net.players_changed.connect(func():
if _pages["lobby"].visible:
_fill_lobby())
_show("main")
_show(start_page if start_page in _pages else "main")
start_page = ""
# Back from a server (left, kicked, or it went away): say why.
if Net.state == "offline" and not Net.last_reason.is_empty():
_show("join")
@@ -202,9 +205,13 @@ func _main_page() -> Control:
var v := VBoxContainer.new()
v.add_theme_constant_override("separation", 10)
var worlds := Saves.list_worlds()
if not worlds.is_empty():
if worlds.is_empty():
v.add_child(UITheme.label("New here? Try the tutorial (about 20 minutes).", 15, UITheme.TEXT_DIM))
else:
var w: Dictionary = worlds[0]
v.add_child(_button("Continue: %s" % w.name, _play.bind(w.id)))
var tut := tutorial_world()
v.add_child(_button("Tutorial" if tut.is_empty() else "Tutorial (carry on)", _play_tutorial))
v.add_child(_button("New World", _show.bind("new")))
var lb := _button("Load World", _show.bind("load"))
lb.disabled = worlds.is_empty()
@@ -673,6 +680,20 @@ func _create() -> void:
var rot: String = ROT_CHOICES[maxi(_rot_pick.selected, 0)][0]
_play(Saves.create_world(world_name, seed, {"rot": rot}))
## The tutorial (docs/TUTORIAL_DESIGN.md): its own world on the original
## island (seed 1337), made the first time and carried on after that.
const TUTORIAL_SEED := 1337
static func tutorial_world() -> Dictionary:
for w in Saves.list_worlds():
if bool(w.get("tutorial", false)):
return w
return {}
func _play_tutorial() -> void:
var w := tutorial_world()
_play(String(w.id) if not w.is_empty() else Saves.create_world("Tutorial", TUTORIAL_SEED, {"tutorial": true}))
func _play(id: String) -> void:
Saves.current_id = id
get_tree().change_scene_to_file(WORLD_SCENE)