P07-01-WX: 仕上がった天候の機能の受入:自然天候・雨・嵐・世界樹と成人客のマナ霧・上部の表示と予報・保存と移行(マナ炉の産出 120 を除く。P07-01 の補助の作業。原単位への加算 0)
This commit is contained in:
@@ -12420,6 +12420,8 @@ func _on_guest_despawned(guest_id: StringName, persistent_record: Dictionary) ->
|
|||||||
elevators.cancel_actor(actor_id)
|
elevators.cancel_actor(actor_id)
|
||||||
var path_removed := path_service.despawn_actor(actor_id)
|
var path_removed := path_service.despawn_actor(actor_id)
|
||||||
_movement_credits.erase(actor_id)
|
_movement_credits.erase(actor_id)
|
||||||
|
# A13: a rain hold describes a present guest, so it leaves with the guest.
|
||||||
|
weather.release_rain_hold(guest_id)
|
||||||
_synchronize_operations_population()
|
_synchronize_operations_population()
|
||||||
var payload := persistent_record.duplicate(true)
|
var payload := persistent_record.duplicate(true)
|
||||||
payload[&"path_actor_id"] = actor_id
|
payload[&"path_actor_id"] = actor_id
|
||||||
|
|||||||
+3
-3
@@ -3964,7 +3964,7 @@
|
|||||||
"template": "PASS: <checks> checks",
|
"template": "PASS: <checks> checks",
|
||||||
"required": true,
|
"required": true,
|
||||||
"fixed_check_count_used": false,
|
"fixed_check_count_used": false,
|
||||||
"source_sha256_at_schema_audit": "0dfba98e091f015f74fc7897f8a7b7ce8e286826dc2a17785095ab4e0d51a946",
|
"source_sha256_at_schema_audit": "e34b52ba3511f7391de1435c2f907997dd10235742ebc029831808af969c68e0",
|
||||||
"authority": {
|
"authority": {
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
||||||
"scope": "new P07-01 suite marker; native execution pending"
|
"scope": "new P07-01 suite marker; native execution pending"
|
||||||
@@ -3975,7 +3975,7 @@
|
|||||||
"template": "PASS: <checks> checks",
|
"template": "PASS: <checks> checks",
|
||||||
"required": true,
|
"required": true,
|
||||||
"fixed_check_count_used": false,
|
"fixed_check_count_used": false,
|
||||||
"source_sha256_at_schema_audit": "39ca0eb47eef46a5c2c73cb165b300360753ce74010b6512901c0f921d2e00a6",
|
"source_sha256_at_schema_audit": "d85e56dcf75535b19b1af615f8b75e010f4f3906a0e71afdf97102e1bfbffc65",
|
||||||
"authority": {
|
"authority": {
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
||||||
"scope": "new P07-01 F7 restart writer marker; native execution pending"
|
"scope": "new P07-01 F7 restart writer marker; native execution pending"
|
||||||
@@ -3986,7 +3986,7 @@
|
|||||||
"template": "PASS: <checks> checks",
|
"template": "PASS: <checks> checks",
|
||||||
"required": true,
|
"required": true,
|
||||||
"fixed_check_count_used": false,
|
"fixed_check_count_used": false,
|
||||||
"source_sha256_at_schema_audit": "dd7c41952ced7edf38d2fbc5517128bc7b955c49ddccca90eb933062f4b8e8a7",
|
"source_sha256_at_schema_audit": "e5c2376e9cb3197d6a0a8d99c9dea020cad2648328178949cd188d999e72071a",
|
||||||
"authority": {
|
"authority": {
|
||||||
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
"path": "docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md",
|
||||||
"scope": "new P07-01 F7 restart reader marker; native execution pending"
|
"scope": "new P07-01 F7 restart reader marker; native execution pending"
|
||||||
|
|||||||
@@ -91,3 +91,33 @@
|
|||||||
- 比べる状態の `needs` は、名前を文字の順に並べる。読み直した客は needs のキーの順が違うことがあり、`StringName` の並べ替えは文字の順ではなく、process ごとに違うため。
|
- 比べる状態の `needs` は、名前を文字の順に並べる。読み直した客は needs のキーの順が違うことがあり、`StringName` の並べ替えは文字の順ではなく、process ごとに違うため。
|
||||||
- 固定の値: 変えた3本(`test_p07_weather_runtime.gd`・writer・reader)の source の SHA を、`tools/regression/suite-policy.json` と `completion_marker_contracts.json` で更新した。
|
- 固定の値: 変えた3本(`test_p07_weather_runtime.gd`・writer・reader)の source の SHA を、`tools/regression/suite-policy.json` と `completion_marker_contracts.json` で更新した。
|
||||||
- 確かめ(局所。正式の証拠ではない): scratch の stage で、変えた suite と狭い roster の 12 本、kitchen を直接動かして合格した(`P07_01_WX_REPAIR1_LOCAL_CHECKS_R01.json`)。正式の証拠は、新しい S の native の収集、登録の validation、全 roster、独立レビュー。
|
- 確かめ(局所。正式の証拠ではない): scratch の stage で、変えた suite と狭い roster の 12 本、kitchen を直接動かして合格した(`P07_01_WX_REPAIR1_LOCAL_CHECKS_R01.json`)。正式の証拠は、新しい S の native の収集、登録の validation、全 roster、独立レビュー。
|
||||||
|
|
||||||
|
## 7. 直し 2(S `f99c881b` の最終の独立レビューの後。repair 2)
|
||||||
|
|
||||||
|
- 契機:
|
||||||
|
- S `f99c881b` の最終の独立レビュー(`local_c4c1a8d6`)は changes_requested(medium 1・low 1)。前のレビューの high と medium は解消したと判定された。
|
||||||
|
- S `f99c881b` の全 roster は合格した(198 本・22,857 checks)。
|
||||||
|
- 管理の記録は `COMMANDER_REPAIR_PLAN_P07_01_WX_R02.md`。
|
||||||
|
- 診断(scratch の stage)で分かったこと:
|
||||||
|
- 施設の無い試験の世界では、延びた客は 06:03 に帰り始め(`NO_SUITABLE_FACILITY`)、06:04 に居なくなる。必要(needs)の値や客の種類を変えても同じ。
|
||||||
|
- そのため、再開の保存には延長の記録が一度も乗っていなかった。
|
||||||
|
- 製品の不具合(持ち越したコード): 延長の記録は、次の tick の天候の境界まで片づかなかった。
|
||||||
|
- そのため、客が居なくなった分の保存は、保存は成功するが読み込めなかった(`RESTORE_FAILED`)。
|
||||||
|
- 原因は、復元の照合「延長は館内の客の予定と一致すること」。
|
||||||
|
- 直したもの:
|
||||||
|
1. 製品: 客が居なくなった時(`autoload/simulation_runtime.gd` の `_on_guest_despawned`)に、その客の延長の記録をすぐ片づける。
|
||||||
|
- `scripts/environment/weather_timeline.gd` に `release_rain_hold` を足した。
|
||||||
|
- 天候の境界での片づけは今のまま残した。
|
||||||
|
2. medium(WX7): 再開の台本の雨の場面に、2つの保存を足した。
|
||||||
|
- 363 分: 延びた客が帰る途中で館内に居て、延長の記録がある。
|
||||||
|
- 364 分: 客が居なくなった直後で、延長の記録が無い。上の不具合の回帰の確かめ。
|
||||||
|
- writer は、雨の全ての保存を同じ process で読み直す。読んだ直後・1分後・最後の状態が、straight と bytes で一致することを確かめる。
|
||||||
|
- reader は、別の process で同じことを確かめる。
|
||||||
|
- 363 分の保存では、延長の記録が1つで、`planned_exit_at` が 602 であることを厳密に確かめる。1分後の一致で、二度目の延長が無いことを示す。
|
||||||
|
- 500 分の確かめから、誤っていた「with the hold of a present guest」を外した。
|
||||||
|
3. 回帰: `test_p07_weather_runtime.gd` で、通常の進行で延びた客が帰った分に、延長の記録が片づいていて、その分の snapshot が復元できることを確かめる。
|
||||||
|
- 開示(U1): 施設の無い試験の世界では、延びた客は延長の時刻より前に、施設が無いので帰る。
|
||||||
|
- そのため、通常の時刻の進行で延長の時刻(10:02)に着いて帰る場面は、この試験では作れない。施設を建てて客が使う場面が要る。
|
||||||
|
- 延長の時刻の帰りは、決定の処理を延長の時刻でじかに呼んで確かめている(`_test_rain_hold_exit`)。延長の時刻に、二度目の延長をせず、PLANNED_EXIT で帰り始める。
|
||||||
|
- 固定の値: 変えた3本の source の SHA を、`tools/regression/suite-policy.json` と `completion_marker_contracts.json` で更新した。
|
||||||
|
- 確かめ(局所。正式の証拠ではない): scratch の stage で、狭い roster の 12 本・再開の2段・kitchen を直接動かして合格した(`P07_01_WX_REPAIR2_LOCAL_CHECKS_R01.json`)。
|
||||||
|
|||||||
@@ -145,6 +145,11 @@ func prune_rain_holds(present_guest_ids: Dictionary) -> void:
|
|||||||
if not present_guest_ids.has(StringName(key)):
|
if not present_guest_ids.has(StringName(key)):
|
||||||
_rain_holds.erase(key)
|
_rain_holds.erase(key)
|
||||||
|
|
||||||
|
## The hold of a guest that has just left; a save in that same minute then
|
||||||
|
## holds only present guests' holds (P07-01 SPEC section 5).
|
||||||
|
func release_rain_hold(guest_id: StringName) -> void:
|
||||||
|
_rain_holds.erase(String(guest_id))
|
||||||
|
|
||||||
func create_snapshot() -> Dictionary:
|
func create_snapshot() -> Dictionary:
|
||||||
return {&"version": VERSION, &"minute": _minute, &"kind": _kind,
|
return {&"version": VERSION, &"minute": _minute, &"kind": _kind,
|
||||||
&"since": _since, &"pending": _pending.duplicate(true),
|
&"since": _since, &"pending": _pending.duplicate(true),
|
||||||
|
|||||||
@@ -26,15 +26,23 @@ func _run() -> void:
|
|||||||
var straight := fixtures.new_fixture()
|
var straight := fixtures.new_fixture()
|
||||||
var straight_runtime: Variant = straight[&"runtime"]
|
var straight_runtime: Variant = straight[&"runtime"]
|
||||||
var held_guest: Variant = straight_runtime.guest_service.get_guest(Fixture.HELD_GUEST)
|
var held_guest: Variant = straight_runtime.guest_service.get_guest(Fixture.HELD_GUEST)
|
||||||
var held := {"hold": {}, "reason": &""}
|
var held := {"hold": {}, "reason": &"", "after": {}}
|
||||||
fixtures.play(straight, Fixture.FIRST_MINUTE, Fixture.LAST_MINUTE, func(_minute: int) -> void:
|
fixtures.play(straight, Fixture.FIRST_MINUTE, Fixture.LAST_MINUTE, func(minute: int) -> void:
|
||||||
if (held["hold"] as Dictionary).is_empty():
|
if (held["hold"] as Dictionary).is_empty():
|
||||||
held["hold"] = straight_runtime.weather.get_rain_hold(Fixture.HELD_GUEST)
|
held["hold"] = straight_runtime.weather.get_rain_hold(Fixture.HELD_GUEST)
|
||||||
if StringName(held["reason"]).is_empty():
|
if StringName(held["reason"]).is_empty():
|
||||||
held["reason"] = held_guest.exit_reason)
|
held["reason"] = held_guest.exit_reason
|
||||||
|
if minute == 363:
|
||||||
|
_expect(straight_runtime.guest_service.get_guest(Fixture.HELD_GUEST) != null and held_guest.state == GuestRuntime.State.LEAVING
|
||||||
|
and straight_runtime.weather.get_rain_hold(Fixture.HELD_GUEST) == Fixture.HOLD, "at 06:03 the held guest is still present and leaving with its hold")
|
||||||
|
if minute == 364:
|
||||||
|
_expect(straight_runtime.guest_service.get_guest(Fixture.HELD_GUEST) == null and straight_runtime.weather.get_rain_holds().is_empty(),
|
||||||
|
"at 06:04 the held guest is gone and its hold left with it")
|
||||||
|
if minute - 1 in Fixture.SAVE_MINUTES:
|
||||||
|
held["after"][minute] = fixtures.state_bytes(straight_runtime))
|
||||||
# The hold only moves the planned exit; every other current rule still applies,
|
# The hold only moves the planned exit; every other current rule still applies,
|
||||||
# so in this world without facilities the guest leaves for lack of one.
|
# so in this world without facilities the guest leaves for lack of one.
|
||||||
_expect(held["hold"] == {"original_exit": 362, "extended_to": 602} and held_guest.planned_exit_at == 602 and held["reason"] == &"NO_SUITABLE_FACILITY",
|
_expect(held["hold"] == Fixture.HOLD and held_guest.planned_exit_at == 602 and held["reason"] == &"NO_SUITABLE_FACILITY",
|
||||||
"the guest due at 06:02 was held to 10:02 and still left by the current rules (%s)" % String(held["reason"]))
|
"the guest due at 06:02 was held to 10:02 and still left by the current rules (%s)" % String(held["reason"]))
|
||||||
_expect(straight[&"draws"][&"count"] == Fixture.DRAW_MINUTES.size() and straight_runtime.weather.get_last_draw_day() == 1, "the uninterrupted script draws day 1 once")
|
_expect(straight[&"draws"][&"count"] == Fixture.DRAW_MINUTES.size() and straight_runtime.weather.get_last_draw_day() == 1, "the uninterrupted script draws day 1 once")
|
||||||
var saving := fixtures.new_fixture()
|
var saving := fixtures.new_fixture()
|
||||||
@@ -43,16 +51,39 @@ func _run() -> void:
|
|||||||
var saved_paths := {}
|
var saved_paths := {}
|
||||||
fixtures.play(saving, Fixture.FIRST_MINUTE, Fixture.LAST_MINUTE, func(minute: int) -> void:
|
fixtures.play(saving, Fixture.FIRST_MINUTE, Fixture.LAST_MINUTE, func(minute: int) -> void:
|
||||||
if minute in Fixture.SAVE_MINUTES:
|
if minute in Fixture.SAVE_MINUTES:
|
||||||
|
if minute == 363:
|
||||||
|
_expect(saving_runtime.guest_service.get_guest(Fixture.HELD_GUEST) != null and saving_runtime.weather.get_rain_holds() == {String(Fixture.HELD_GUEST): Fixture.HOLD}
|
||||||
|
and saving_runtime.guest_service.get_guest(Fixture.HELD_GUEST).planned_exit_at == 602, "minute 363 saves the hold of the present held guest")
|
||||||
|
if minute == 364:
|
||||||
|
_expect(saving_runtime.guest_service.get_guest(Fixture.HELD_GUEST) == null and saving_runtime.weather.get_rain_holds().is_empty(), "minute 364 saves just after the held guest left, without its hold")
|
||||||
if minute == 500:
|
if minute == 500:
|
||||||
var held_present: bool = saving_runtime.guest_service.get_guest(Fixture.HELD_GUEST) != null
|
_expect(saving_runtime.weather.get_kind() == &"rain", "minute 500 saves mid-rain")
|
||||||
_expect(saving_runtime.weather.get_kind() == &"rain" and (not held_present or not saving_runtime.weather.get_rain_hold(Fixture.HELD_GUEST).is_empty()), "minute 500 saves mid-rain with the hold of a present guest")
|
|
||||||
var path := Fixture.WRITER_SAVE % minute
|
var path := Fixture.WRITER_SAVE % minute
|
||||||
saved_states[minute] = fixtures.state_bytes(saving_runtime)
|
saved_states[minute] = fixtures.state_bytes(saving_runtime)
|
||||||
_expect(bool(saving_runtime.save_to_path(path).get(&"ok", false)), "save file at minute %d" % minute)
|
_expect(bool(saving_runtime.save_to_path(path).get(&"ok", false)), "save file at minute %d" % minute)
|
||||||
saved_paths[minute] = path)
|
saved_paths[minute] = path)
|
||||||
_expect(fixtures.state_bytes(saving_runtime) == fixtures.state_bytes(straight_runtime), "writing the save files leaves the weather state as without saving")
|
_expect(fixtures.state_bytes(saving_runtime) == fixtures.state_bytes(straight_runtime), "writing the save files leaves the weather state as without saving")
|
||||||
var saves := _packages(Fixture.SAVE_MINUTES, saved_paths, saved_states, Fixture.WRITER_SAVE)
|
|
||||||
var final_state := fixtures.state_bytes(straight_runtime)
|
var final_state := fixtures.state_bytes(straight_runtime)
|
||||||
|
for minute: int in Fixture.SAVE_MINUTES:
|
||||||
|
var reload := fixtures.new_fixture(false)
|
||||||
|
var reload_runtime: Variant = reload[&"runtime"]
|
||||||
|
_expect(bool(reload_runtime.load_from_path(str(saved_paths.get(minute, Fixture.WRITER_SAVE % minute))).get(&"ok", false))
|
||||||
|
and fixtures.state_bytes(reload_runtime) == saved_states.get(minute, PackedByteArray()) and reload[&"clock"].absolute_minute == minute,
|
||||||
|
"this process reloads the save file of minute %d exactly" % minute)
|
||||||
|
if minute == 363:
|
||||||
|
_expect(reload_runtime.weather.get_rain_holds() == {String(Fixture.HELD_GUEST): Fixture.HOLD} and reload_runtime.guest_service.get_guest(Fixture.HELD_GUEST).planned_exit_at == 602,
|
||||||
|
"the reloaded minute 363 save keeps the one hold and the extended plan")
|
||||||
|
fixtures.play(reload, minute, minute + 1, Callable())
|
||||||
|
_expect(fixtures.state_bytes(reload_runtime) == held["after"].get(minute + 1, PackedByteArray()),
|
||||||
|
"one minute after the minute %d reload equals the uninterrupted run (no second extension)" % minute)
|
||||||
|
fixtures.play(reload, minute + 1, Fixture.LAST_MINUTE, Callable())
|
||||||
|
_expect(fixtures.state_bytes(reload_runtime) == final_state, "the minute %d reload continues to the uninterrupted final state" % minute)
|
||||||
|
fixtures.free_fixture(reload)
|
||||||
|
var saves := _packages(Fixture.SAVE_MINUTES, saved_paths, saved_states, Fixture.WRITER_SAVE)
|
||||||
|
var after := {}
|
||||||
|
for minute: int in held["after"]:
|
||||||
|
var bytes: PackedByteArray = held["after"][minute]
|
||||||
|
after[str(minute)] = {"sha256": Fixture.sha256(bytes), "base64": Marshalls.raw_to_base64(bytes)}
|
||||||
var fog := _fog_scene(fixtures)
|
var fog := _fog_scene(fixtures)
|
||||||
var handoff := {
|
var handoff := {
|
||||||
"schema": Fixture.HANDOFF_SCHEMA,
|
"schema": Fixture.HANDOFF_SCHEMA,
|
||||||
@@ -62,6 +93,7 @@ func _run() -> void:
|
|||||||
"last_minute": Fixture.LAST_MINUTE,
|
"last_minute": Fixture.LAST_MINUTE,
|
||||||
"straight_final_state_sha256": Fixture.sha256(final_state),
|
"straight_final_state_sha256": Fixture.sha256(final_state),
|
||||||
"straight_final_state_base64": Marshalls.raw_to_base64(final_state),
|
"straight_final_state_base64": Marshalls.raw_to_base64(final_state),
|
||||||
|
"after_states": after,
|
||||||
"saves": saves,
|
"saves": saves,
|
||||||
"fog": fog,
|
"fog": fog,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,19 +55,28 @@ func _check_restarts(handoff: Dictionary) -> void:
|
|||||||
_expect(Fixture.sha256(final_state) == str(handoff.get("straight_final_state_sha256", "")), "the writer's final state arrived intact")
|
_expect(Fixture.sha256(final_state) == str(handoff.get("straight_final_state_sha256", "")), "the writer's final state arrived intact")
|
||||||
var saves: Array = handoff.get("saves", [])
|
var saves: Array = handoff.get("saves", [])
|
||||||
_expect(saves.size() == Fixture.SAVE_MINUTES.size(), "every save package was handed off")
|
_expect(saves.size() == Fixture.SAVE_MINUTES.size(), "every save package was handed off")
|
||||||
|
var after: Dictionary = handoff.get("after_states", {})
|
||||||
for save: Variant in saves:
|
for save: Variant in saves:
|
||||||
var minute := int((save as Dictionary).get("minute", -1))
|
var minute := int((save as Dictionary).get("minute", -1))
|
||||||
var path := Fixture.READER_SAVE % minute
|
var path := Fixture.READER_SAVE % minute
|
||||||
_expect(_write_package(save, path), "save package at minute %d arrived byte-exact" % minute)
|
_expect(_write_package(save, path), "save package at minute %d arrived byte-exact" % minute)
|
||||||
var expected_state := Marshalls.base64_to_raw(str((save as Dictionary).get("state_base64", "")))
|
var expected_state := Marshalls.base64_to_raw(str((save as Dictionary).get("state_base64", "")))
|
||||||
|
var next_row: Dictionary = after.get(str(minute + 1), {})
|
||||||
|
var next_state := Marshalls.base64_to_raw(str(next_row.get("base64", "")))
|
||||||
|
_expect(not next_state.is_empty() and Fixture.sha256(next_state) == str(next_row.get("sha256", "")), "the writer's state one minute after %d arrived intact" % minute)
|
||||||
var fixture := fixtures.new_fixture(false)
|
var fixture := fixtures.new_fixture(false)
|
||||||
var runtime: Variant = fixture[&"runtime"]
|
var runtime: Variant = fixture[&"runtime"]
|
||||||
_expect(bool(runtime.load_from_path(path).get(&"ok", false)), "the reader loads the minute %d save" % minute)
|
_expect(bool(runtime.load_from_path(path).get(&"ok", false)), "the reader loads the minute %d save" % minute)
|
||||||
_expect(fixtures.state_bytes(runtime) == expected_state and fixture[&"clock"].absolute_minute == minute, "the minute %d save resumes the writer's weather, holds, stream and plans" % minute)
|
_expect(fixtures.state_bytes(runtime) == expected_state and fixture[&"clock"].absolute_minute == minute, "the minute %d save resumes the writer's weather, holds, stream and plans" % minute)
|
||||||
|
if minute == 363:
|
||||||
|
_expect(runtime.weather.get_rain_holds() == {String(Fixture.HELD_GUEST): Fixture.HOLD} and runtime.guest_service.get_guest(Fixture.HELD_GUEST) != null
|
||||||
|
and runtime.guest_service.get_guest(Fixture.HELD_GUEST).planned_exit_at == 602, "the reader resumes the one hold of the present held guest and its extended plan")
|
||||||
# Loading replaces the event stream, so the draw counter subscribes again.
|
# Loading replaces the event stream, so the draw counter subscribes again.
|
||||||
fixture[&"draws"][&"count"] = 0
|
fixture[&"draws"][&"count"] = 0
|
||||||
fixtures.watch_draws(fixture)
|
fixtures.watch_draws(fixture)
|
||||||
fixtures.play(fixture, minute, Fixture.LAST_MINUTE, Callable())
|
fixtures.play(fixture, minute, minute + 1, Callable())
|
||||||
|
_expect(fixtures.state_bytes(runtime) == next_state, "one minute after the minute %d save the reader equals the writer (no second extension)" % minute)
|
||||||
|
fixtures.play(fixture, minute + 1, Fixture.LAST_MINUTE, Callable())
|
||||||
var expected_draws := 0
|
var expected_draws := 0
|
||||||
for draw_minute: int in Fixture.DRAW_MINUTES:
|
for draw_minute: int in Fixture.DRAW_MINUTES:
|
||||||
if draw_minute > minute:
|
if draw_minute > minute:
|
||||||
|
|||||||
@@ -238,6 +238,16 @@ func _test_rain_stay_and_saves() -> void:
|
|||||||
## itself runs at the extended time: it is not held again and begins leaving
|
## itself runs at the extended time: it is not held again and begins leaving
|
||||||
## with the ordinary PLANNED_EXIT.
|
## with the ordinary PLANNED_EXIT.
|
||||||
func _test_rain_hold_exit() -> void:
|
func _test_rain_hold_exit() -> void:
|
||||||
|
var natural := _new_runtime(SEED_RAIN)
|
||||||
|
var natural_runtime: Variant = natural[&"runtime"]
|
||||||
|
var departing: Variant = _spawn(natural_runtime, &"p07_departing_guest", &"traveler", 362)
|
||||||
|
natural[&"clock"].advance_minutes(3)
|
||||||
|
_expect(natural_runtime.weather.get_rain_hold(&"p07_departing_guest") == {"original_exit": 362, "extended_to": 602} and departing.state == GuestRuntime.State.LEAVING
|
||||||
|
and departing.exit_reason == &"NO_SUITABLE_FACILITY", "in ordinary minutes the held guest still leaves by the current rules")
|
||||||
|
natural[&"clock"].advance_minutes(1)
|
||||||
|
var departed: Dictionary = natural_runtime.create_snapshot()
|
||||||
|
_expect(natural_runtime.guest_service.get_guest(&"p07_departing_guest") == null and natural_runtime.weather.get_rain_holds().is_empty()
|
||||||
|
and natural_runtime.restore_snapshot(departed) and natural_runtime.create_snapshot() == departed, "the hold leaves with the guest, so the minute it left restores")
|
||||||
var rainy := _new_runtime(SEED_RAIN)
|
var rainy := _new_runtime(SEED_RAIN)
|
||||||
var runtime: Variant = rainy[&"runtime"]
|
var runtime: Variant = rainy[&"runtime"]
|
||||||
var guest: Variant = _spawn(runtime, &"p07_exit_guest", &"traveler", 362)
|
var guest: Variant = _spawn(runtime, &"p07_exit_guest", &"traveler", 362)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ extends RefCounted
|
|||||||
## (tests/environment/test_p07_weather_restart_2_read.gd), which run as separate
|
## (tests/environment/test_p07_weather_restart_2_read.gd), which run as separate
|
||||||
## engine processes. Seed 1106 opens day 0 with rain 06:00-12:00 (A13), a guest
|
## engine processes. Seed 1106 opens day 0 with rain 06:00-12:00 (A13), a guest
|
||||||
## due at 06:02 is held to 10:02, production arrivals run, and day 1 draws at 06:00.
|
## due at 06:02 is held to 10:02, production arrivals run, and day 1 draws at 06:00.
|
||||||
|
## With no facility in this world the held guest starts leaving at 06:03 (still
|
||||||
|
## present with its hold) and is gone at 06:04 (its hold leaves with it).
|
||||||
## The fog scene (WX7): seed 1592 opens day 0 with mana fog 06:00-10:00, two
|
## The fog scene (WX7): seed 1592 opens day 0 with mana fog 06:00-10:00, two
|
||||||
## adult-verified guests arrive at 06:58 and 09:58 (with no facility in this
|
## adult-verified guests arrive at 06:58 and 09:58 (with no facility in this
|
||||||
## world a guest leaves after a few minutes, so each one is present at its
|
## world a guest leaves after a few minutes, so each one is present at its
|
||||||
@@ -16,8 +18,10 @@ const WRITER_SAVE := "user://p07_restart_write/minute_%d"
|
|||||||
const READER_SAVE := "user://p07_restart_read/minute_%d"
|
const READER_SAVE := "user://p07_restart_read/minute_%d"
|
||||||
const SEED := 1106
|
const SEED := 1106
|
||||||
const FIRST_MINUTE := 360
|
const FIRST_MINUTE := 360
|
||||||
# Mid-rain, just before and just after the rain end, just before and just after the day 1 draw.
|
# The held guest present with its hold, the minute it left, mid-rain, just before and
|
||||||
const SAVE_MINUTES: Array[int] = [500, 719, 720, 1799, 1800]
|
# just after the rain end, just before and just after the day 1 draw.
|
||||||
|
const SAVE_MINUTES: Array[int] = [363, 364, 500, 719, 720, 1799, 1800]
|
||||||
|
const HOLD := {"original_exit": 362, "extended_to": 602}
|
||||||
const LAST_MINUTE := 1830
|
const LAST_MINUTE := 1830
|
||||||
const DRAW_MINUTES: Array[int] = [1800]
|
const DRAW_MINUTES: Array[int] = [1800]
|
||||||
const HELD_GUEST := &"p07_restart_guest"
|
const HELD_GUEST := &"p07_restart_guest"
|
||||||
|
|||||||
@@ -440,21 +440,21 @@
|
|||||||
}
|
}
|
||||||
,
|
,
|
||||||
"tests/environment/test_p07_weather_runtime.gd": {
|
"tests/environment/test_p07_weather_runtime.gd": {
|
||||||
"source_sha256": "0dfba98e091f015f74fc7897f8a7b7ce8e286826dc2a17785095ab4e0d51a946",
|
"source_sha256": "e34b52ba3511f7391de1435c2f907997dd10235742ebc029831808af969c68e0",
|
||||||
"ordinary_cleanup_prepared": false,
|
"ordinary_cleanup_prepared": false,
|
||||||
"ordinary_control_labels": [],
|
"ordinary_control_labels": [],
|
||||||
"old_bounded_teardown": true,
|
"old_bounded_teardown": true,
|
||||||
"new_audio_QA": false
|
"new_audio_QA": false
|
||||||
},
|
},
|
||||||
"tests/environment/test_p07_weather_restart_1_write.gd": {
|
"tests/environment/test_p07_weather_restart_1_write.gd": {
|
||||||
"source_sha256": "39ca0eb47eef46a5c2c73cb165b300360753ce74010b6512901c0f921d2e00a6",
|
"source_sha256": "d85e56dcf75535b19b1af615f8b75e010f4f3906a0e71afdf97102e1bfbffc65",
|
||||||
"ordinary_cleanup_prepared": false,
|
"ordinary_cleanup_prepared": false,
|
||||||
"ordinary_control_labels": [],
|
"ordinary_control_labels": [],
|
||||||
"old_bounded_teardown": false,
|
"old_bounded_teardown": false,
|
||||||
"new_audio_QA": false
|
"new_audio_QA": false
|
||||||
},
|
},
|
||||||
"tests/environment/test_p07_weather_restart_2_read.gd": {
|
"tests/environment/test_p07_weather_restart_2_read.gd": {
|
||||||
"source_sha256": "dd7c41952ced7edf38d2fbc5517128bc7b955c49ddccca90eb933062f4b8e8a7",
|
"source_sha256": "e5c2376e9cb3197d6a0a8d99c9dea020cad2648328178949cd188d999e72071a",
|
||||||
"ordinary_cleanup_prepared": false,
|
"ordinary_cleanup_prepared": false,
|
||||||
"ordinary_control_labels": [],
|
"ordinary_control_labels": [],
|
||||||
"old_bounded_teardown": false,
|
"old_bounded_teardown": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user