Make locomotive context save-native

This commit is contained in:
Jan Petykiewicz 2026-04-16 12:18:13 -07:00
commit b060c42fa2
18 changed files with 1240 additions and 83 deletions

View file

@ -3,7 +3,7 @@
"fixture_id": "packed-event-locomotive-availability-missing-catalog-save-slice-fixture",
"source": {
"kind": "captured-runtime",
"description": "Fixture backed by a tracked save-slice document that leaves a scalar locomotive availability row blocked until overlay-backed catalog context is supplied."
"description": "Fixture backed by a tracked save-slice document that leaves a scalar locomotive availability row blocked until save-derived or embedded catalog context is supplied."
},
"state_save_slice_path": "packed-event-locomotive-availability-missing-catalog-save-slice.json",
"commands": [

View file

@ -2,7 +2,7 @@
"format_version": 1,
"save_slice_id": "packed-event-locomotive-availability-missing-catalog-save-slice",
"source": {
"description": "Tracked save-slice document proving scalar locomotive availability rows stay parity-only without overlay-backed locomotive catalog context.",
"description": "Tracked save-slice document proving scalar locomotive availability rows stay parity-only when the save slice lacks enough locomotive catalog context.",
"original_save_filename": "captured-locomotive-availability-missing-catalog.gms",
"original_save_sha256": "locomotive-availability-missing-catalog-sample-sha256",
"notes": [
@ -89,7 +89,7 @@
"decoded_actions": [],
"executable_import_ready": false,
"notes": [
"scalar locomotive availability row still requires overlay-backed locomotive catalog context"
"scalar locomotive availability row still requires locomotive catalog context that this save slice does not carry"
]
}
]

View file

@ -0,0 +1,53 @@
{
"format_version": 1,
"fixture_id": "packed-event-locomotive-availability-save-slice-fixture",
"source": {
"kind": "captured-runtime",
"description": "Fixture backed by a tracked save-slice document that imports recovered scalar locomotive availability descriptors through embedded locomotive catalog context."
},
"state_save_slice_path": "packed-event-locomotive-availability-save-slice.json",
"commands": [
{
"kind": "service_trigger_kind",
"trigger_kind": 7
}
],
"expected_summary": {
"calendar_projection_is_placeholder": true,
"locomotive_catalog_count": 2,
"packed_event_collection_present": true,
"packed_event_record_count": 1,
"packed_event_decoded_record_count": 1,
"packed_event_imported_runtime_record_count": 1,
"event_runtime_record_count": 1,
"named_locomotive_availability_count": 2,
"zero_named_locomotive_availability_count": 0,
"total_event_record_service_count": 1,
"total_trigger_dispatch_count": 1,
"dirty_rerun_count": 0
},
"expected_state_fragment": {
"metadata": {
"save_slice.locomotive_catalog_source_kind": "save-direct-locomotive-row-run-ordinal-catalog"
},
"named_locomotive_availability": {
"Locomotive 10": 42,
"Locomotive 112": 7
},
"packed_event_collection": {
"live_entry_ids": [33],
"records": [
{
"decode_status": "parity_only",
"import_outcome": "imported"
}
]
},
"event_runtime_records": [
{
"record_id": 33,
"service_count": 1
}
]
}
}

View file

@ -0,0 +1,133 @@
{
"format_version": 1,
"save_slice_id": "packed-event-locomotive-availability-save-slice",
"source": {
"description": "Tracked save-slice document proving recovered scalar locomotive availability descriptors import through embedded save-native locomotive catalog context.",
"original_save_filename": "captured-locomotive-availability-save-slice.gms",
"original_save_sha256": "locomotive-availability-save-slice-sample-sha256",
"notes": [
"tracked as JSON save-slice document rather than raw .smp",
"uses embedded save-native locomotive catalog entries to prove standalone save-slice execution for lower-band and upper-band locomotive availability descriptors"
]
},
"save_slice": {
"file_extension_hint": "gms",
"container_profile_family": "rt3-classic-save-container-v1",
"mechanism_family": "classic-save-rehydrate-v1",
"mechanism_confidence": "grounded",
"trailer_family": null,
"bridge_family": null,
"profile": null,
"candidate_availability_table": null,
"named_locomotive_availability_table": null,
"locomotive_catalog": {
"source_kind": "save-direct-locomotive-row-run-ordinal-catalog",
"semantic_family": "scenario-save-derived-locomotive-catalog",
"entries_offset": 31864,
"observed_entry_count": 2,
"entries": [
{ "locomotive_id": 10, "name": "Locomotive 10" },
{ "locomotive_id": 112, "name": "Locomotive 112" }
]
},
"special_conditions_table": null,
"event_runtime_collection": {
"source_kind": "packed-event-runtime-collection",
"mechanism_family": "classic-save-rehydrate-v1",
"mechanism_confidence": "grounded",
"container_profile_family": "rt3-classic-save-container-v1",
"metadata_tag_offset": 28928,
"records_tag_offset": 29184,
"close_tag_offset": 29696,
"packed_state_version": 1001,
"packed_state_version_hex": "0x000003e9",
"live_id_bound": 33,
"live_record_count": 1,
"live_entry_ids": [33],
"decoded_record_count": 1,
"imported_runtime_record_count": 1,
"records": [
{
"record_index": 0,
"live_entry_id": 33,
"payload_offset": 29186,
"payload_len": 120,
"decode_status": "parity_only",
"payload_family": "real_packed_v1",
"trigger_kind": 7,
"one_shot": false,
"compact_control": {
"mode_byte_0x7ef": 7,
"primary_selector_0x7f0": 0,
"grouped_mode_0x7f4": 2,
"one_shot_header_0x7f5": 0,
"modifier_flag_0x7f9": 0,
"modifier_flag_0x7fa": 0,
"grouped_target_scope_ordinals_0x7fb": [0, 0, 0, 0],
"grouped_scope_checkboxes_0x7ff": [1, 0, 0, 0],
"summary_toggle_0x800": 1,
"grouped_territory_selectors_0x80f": [-1, -1, -1, -1]
},
"text_bands": [],
"standalone_condition_row_count": 0,
"standalone_condition_rows": [],
"grouped_effect_row_counts": [2, 0, 0, 0],
"grouped_effect_rows": [
{
"group_index": 0,
"row_index": 0,
"descriptor_id": 250,
"descriptor_label": "Unknown Loco Available",
"target_mask_bits": 8,
"parameter_family": "locomotive_availability_scalar",
"opcode": 3,
"raw_scalar_value": 42,
"value_byte_0x09": 0,
"value_dword_0x0d": 0,
"value_byte_0x11": 0,
"value_byte_0x12": 0,
"value_word_0x14": 0,
"value_word_0x16": 0,
"row_shape": "scalar_assignment",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Unknown Loco Available to 42",
"recovered_locomotive_id": 10,
"locomotive_name": null,
"notes": []
},
{
"group_index": 0,
"row_index": 1,
"descriptor_id": 457,
"descriptor_label": "Unknown Loco Available",
"target_mask_bits": 8,
"parameter_family": "locomotive_availability_scalar",
"opcode": 3,
"raw_scalar_value": 7,
"value_byte_0x09": 0,
"value_dword_0x0d": 0,
"value_byte_0x11": 0,
"value_byte_0x12": 0,
"value_word_0x14": 0,
"value_word_0x16": 0,
"row_shape": "scalar_assignment",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Unknown Loco Available to 7",
"recovered_locomotive_id": 112,
"locomotive_name": null,
"notes": []
}
],
"decoded_actions": [],
"executable_import_ready": false,
"notes": [
"scalar locomotive availability rows use save-native catalog context"
]
}
]
},
"notes": [
"save-slice-backed locomotive availability effect sample"
]
}
}

View file

@ -0,0 +1,52 @@
{
"format_version": 1,
"fixture_id": "packed-event-locomotive-cost-save-slice-fixture",
"source": {
"kind": "captured-runtime",
"description": "Fixture backed by a tracked save-slice document that imports recovered scalar locomotive cost descriptors through embedded locomotive catalog context."
},
"state_save_slice_path": "packed-event-locomotive-cost-save-slice.json",
"commands": [
{
"kind": "service_trigger_kind",
"trigger_kind": 7
}
],
"expected_summary": {
"calendar_projection_is_placeholder": true,
"locomotive_catalog_count": 2,
"packed_event_collection_present": true,
"packed_event_record_count": 1,
"packed_event_decoded_record_count": 1,
"packed_event_imported_runtime_record_count": 1,
"event_runtime_record_count": 1,
"named_locomotive_cost_count": 2,
"total_event_record_service_count": 1,
"total_trigger_dispatch_count": 1,
"dirty_rerun_count": 0
},
"expected_state_fragment": {
"metadata": {
"save_slice.locomotive_catalog_source_kind": "save-direct-locomotive-row-run-ordinal-catalog"
},
"named_locomotive_cost": {
"Locomotive 1": 250000,
"Locomotive 101": 325000
},
"packed_event_collection": {
"live_entry_ids": [41],
"records": [
{
"decode_status": "parity_only",
"import_outcome": "imported"
}
]
},
"event_runtime_records": [
{
"record_id": 41,
"service_count": 1
}
]
}
}

View file

@ -0,0 +1,150 @@
{
"format_version": 1,
"save_slice_id": "packed-event-locomotive-cost-save-slice",
"source": {
"description": "Tracked save-slice document proving recovered scalar locomotive cost descriptors import through embedded save-native locomotive catalog context.",
"original_save_filename": "captured-locomotive-cost-save-slice.gms",
"original_save_sha256": "locomotive-cost-save-slice-sample-sha256",
"notes": [
"tracked as JSON save-slice document rather than raw .smp",
"uses embedded save-native locomotive catalog entries to prove standalone save-slice execution for lower-band and upper-band locomotive cost descriptors"
]
},
"save_slice": {
"file_extension_hint": "gms",
"container_profile_family": "rt3-classic-save-container-v1",
"mechanism_family": "classic-save-rehydrate-v1",
"mechanism_confidence": "grounded",
"trailer_family": null,
"bridge_family": null,
"profile": null,
"candidate_availability_table": null,
"named_locomotive_availability_table": null,
"locomotive_catalog": {
"source_kind": "save-direct-locomotive-row-run-ordinal-catalog",
"semantic_family": "scenario-save-derived-locomotive-catalog",
"entries_offset": 31864,
"observed_entry_count": 2,
"entries": [
{ "locomotive_id": 1, "name": "Locomotive 1" },
{ "locomotive_id": 101, "name": "Locomotive 101" }
]
},
"special_conditions_table": null,
"event_runtime_collection": {
"source_kind": "packed-event-runtime-collection",
"mechanism_family": "classic-save-rehydrate-v1",
"mechanism_confidence": "grounded",
"container_profile_family": "rt3-classic-save-container-v1",
"metadata_tag_offset": 29952,
"records_tag_offset": 30208,
"close_tag_offset": 30976,
"packed_state_version": 1001,
"packed_state_version_hex": "0x000003e9",
"live_id_bound": 41,
"live_record_count": 1,
"live_entry_ids": [41],
"decoded_record_count": 1,
"imported_runtime_record_count": 1,
"records": [
{
"record_index": 0,
"live_entry_id": 41,
"payload_offset": 30240,
"payload_len": 120,
"decode_status": "parity_only",
"payload_family": "real_packed_v1",
"trigger_kind": 7,
"one_shot": false,
"compact_control": {
"mode_byte_0x7ef": 7,
"primary_selector_0x7f0": 0,
"grouped_mode_0x7f4": 2,
"one_shot_header_0x7f5": 0,
"modifier_flag_0x7f9": 0,
"modifier_flag_0x7fa": 0,
"grouped_target_scope_ordinals_0x7fb": [0, 0, 0, 0],
"grouped_scope_checkboxes_0x7ff": [1, 0, 0, 0],
"summary_toggle_0x800": 1,
"grouped_territory_selectors_0x80f": [-1, -1, -1, -1]
},
"text_bands": [],
"standalone_condition_row_count": 0,
"standalone_condition_rows": [],
"negative_sentinel_scope": null,
"grouped_effect_row_counts": [2, 0, 0, 0],
"grouped_effect_rows": [
{
"group_index": 0,
"row_index": 0,
"descriptor_id": 352,
"descriptor_label": "Locomotive 1 Cost",
"target_mask_bits": 8,
"parameter_family": "locomotive_cost_scalar",
"opcode": 3,
"raw_scalar_value": 250000,
"value_byte_0x09": 0,
"value_dword_0x0d": 0,
"value_byte_0x11": 0,
"value_byte_0x12": 0,
"value_word_0x14": 0,
"value_word_0x16": 0,
"row_shape": "scalar_assignment",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Locomotive 1 Cost to 250000",
"recovered_locomotive_id": 1,
"locomotive_name": null,
"notes": [
"locomotive cost descriptor maps to live locomotive id 1"
]
},
{
"group_index": 0,
"row_index": 1,
"descriptor_id": 475,
"descriptor_label": "Locomotive 101 Cost",
"target_mask_bits": 8,
"parameter_family": "locomotive_cost_scalar",
"opcode": 3,
"raw_scalar_value": 325000,
"value_byte_0x09": 0,
"value_dword_0x0d": 0,
"value_byte_0x11": 0,
"value_byte_0x12": 0,
"value_word_0x14": 0,
"value_word_0x16": 0,
"row_shape": "scalar_assignment",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Locomotive 101 Cost to 325000",
"recovered_locomotive_id": 101,
"locomotive_name": null,
"notes": [
"locomotive cost descriptor maps to live locomotive id 101"
]
}
],
"decoded_conditions": [],
"decoded_actions": [
{
"kind": "set_named_locomotive_cost",
"name": "Locomotive 1",
"value": 250000
},
{
"kind": "set_named_locomotive_cost",
"name": "Locomotive 101",
"value": 325000
}
],
"executable_import_ready": false,
"notes": [
"scalar locomotive cost rows use save-native catalog context"
]
}
]
},
"notes": [
"save-slice-backed locomotive cost effect sample"
]
}
}

View file

@ -20,20 +20,21 @@
"tick_slot": 1
},
"calendar_projection_is_placeholder": true,
"locomotive_catalog_count": 10,
"packed_event_collection_present": true,
"packed_event_record_count": 2,
"packed_event_decoded_record_count": 2,
"packed_event_imported_runtime_record_count": 1,
"packed_event_imported_runtime_record_count": 2,
"packed_event_parity_only_record_count": 2,
"packed_event_unsupported_record_count": 0,
"packed_event_blocked_missing_locomotive_catalog_context_count": 1,
"packed_event_blocked_missing_locomotive_catalog_context_count": 0,
"packed_event_blocked_missing_condition_context_count": 0,
"packed_event_blocked_territory_condition_scope_count": 0,
"packed_event_blocked_missing_compact_control_count": 0,
"packed_event_blocked_unmapped_real_descriptor_count": 0,
"packed_event_blocked_unmapped_world_descriptor_count": 0,
"packed_event_blocked_structural_only_count": 0,
"event_runtime_record_count": 1,
"event_runtime_record_count": 2,
"total_company_cash": 0
},
"expected_state_fragment": {
@ -49,7 +50,7 @@
{
"decode_status": "parity_only",
"payload_family": "real_packed_v1",
"import_outcome": "blocked_missing_locomotive_catalog_context",
"import_outcome": "imported",
"grouped_effect_rows": [
{
"descriptor_id": 250,

View file

@ -7,7 +7,7 @@
"original_save_sha256": "parity-sample-sha256",
"notes": [
"tracked as JSON save-slice document rather than raw .smp",
"preserves one recovered scalar locomotive-availability row that still needs overlay-backed catalog context and one semantically decoded imported row"
"preserves one recovered scalar locomotive-availability row that now imports through save-native locomotive catalog context and one semantically decoded imported row"
]
},
"save_slice": {
@ -19,6 +19,24 @@
"bridge_family": null,
"profile": null,
"candidate_availability_table": null,
"locomotive_catalog": {
"source_kind": "save-direct-locomotive-row-run-ordinal-catalog",
"semantic_family": "scenario-save-derived-locomotive-catalog",
"entries_offset": 31864,
"observed_entry_count": 10,
"entries": [
{ "locomotive_id": 1, "name": "Locomotive 1" },
{ "locomotive_id": 2, "name": "Locomotive 2" },
{ "locomotive_id": 3, "name": "Locomotive 3" },
{ "locomotive_id": 4, "name": "Locomotive 4" },
{ "locomotive_id": 5, "name": "Locomotive 5" },
{ "locomotive_id": 6, "name": "Locomotive 6" },
{ "locomotive_id": 7, "name": "Locomotive 7" },
{ "locomotive_id": 8, "name": "Locomotive 8" },
{ "locomotive_id": 9, "name": "Locomotive 9" },
{ "locomotive_id": 10, "name": "Locomotive 10" }
]
},
"special_conditions_table": null,
"event_runtime_collection": {
"source_kind": "packed-event-runtime-collection",
@ -34,7 +52,7 @@
"live_record_count": 2,
"live_entry_ids": [3, 5],
"decoded_record_count": 2,
"imported_runtime_record_count": 1,
"imported_runtime_record_count": 2,
"records": [
{
"record_index": 0,
@ -83,7 +101,7 @@
"recovered_locomotive_id": 10,
"locomotive_name": null,
"notes": [
"recovered locomotive availability descriptor family now supports scalar payloads, but standalone save-slice import still needs overlay-backed locomotive catalog context"
"recovered locomotive availability descriptor family now imports through save-native locomotive catalog context"
]
}
],
@ -91,7 +109,7 @@
"executable_import_ready": false,
"notes": [
"decoded from grounded real 0x4e9a row framing",
"recovered locomotives-page descriptor band is now checked in, and this scalar family can import through named locomotive availability overrides once overlay-backed locomotive catalog context is present"
"recovered locomotives-page descriptor band is now checked in, and this scalar family now imports through named locomotive availability overrides when the save slice carries locomotive catalog context"
]
},
{

View file

@ -21,7 +21,7 @@
},
"calendar_projection_source": "base-snapshot-preserved",
"calendar_projection_is_placeholder": false,
"world_flag_count": 8,
"world_flag_count": 9,
"company_count": 1,
"packed_event_collection_present": true,
"packed_event_record_count": 2,

View file

@ -3,7 +3,7 @@
"fixture_id": "packed-event-world-scalar-band-parity-save-slice-fixture",
"source": {
"kind": "captured-runtime",
"description": "Fixture backed by a tracked save-slice document that mixes executable scalar world descriptors with one remaining missing-catalog frontier."
"description": "Fixture backed by a tracked save-slice document that mixes executable scalar world descriptors with one remaining intentionally unsupported scalar frontier."
},
"state_save_slice_path": "packed-event-world-scalar-band-parity-save-slice.json",
"commands": [
@ -26,12 +26,12 @@
"packed_event_imported_runtime_record_count": 2,
"packed_event_parity_only_record_count": 3,
"packed_event_unsupported_record_count": 0,
"packed_event_blocked_missing_locomotive_catalog_context_count": 1,
"packed_event_blocked_missing_locomotive_catalog_context_count": 0,
"packed_event_blocked_missing_condition_context_count": 0,
"packed_event_blocked_territory_condition_scope_count": 0,
"packed_event_blocked_missing_compact_control_count": 0,
"packed_event_blocked_unmapped_real_descriptor_count": 0,
"packed_event_blocked_unmapped_world_descriptor_count": 0,
"packed_event_blocked_unmapped_world_descriptor_count": 1,
"packed_event_blocked_structural_only_count": 0,
"event_runtime_record_count": 2,
"cargo_production_override_count": 0,
@ -63,7 +63,7 @@
{
"decode_status": "parity_only",
"payload_family": "real_packed_v1",
"import_outcome": "blocked_missing_locomotive_catalog_context",
"import_outcome": "blocked_unmapped_world_descriptor",
"grouped_effect_rows": [
{
"descriptor_id": 352,
@ -71,7 +71,7 @@
"target_mask_bits": 8,
"parameter_family": "locomotive_cost_scalar",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Locomotive 1 Cost to 250000",
"semantic_preview": "Set Locomotive 1 Cost to -250000",
"recovered_locomotive_id": 1,
"row_shape": "scalar_assignment"
}

View file

@ -7,7 +7,7 @@
"original_save_sha256": "world-scalar-band-parity-sample-sha256",
"notes": [
"tracked as JSON save-slice document rather than raw .smp",
"covers recovered cargo production, locomotive cost, and territory access cost families with one remaining missing-catalog frontier"
"covers recovered cargo production, locomotive cost, and territory access cost families with one remaining intentionally unsupported scalar frontier"
]
},
"save_slice": {
@ -35,7 +35,7 @@
"live_record_count": 3,
"live_entry_ids": [11, 12, 13],
"decoded_record_count": 3,
"imported_runtime_record_count": 0,
"imported_runtime_record_count": 2,
"records": [
{
"record_index": 0,
@ -126,7 +126,7 @@
"target_mask_bits": 8,
"parameter_family": "locomotive_cost_scalar",
"opcode": 3,
"raw_scalar_value": 250000,
"raw_scalar_value": -250000,
"value_byte_0x09": 0,
"value_dword_0x0d": 0,
"value_byte_0x11": 0,
@ -135,7 +135,7 @@
"value_word_0x16": 0,
"row_shape": "scalar_assignment",
"semantic_family": "scalar_assignment",
"semantic_preview": "Set Locomotive 1 Cost to 250000",
"semantic_preview": "Set Locomotive 1 Cost to -250000",
"recovered_locomotive_id": 1,
"locomotive_name": null,
"notes": [
@ -146,7 +146,7 @@
"decoded_actions": [],
"executable_import_ready": false,
"notes": [
"recovered locomotive cost metadata is now checked in, but scalar rows still need overlay-backed locomotive catalog context to import"
"negative locomotive cost payload remains intentionally unsupported even though the descriptor family is recovered"
]
},
{