Save The Tree implementation and acceptance work in progress
Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
save_completed 2026-10-01T22:06:54
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"absolute_minute": 576,
|
||||
"checkpoint_reason": "manual",
|
||||
"checksum_world": "100e43372360909122e9bf4a2b1f3d19919abbbe60fa23cc29e4eca57e1a0459",
|
||||
"content_pack_ids": [],
|
||||
"created_at_real": "2026-10-01T22:06:54",
|
||||
"day": 1,
|
||||
"display_name": "manual",
|
||||
"enabled_filter_profile": "default",
|
||||
"format_version": 1,
|
||||
"game_version": "0.1.0",
|
||||
"save_id": "manual",
|
||||
"seed": 42163,
|
||||
"uncompressed_size": 158836,
|
||||
"updated_at_real": "2026-10-01T22:06:54"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 83 B |
Binary file not shown.
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"genuine_prepatch_runtime14": true,
|
||||
"strict_actual_capture_passed": true,
|
||||
"origin": "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p09-kitchen-single-link-candidate-r08/execution/proofs/legacy",
|
||||
"origin_narrow_result_sha256": "a0cb51b8bfc0e17b77b463e61871414cef4523a34485608cd471656eda7ad707",
|
||||
"origin_baseline_capture_source_sha256": "103a3d9d53de65e29d9804c89c751cca43043ab45f8e34062914da611db3aa97",
|
||||
"origin_writer": {
|
||||
"phase": "legacy-write",
|
||||
"command": [
|
||||
"/opt/homebrew/bin/godot",
|
||||
"--headless",
|
||||
"--path",
|
||||
"/private/tmp/thetree-p09-kitchen-e6c6388ec23c/stage",
|
||||
"--script",
|
||||
"res://tests/fixtures/p09/kitchen_single_link.gd",
|
||||
"--",
|
||||
"--legacy-write"
|
||||
],
|
||||
"pid": 70385,
|
||||
"exit_code": 0,
|
||||
"passed": true,
|
||||
"source_changes": [],
|
||||
"raw_sha256": "a4f2b3fcdfcf3f8d39a372e5bf68aeaa94a2cbaa13264fe006732ec8da894e5b",
|
||||
"checks": 41,
|
||||
"failures": 0,
|
||||
"parse_gate": false,
|
||||
"expected_guard_rejection91": false
|
||||
},
|
||||
"origin_reader": {
|
||||
"phase": "legacy-read",
|
||||
"command": [
|
||||
"/opt/homebrew/bin/godot",
|
||||
"--headless",
|
||||
"--path",
|
||||
"/private/tmp/thetree-p09-kitchen-e6c6388ec23c/stage",
|
||||
"--script",
|
||||
"res://tests/fixtures/p09/kitchen_single_link.gd",
|
||||
"--",
|
||||
"--legacy-read"
|
||||
],
|
||||
"pid": 70421,
|
||||
"exit_code": 0,
|
||||
"passed": true,
|
||||
"source_changes": [],
|
||||
"raw_sha256": "31547b5e2b1009a5e6e6261a44beb7c4d2ce903518de4831695e04184b79d2af",
|
||||
"checks": 49,
|
||||
"failures": 0,
|
||||
"parse_gate": false,
|
||||
"expected_guard_rejection91": false
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"path": "formal-package/world.bin",
|
||||
"sha256": "7bd0fe615790b55e09f0bf7c047a19173011f49954403c655644c5865830c13c",
|
||||
"bytes": 15405
|
||||
},
|
||||
{
|
||||
"path": "formal-package/manifest.json",
|
||||
"sha256": "4b276a7b6abad39ecfe2e43114b5637b61640a626580dce4b5871e648a182a7d",
|
||||
"bytes": 449
|
||||
},
|
||||
{
|
||||
"path": "formal-package/journal.log",
|
||||
"sha256": "defee9e7f3721ca05f4f1ba839fee8dba773a798c1b8408df31327eb19d2a1ad",
|
||||
"bytes": 35
|
||||
},
|
||||
{
|
||||
"path": "formal-package/thumbnail.png.bytes",
|
||||
"sha256": "0ef55674eca98b6748ae5ccca85a14b042c1545a143810c9c47b487119895c32",
|
||||
"bytes": 83,
|
||||
"original_formal_file": "thumbnail.png",
|
||||
"raw_byte_alias_reason": "Prevent Godot image importer from converting or remapping a genuine formal-save byte file"
|
||||
},
|
||||
{
|
||||
"path": "write-contract.var",
|
||||
"sha256": "f32e3f3c0ef44f56b4c320206f6507a4ca5074be5f7813e2f5c76a47c152b3cf",
|
||||
"bytes": 392
|
||||
},
|
||||
{
|
||||
"path": "write-checkpoint.var",
|
||||
"sha256": "a5348a17af34e717108f9ccceb215223ce48f1db1aebbd9024a9ea02c637adaf",
|
||||
"bytes": 159576
|
||||
},
|
||||
{
|
||||
"path": "write-persisted-before-io.var",
|
||||
"sha256": "6a0ba26642176c9432ce272e578764b3336731ea9b4d07ac9623f9fcdeed077a",
|
||||
"bytes": 158836
|
||||
}
|
||||
],
|
||||
"raw_cached_state": "unlinked dedicated cafeteria OPEN and meal ACTIVE elapsed5/duration45",
|
||||
"not_synthetic_current_state": true,
|
||||
"production_source_files": 1224,
|
||||
"fixture_use": "copy entire formal4 to fresh user://tests and read only; original writer slot is expected to differ from copied reader path inside complete IO1 payload substitution",
|
||||
"fixture_file_name_alias": {
|
||||
"formal-package/thumbnail.png.bytes": "formal-package/thumbnail.png"
|
||||
},
|
||||
"formal_package_bytes_unchanged": true
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+59
@@ -0,0 +1,59 @@
|
||||
extends RefCounted
|
||||
## Test-only public setup. Paid real kitchen/door; controlled model staff is
|
||||
## explicitly separate from the new candidate's normally hired/commuting UI pair.
|
||||
static func ensure(runtime: Variant, clock: Variant, cafe_id: StringName, physical_staff := true) -> Dictionary:
|
||||
var cafe: FacilityInstance = runtime.facility_service.get_instance(cafe_id)
|
||||
if cafe == null: return {&"ok": false, &"reason": &"NO_DINING_FIXTURE"}
|
||||
if not runtime.facility_service.has_method(&"get_kitchen_placement_report"): return {&"ok": false, &"reason": &"NO_PLACEMENT_REPORT"}
|
||||
var kitchen: FacilityInstance
|
||||
var build_minutes := 0
|
||||
var gold_cost := 0
|
||||
var material_cost := 0
|
||||
kitchen = _matching_kitchen(runtime, cafe_id)
|
||||
if kitchen == null:
|
||||
var definition: FacilityDefinition = runtime.definition_registry.get_facility(&"kitchen")
|
||||
var result: CommandResult = runtime.submit_command(&"build_facility", {&"definition_id": &"kitchen", &"origin": Vector3i(cafe.origin.x, cafe.origin.y, WorldService.LAYER_BACK)})
|
||||
if not result.is_success(): return {&"ok": false, &"reason": &"KITCHEN_BUILD_REJECTED", &"details": result.details}
|
||||
build_minutes = definition.build_minutes
|
||||
gold_cost += int(definition.construction_cost.get(&"gold", 0))
|
||||
material_cost += int(definition.construction_cost.get(&"materials", 0))
|
||||
var has_door := false
|
||||
for facility: Dictionary in runtime.construction_service.get_facilities():
|
||||
has_door = has_door or facility[&"definition_id"] == &"staff_door"
|
||||
if not has_door:
|
||||
var definition: FacilityDefinition = runtime.definition_registry.get_facility(&"staff_door")
|
||||
var result: CommandResult = runtime.submit_command(&"build_facility", {&"definition_id": &"staff_door", &"origin": Vector3i(0, 0, WorldService.LAYER_BACK)})
|
||||
if not result.is_success(): return {&"ok": false, &"reason": &"DOOR_BUILD_REJECTED", &"details": result.details}
|
||||
build_minutes = maxi(build_minutes, definition.build_minutes)
|
||||
gold_cost += int(definition.construction_cost.get(&"gold", 0))
|
||||
material_cost += int(definition.construction_cost.get(&"materials", 0))
|
||||
if build_minutes > 0: clock.advance_minutes(build_minutes)
|
||||
if kitchen == null:
|
||||
kitchen = _matching_kitchen(runtime, cafe_id)
|
||||
if kitchen == null: return {&"ok": false, &"reason": &"KITCHEN_NOT_COMPLETE"}
|
||||
var worker_id := StringName("fixture.kitchen.worker.%s" % cafe_id)
|
||||
if physical_staff:
|
||||
var registered: CommandResult = runtime.submit_command(&"register_staff", {&"staff_id": worker_id, &"role_id": &"cook", &"options": {&"state": StaffRuntime.State.OFF_DUTY, &"current_cell": kitchen.origin, &"role_tags": [&"cook"], &"permitted_task_tags": [&"cooking", &"work"], &"skills": {&"operation": 50}}})
|
||||
if not registered.is_success(): return {&"ok": false, &"reason": &"WORKER_REGISTER_REJECTED", &"details": registered.details}
|
||||
var minute: int = posmod(clock.absolute_minute, 1440)
|
||||
var shift: CommandResult = runtime.submit_command(&"create_staff_shift", {&"staff_id": worker_id, &"template_id": &"FLEX", &"start_day": clock.absolute_minute / 1440, &"start_minute_of_day": minute, &"end_minute_of_day": 1439, &"facility_id": kitchen.instance_id})
|
||||
if not shift.is_success(): return {&"ok": false, &"reason": &"WORKER_SHIFT_REJECTED", &"details": shift.details}
|
||||
clock.advance_one_minute()
|
||||
else:
|
||||
# Preserve the existing S2/business legacy logical-attendance test contract;
|
||||
# Only logical attendance is set here: registering a physical staff actor
|
||||
# would enable Runtime projection and erase the old model staff on tick.
|
||||
# This is a controlled public command fixture, not genuine hired commute.
|
||||
var staffed: CommandResult = runtime.submit_command(&"set_facility_conditions", {&"facility_id": kitchen.instance_id, &"conditions": {&"active_staff_ids": [worker_id]}})
|
||||
if not staffed.is_success(): return {&"ok": false, &"reason": &"LOGICAL_STAFF_REJECTED"}
|
||||
var linked: CommandResult = runtime.submit_command(&"set_facility_conditions", {&"facility_id": cafe_id, &"conditions": {&"related_facility_id": kitchen.instance_id}})
|
||||
return {&"ok": linked.is_success() and cafe.related_facility_operating, &"reason": &"" if linked.is_success() else &"LINK_REJECTED", &"kitchen_id": kitchen.instance_id, &"worker_id": worker_id, &"gold_cost": gold_cost, &"material_cost": material_cost, &"physical_staff": physical_staff}
|
||||
|
||||
# A geometrically valid, non-suspended kitchen may be staffed by this controlled
|
||||
# fixture. Being merely BACK or already available elsewhere is not eligibility.
|
||||
static func _matching_kitchen(runtime: Variant, cafe_id: StringName) -> FacilityInstance:
|
||||
for instance: FacilityInstance in runtime.facility_service.get_instances():
|
||||
var report: Dictionary = runtime.facility_service.get_kitchen_placement_report(cafe_id, instance.instance_id)
|
||||
if bool(report.get(&"valid_placement", false)) and instance.suspension_reason.is_empty():
|
||||
return instance
|
||||
return null
|
||||
@@ -0,0 +1 @@
|
||||
uid://mpwmij1rsash
|
||||
Reference in New Issue
Block a user