Recover scalar-band packed event metadata
This commit is contained in:
parent
87108f357b
commit
e2174713a9
8 changed files with 685 additions and 39 deletions
|
|
@ -54,7 +54,9 @@ through checked-in metadata into keyed `world_flags`, while the wider locomotive
|
||||||
scalar bands are now split more cleanly: the boolean `0/1` availability subset can import through
|
scalar bands are now split more cleanly: the boolean `0/1` availability subset can import through
|
||||||
an overlay-backed `RuntimeState.locomotive_catalog` into
|
an overlay-backed `RuntimeState.locomotive_catalog` into
|
||||||
`RuntimeState.named_locomotive_availability`, while non-boolean availability payloads plus the
|
`RuntimeState.named_locomotive_availability`, while non-boolean availability payloads plus the
|
||||||
locomotive-cost/cargo-production/territory-access-cost families remain recovered-but-parity-only.
|
locomotive-cost/cargo-production/territory-access-cost families now surface as recovered,
|
||||||
|
metadata-rich parity rows with checked-in slot labels and locomotive ids where grounded, but they
|
||||||
|
still remain non-executable.
|
||||||
The runtime still carries the save-owned named locomotive availability table directly too:
|
The runtime still carries the save-owned named locomotive availability table directly too:
|
||||||
checked-in save-slice documents can populate `RuntimeState.named_locomotive_availability`, and
|
checked-in save-slice documents can populate `RuntimeState.named_locomotive_availability`, and
|
||||||
imported runtime effects can mutate that map through the ordinary event-service path without
|
imported runtime effects can mutate that map through the ordinary event-service path without
|
||||||
|
|
|
||||||
|
|
@ -4463,6 +4463,9 @@ mod tests {
|
||||||
let overlay_locomotive_fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(
|
let overlay_locomotive_fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(
|
||||||
"../../fixtures/runtime/packed-event-locomotive-availability-overlay-fixture.json",
|
"../../fixtures/runtime/packed-event-locomotive-availability-overlay-fixture.json",
|
||||||
);
|
);
|
||||||
|
let scalar_band_parity_fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(
|
||||||
|
"../../fixtures/runtime/packed-event-world-scalar-band-parity-save-slice-fixture.json",
|
||||||
|
);
|
||||||
|
|
||||||
run_runtime_summarize_fixture(&parity_fixture)
|
run_runtime_summarize_fixture(&parity_fixture)
|
||||||
.expect("save-slice-backed parity fixture should summarize");
|
.expect("save-slice-backed parity fixture should summarize");
|
||||||
|
|
@ -4487,6 +4490,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
run_runtime_summarize_fixture(&overlay_locomotive_fixture)
|
run_runtime_summarize_fixture(&overlay_locomotive_fixture)
|
||||||
.expect("overlay-backed locomotive availability fixture should summarize");
|
.expect("overlay-backed locomotive availability fixture should summarize");
|
||||||
|
run_runtime_summarize_fixture(&scalar_band_parity_fixture)
|
||||||
|
.expect("save-slice-backed recovered scalar-band parity fixture should summarize");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -3070,11 +3070,19 @@ mod tests {
|
||||||
descriptor_id: u32,
|
descriptor_id: u32,
|
||||||
value: i32,
|
value: i32,
|
||||||
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
let recovered_locomotive_id = match descriptor_id {
|
||||||
|
352..=451 => Some(descriptor_id - 351),
|
||||||
|
475..=500 => Some(descriptor_id - 374),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let descriptor_label = recovered_locomotive_id
|
||||||
|
.map(|loco_id| format!("Locomotive {loco_id} Cost"))
|
||||||
|
.unwrap_or_else(|| "Locomotive Cost".to_string());
|
||||||
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_index: 0,
|
row_index: 0,
|
||||||
descriptor_id,
|
descriptor_id,
|
||||||
descriptor_label: Some("Unknown Loco Cost".to_string()),
|
descriptor_label: Some(descriptor_label.clone()),
|
||||||
target_mask_bits: Some(0x08),
|
target_mask_bits: Some(0x08),
|
||||||
parameter_family: Some("locomotive_cost_scalar".to_string()),
|
parameter_family: Some("locomotive_cost_scalar".to_string()),
|
||||||
opcode: 3,
|
opcode: 3,
|
||||||
|
|
@ -3087,12 +3095,65 @@ mod tests {
|
||||||
value_word_0x16: 0,
|
value_word_0x16: 0,
|
||||||
row_shape: "scalar_assignment".to_string(),
|
row_shape: "scalar_assignment".to_string(),
|
||||||
semantic_family: Some("scalar_assignment".to_string()),
|
semantic_family: Some("scalar_assignment".to_string()),
|
||||||
semantic_preview: Some(format!("Set Unknown Loco Cost to {value}")),
|
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||||
recovered_locomotive_id: match descriptor_id {
|
recovered_locomotive_id,
|
||||||
352..=451 => Some(descriptor_id - 351),
|
locomotive_name: None,
|
||||||
475..=500 => Some(descriptor_id - 374),
|
notes: vec![],
|
||||||
_ => None,
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
fn real_cargo_production_row(
|
||||||
|
descriptor_id: u32,
|
||||||
|
value: i32,
|
||||||
|
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
let slot = descriptor_id.saturating_sub(229);
|
||||||
|
let descriptor_label = format!("Cargo Production Slot {slot}");
|
||||||
|
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
group_index: 0,
|
||||||
|
row_index: 0,
|
||||||
|
descriptor_id,
|
||||||
|
descriptor_label: Some(descriptor_label.clone()),
|
||||||
|
target_mask_bits: Some(0x08),
|
||||||
|
parameter_family: Some("cargo_production_scalar".to_string()),
|
||||||
|
opcode: 3,
|
||||||
|
raw_scalar_value: value,
|
||||||
|
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".to_string(),
|
||||||
|
semantic_family: Some("scalar_assignment".to_string()),
|
||||||
|
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||||
|
recovered_locomotive_id: None,
|
||||||
|
locomotive_name: None,
|
||||||
|
notes: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn real_territory_access_cost_row(
|
||||||
|
value: i32,
|
||||||
|
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
group_index: 0,
|
||||||
|
row_index: 0,
|
||||||
|
descriptor_id: 453,
|
||||||
|
descriptor_label: Some("Territory Access Cost".to_string()),
|
||||||
|
target_mask_bits: Some(0x08),
|
||||||
|
parameter_family: Some("territory_access_cost_scalar".to_string()),
|
||||||
|
opcode: 3,
|
||||||
|
raw_scalar_value: value,
|
||||||
|
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".to_string(),
|
||||||
|
semantic_family: Some("scalar_assignment".to_string()),
|
||||||
|
semantic_preview: Some(format!("Set Territory Access Cost to {value}")),
|
||||||
|
recovered_locomotive_id: None,
|
||||||
locomotive_name: None,
|
locomotive_name: None,
|
||||||
notes: vec![],
|
notes: vec![],
|
||||||
}
|
}
|
||||||
|
|
@ -5155,6 +5216,152 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keeps_recovered_cargo_production_rows_parity_only() {
|
||||||
|
let save_slice = SmpLoadedSaveSlice {
|
||||||
|
file_extension_hint: Some("gms".to_string()),
|
||||||
|
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||||
|
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||||
|
mechanism_confidence: "grounded".to_string(),
|
||||||
|
trailer_family: None,
|
||||||
|
bridge_family: None,
|
||||||
|
profile: None,
|
||||||
|
candidate_availability_table: None,
|
||||||
|
named_locomotive_availability_table: None,
|
||||||
|
special_conditions_table: None,
|
||||||
|
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||||
|
source_kind: "packed-event-runtime-collection".to_string(),
|
||||||
|
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||||
|
mechanism_confidence: "grounded".to_string(),
|
||||||
|
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||||
|
metadata_tag_offset: 0x7100,
|
||||||
|
records_tag_offset: 0x7200,
|
||||||
|
close_tag_offset: 0x7600,
|
||||||
|
packed_state_version: 0x3e9,
|
||||||
|
packed_state_version_hex: "0x000003e9".to_string(),
|
||||||
|
live_id_bound: 35,
|
||||||
|
live_record_count: 1,
|
||||||
|
live_entry_ids: vec![35],
|
||||||
|
decoded_record_count: 1,
|
||||||
|
imported_runtime_record_count: 0,
|
||||||
|
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||||
|
record_index: 0,
|
||||||
|
live_entry_id: 35,
|
||||||
|
payload_offset: Some(0x7202),
|
||||||
|
payload_len: Some(96),
|
||||||
|
decode_status: "parity_only".to_string(),
|
||||||
|
payload_family: "real_packed_v1".to_string(),
|
||||||
|
trigger_kind: Some(7),
|
||||||
|
active: None,
|
||||||
|
marks_collection_dirty: None,
|
||||||
|
one_shot: Some(false),
|
||||||
|
compact_control: Some(real_compact_control()),
|
||||||
|
text_bands: vec![],
|
||||||
|
standalone_condition_row_count: 0,
|
||||||
|
standalone_condition_rows: vec![],
|
||||||
|
negative_sentinel_scope: None,
|
||||||
|
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||||
|
grouped_effect_rows: vec![real_cargo_production_row(230, 125)],
|
||||||
|
decoded_conditions: Vec::new(),
|
||||||
|
decoded_actions: vec![],
|
||||||
|
executable_import_ready: false,
|
||||||
|
notes: vec!["cargo production rows remain metadata-only".to_string()],
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
notes: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let import = project_save_slice_to_runtime_state_import(
|
||||||
|
&save_slice,
|
||||||
|
"packed-events-cargo-production-frontier",
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.expect("save slice should project");
|
||||||
|
|
||||||
|
assert!(import.state.event_runtime_records.is_empty());
|
||||||
|
assert_eq!(
|
||||||
|
import
|
||||||
|
.state
|
||||||
|
.packed_event_collection
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||||
|
Some("blocked_unmapped_world_descriptor")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keeps_recovered_territory_access_cost_rows_parity_only() {
|
||||||
|
let save_slice = SmpLoadedSaveSlice {
|
||||||
|
file_extension_hint: Some("gms".to_string()),
|
||||||
|
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||||
|
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||||
|
mechanism_confidence: "grounded".to_string(),
|
||||||
|
trailer_family: None,
|
||||||
|
bridge_family: None,
|
||||||
|
profile: None,
|
||||||
|
candidate_availability_table: None,
|
||||||
|
named_locomotive_availability_table: None,
|
||||||
|
special_conditions_table: None,
|
||||||
|
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||||
|
source_kind: "packed-event-runtime-collection".to_string(),
|
||||||
|
mechanism_family: "classic-save-rehydrate-v1".to_string(),
|
||||||
|
mechanism_confidence: "grounded".to_string(),
|
||||||
|
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||||
|
metadata_tag_offset: 0x7100,
|
||||||
|
records_tag_offset: 0x7200,
|
||||||
|
close_tag_offset: 0x7600,
|
||||||
|
packed_state_version: 0x3e9,
|
||||||
|
packed_state_version_hex: "0x000003e9".to_string(),
|
||||||
|
live_id_bound: 36,
|
||||||
|
live_record_count: 1,
|
||||||
|
live_entry_ids: vec![36],
|
||||||
|
decoded_record_count: 1,
|
||||||
|
imported_runtime_record_count: 0,
|
||||||
|
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||||
|
record_index: 0,
|
||||||
|
live_entry_id: 36,
|
||||||
|
payload_offset: Some(0x7202),
|
||||||
|
payload_len: Some(96),
|
||||||
|
decode_status: "parity_only".to_string(),
|
||||||
|
payload_family: "real_packed_v1".to_string(),
|
||||||
|
trigger_kind: Some(7),
|
||||||
|
active: None,
|
||||||
|
marks_collection_dirty: None,
|
||||||
|
one_shot: Some(false),
|
||||||
|
compact_control: Some(real_compact_control()),
|
||||||
|
text_bands: vec![],
|
||||||
|
standalone_condition_row_count: 0,
|
||||||
|
standalone_condition_rows: vec![],
|
||||||
|
negative_sentinel_scope: None,
|
||||||
|
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||||
|
grouped_effect_rows: vec![real_territory_access_cost_row(750000)],
|
||||||
|
decoded_conditions: Vec::new(),
|
||||||
|
decoded_actions: vec![],
|
||||||
|
executable_import_ready: false,
|
||||||
|
notes: vec!["territory access cost rows remain metadata-only".to_string()],
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
notes: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let import = project_save_slice_to_runtime_state_import(
|
||||||
|
&save_slice,
|
||||||
|
"packed-events-territory-access-cost-frontier",
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.expect("save slice should project");
|
||||||
|
|
||||||
|
assert!(import.state.event_runtime_records.is_empty());
|
||||||
|
assert_eq!(
|
||||||
|
import
|
||||||
|
.state
|
||||||
|
.packed_event_collection
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||||
|
Some("blocked_unmapped_world_descriptor")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn overlays_real_company_cash_descriptor_into_executable_runtime_record() {
|
fn overlays_real_company_cash_descriptor_into_executable_runtime_record() {
|
||||||
let base_state = RuntimeState {
|
let base_state = RuntimeState {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
@ -2684,6 +2686,11 @@ fn parse_real_grouped_effect_row_summary(
|
||||||
"locomotive availability descriptor maps to live locomotive id {loco_id}"
|
"locomotive availability descriptor maps to live locomotive id {loco_id}"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if let Some(loco_id) = recovered_locomotive_cost_loco_id(descriptor_id) {
|
||||||
|
notes.push(format!(
|
||||||
|
"locomotive cost descriptor maps to live locomotive id {loco_id}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Some(SmpLoadedPackedEventGroupedEffectRowSummary {
|
Some(SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
group_index,
|
group_index,
|
||||||
|
|
@ -2711,7 +2718,8 @@ fn parse_real_grouped_effect_row_summary(
|
||||||
value_word_0x14,
|
value_word_0x14,
|
||||||
value_word_0x16,
|
value_word_0x16,
|
||||||
)),
|
)),
|
||||||
recovered_locomotive_id: recovered_locomotive_availability_loco_id(descriptor_id),
|
recovered_locomotive_id: recovered_locomotive_availability_loco_id(descriptor_id)
|
||||||
|
.or_else(|| recovered_locomotive_cost_loco_id(descriptor_id)),
|
||||||
locomotive_name,
|
locomotive_name,
|
||||||
notes,
|
notes,
|
||||||
})
|
})
|
||||||
|
|
@ -2823,16 +2831,16 @@ fn real_grouped_effect_descriptor_metadata(
|
||||||
fn recovered_cargo_production_descriptor_metadata(
|
fn recovered_cargo_production_descriptor_metadata(
|
||||||
descriptor_id: u32,
|
descriptor_id: u32,
|
||||||
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
||||||
(230..=240)
|
recovered_cargo_production_label(descriptor_id).map(|label| {
|
||||||
.contains(&descriptor_id)
|
RealGroupedEffectDescriptorMetadata {
|
||||||
.then_some(RealGroupedEffectDescriptorMetadata {
|
|
||||||
descriptor_id,
|
descriptor_id,
|
||||||
label: "Unknown Cargo Production",
|
label,
|
||||||
target_mask_bits: 0x08,
|
target_mask_bits: 0x08,
|
||||||
parameter_family: "unknown_cargo_production_scalar",
|
parameter_family: "cargo_production_scalar",
|
||||||
runtime_key: None,
|
runtime_key: None,
|
||||||
executable_in_runtime: false,
|
executable_in_runtime: false,
|
||||||
})
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recovered_locomotive_availability_descriptor_metadata(
|
fn recovered_locomotive_availability_descriptor_metadata(
|
||||||
|
|
@ -2872,31 +2880,66 @@ fn recovered_locomotive_availability_loco_id(descriptor_id: u32) -> Option<u32>
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recovered_cargo_production_label(descriptor_id: u32) -> Option<&'static str> {
|
||||||
|
static LABELS: OnceLock<BTreeMap<u32, &'static str>> = OnceLock::new();
|
||||||
|
LABELS
|
||||||
|
.get_or_init(|| {
|
||||||
|
(230..=240)
|
||||||
|
.enumerate()
|
||||||
|
.map(|(slot_index, descriptor_id)| {
|
||||||
|
let label = Box::leak(
|
||||||
|
format!("Cargo Production Slot {}", slot_index + 1).into_boxed_str(),
|
||||||
|
) as &'static str;
|
||||||
|
(descriptor_id, label)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.get(&descriptor_id)
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recovered_locomotive_cost_loco_id(descriptor_id: u32) -> Option<u32> {
|
||||||
|
if (352..=451).contains(&descriptor_id) {
|
||||||
|
return Some(descriptor_id - 351);
|
||||||
|
}
|
||||||
|
if (475..=500).contains(&descriptor_id) {
|
||||||
|
return Some(descriptor_id - 374);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recovered_locomotive_cost_label(descriptor_id: u32) -> Option<&'static str> {
|
||||||
|
static LABELS: OnceLock<BTreeMap<u32, &'static str>> = OnceLock::new();
|
||||||
|
LABELS
|
||||||
|
.get_or_init(|| {
|
||||||
|
(352..=451)
|
||||||
|
.chain(475..=500)
|
||||||
|
.filter_map(|descriptor_id| {
|
||||||
|
recovered_locomotive_cost_loco_id(descriptor_id).map(|loco_id| {
|
||||||
|
let label = Box::leak(format!("Locomotive {loco_id} Cost").into_boxed_str())
|
||||||
|
as &'static str;
|
||||||
|
(descriptor_id, label)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.get(&descriptor_id)
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
|
|
||||||
fn recovered_locomotive_cost_descriptor_metadata(
|
fn recovered_locomotive_cost_descriptor_metadata(
|
||||||
descriptor_id: u32,
|
descriptor_id: u32,
|
||||||
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
||||||
(352..=451)
|
recovered_locomotive_cost_label(descriptor_id).map(|label| {
|
||||||
.contains(&descriptor_id)
|
RealGroupedEffectDescriptorMetadata {
|
||||||
.then_some(RealGroupedEffectDescriptorMetadata {
|
|
||||||
descriptor_id,
|
descriptor_id,
|
||||||
label: "Unknown Loco Cost",
|
label,
|
||||||
target_mask_bits: 0x08,
|
target_mask_bits: 0x08,
|
||||||
parameter_family: "locomotive_cost_scalar",
|
parameter_family: "locomotive_cost_scalar",
|
||||||
runtime_key: None,
|
runtime_key: None,
|
||||||
executable_in_runtime: false,
|
executable_in_runtime: false,
|
||||||
})
|
}
|
||||||
.or_else(|| {
|
})
|
||||||
(475..=500)
|
|
||||||
.contains(&descriptor_id)
|
|
||||||
.then_some(RealGroupedEffectDescriptorMetadata {
|
|
||||||
descriptor_id,
|
|
||||||
label: "Unknown Loco Cost",
|
|
||||||
target_mask_bits: 0x08,
|
|
||||||
parameter_family: "locomotive_cost_scalar",
|
|
||||||
runtime_key: None,
|
|
||||||
executable_in_runtime: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recovered_territory_access_cost_descriptor_metadata(
|
fn recovered_territory_access_cost_descriptor_metadata(
|
||||||
|
|
@ -2904,7 +2947,7 @@ fn recovered_territory_access_cost_descriptor_metadata(
|
||||||
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
||||||
(descriptor_id == 453).then_some(RealGroupedEffectDescriptorMetadata {
|
(descriptor_id == 453).then_some(RealGroupedEffectDescriptorMetadata {
|
||||||
descriptor_id,
|
descriptor_id,
|
||||||
label: "Territory access cost",
|
label: "Territory Access Cost",
|
||||||
target_mask_bits: 0x08,
|
target_mask_bits: 0x08,
|
||||||
parameter_family: "territory_access_cost_scalar",
|
parameter_family: "territory_access_cost_scalar",
|
||||||
runtime_key: None,
|
runtime_key: None,
|
||||||
|
|
@ -9292,6 +9335,81 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn looks_up_recovered_cargo_production_descriptor_metadata() {
|
||||||
|
let metadata =
|
||||||
|
real_grouped_effect_descriptor_metadata(230).expect("descriptor metadata should exist");
|
||||||
|
|
||||||
|
assert_eq!(metadata.label, "Cargo Production Slot 1");
|
||||||
|
assert_eq!(metadata.target_mask_bits, 0x08);
|
||||||
|
assert_eq!(metadata.parameter_family, "cargo_production_scalar");
|
||||||
|
assert_eq!(metadata.runtime_key, None);
|
||||||
|
assert!(!metadata.executable_in_runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn looks_up_recovered_lower_band_locomotive_cost_descriptor_metadata() {
|
||||||
|
let metadata =
|
||||||
|
real_grouped_effect_descriptor_metadata(352).expect("descriptor metadata should exist");
|
||||||
|
|
||||||
|
assert_eq!(metadata.label, "Locomotive 1 Cost");
|
||||||
|
assert_eq!(metadata.target_mask_bits, 0x08);
|
||||||
|
assert_eq!(metadata.parameter_family, "locomotive_cost_scalar");
|
||||||
|
assert_eq!(metadata.runtime_key, None);
|
||||||
|
assert_eq!(recovered_locomotive_cost_loco_id(352), Some(1));
|
||||||
|
assert!(!metadata.executable_in_runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn looks_up_recovered_upper_band_locomotive_cost_descriptor_metadata() {
|
||||||
|
let metadata =
|
||||||
|
real_grouped_effect_descriptor_metadata(475).expect("descriptor metadata should exist");
|
||||||
|
|
||||||
|
assert_eq!(metadata.label, "Locomotive 101 Cost");
|
||||||
|
assert_eq!(metadata.parameter_family, "locomotive_cost_scalar");
|
||||||
|
assert_eq!(recovered_locomotive_cost_loco_id(475), Some(101));
|
||||||
|
assert!(!metadata.executable_in_runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn looks_up_recovered_territory_access_cost_descriptor_metadata() {
|
||||||
|
let metadata =
|
||||||
|
real_grouped_effect_descriptor_metadata(453).expect("descriptor metadata should exist");
|
||||||
|
|
||||||
|
assert_eq!(metadata.label, "Territory Access Cost");
|
||||||
|
assert_eq!(metadata.target_mask_bits, 0x08);
|
||||||
|
assert_eq!(metadata.parameter_family, "territory_access_cost_scalar");
|
||||||
|
assert_eq!(metadata.runtime_key, None);
|
||||||
|
assert!(!metadata.executable_in_runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parses_recovered_locomotive_cost_row_with_structured_locomotive_id() {
|
||||||
|
let row_bytes = build_real_grouped_effect_row(RealGroupedEffectRowSpec {
|
||||||
|
descriptor_id: 352,
|
||||||
|
raw_scalar_value: 250000,
|
||||||
|
opcode: 3,
|
||||||
|
value_byte_0x09: 0,
|
||||||
|
value_dword_0x0d: 0,
|
||||||
|
value_byte_0x11: 0,
|
||||||
|
value_byte_0x12: 0,
|
||||||
|
value_word_0x14: 0,
|
||||||
|
value_word_0x16: 0,
|
||||||
|
locomotive_name: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let row = parse_real_grouped_effect_row_summary(&row_bytes, 0, 0, None)
|
||||||
|
.expect("row should parse");
|
||||||
|
|
||||||
|
assert_eq!(row.descriptor_id, 352);
|
||||||
|
assert_eq!(row.descriptor_label.as_deref(), Some("Locomotive 1 Cost"));
|
||||||
|
assert_eq!(row.recovered_locomotive_id, Some(1));
|
||||||
|
assert_eq!(
|
||||||
|
row.parameter_family.as_deref(),
|
||||||
|
Some("locomotive_cost_scalar")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn looks_up_recovered_locomotive_policy_descriptor_metadata() {
|
fn looks_up_recovered_locomotive_policy_descriptor_metadata() {
|
||||||
let metadata =
|
let metadata =
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,9 @@ The highest-value next passes are now:
|
||||||
`blocked_unmapped_world_descriptor` frontier
|
`blocked_unmapped_world_descriptor` frontier
|
||||||
- the next recovered locomotives-page descriptor batch is partially executable too:
|
- the next recovered locomotives-page descriptor batch is partially executable too:
|
||||||
descriptors `454..456` (`All Steam/Diesel/Electric Locos Avail.`) now lower through checked-in
|
descriptors `454..456` (`All Steam/Diesel/Electric Locos Avail.`) now lower through checked-in
|
||||||
metadata into keyed `world_flags`, while the wider locomotive availability/cost scalar bands
|
metadata into keyed `world_flags`, while the wider locomotive availability/cost scalar bands now
|
||||||
remain recovered-but-parity-only until per-locomotive identity is grounded
|
split cleanly between executable boolean availability rows and recovered metadata-rich parity
|
||||||
|
rows for the remaining cargo-production, locomotive-cost, and territory-access-cost families
|
||||||
- the runtime now also carries both the save-owned named locomotive availability table and an
|
- the runtime now also carries both the save-owned named locomotive availability table and an
|
||||||
overlay-backed locomotive catalog context: checked-in save-slice documents can populate
|
overlay-backed locomotive catalog context: checked-in save-slice documents can populate
|
||||||
`RuntimeState.named_locomotive_availability`, and boolean `0/1` availability descriptors can
|
`RuntimeState.named_locomotive_availability`, and boolean `0/1` availability descriptors can
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,15 @@ Implemented today:
|
||||||
through the ordinary event-service path without requiring Trainbuy or live locomotive-pool parity
|
through the ordinary event-service path without requiring Trainbuy or live locomotive-pool parity
|
||||||
- the boolean `0/1` subset of the recovered locomotives-page availability bands can now import
|
- the boolean `0/1` subset of the recovered locomotives-page availability bands can now import
|
||||||
through an overlay-backed `RuntimeState.locomotive_catalog`; non-boolean availability payloads
|
through an overlay-backed `RuntimeState.locomotive_catalog`; non-boolean availability payloads
|
||||||
and the adjacent locomotive-cost/cargo-production/access-cost families remain parity-only
|
and the adjacent locomotive-cost/cargo-production/access-cost families now surface as recovered
|
||||||
|
metadata-rich parity rows with checked-in slot labels and locomotive ids where grounded, but
|
||||||
|
execution for those scalar families remains deferred
|
||||||
|
|
||||||
That means the next implementation work is breadth, not bootstrap. The recommended next slice is
|
That means the next implementation work is breadth, not bootstrap. The recommended next slice is
|
||||||
broader real grouped-descriptor and ordinary condition-id coverage beyond the current access,
|
honest landing surfaces for one or more of those recovered scalar families, plus broader real
|
||||||
whole-game toggle, train, player, numeric-threshold, named locomotive availability, and
|
grouped-descriptor and ordinary condition-id coverage beyond the current access, whole-game
|
||||||
overlay-resolved locomotive availability batches.
|
toggle, train, player, numeric-threshold, named locomotive availability, and overlay-resolved
|
||||||
|
locomotive availability batches.
|
||||||
Richer runtime ownership should still be added only where a later descriptor or condition family
|
Richer runtime ownership should still be added only where a later descriptor or condition family
|
||||||
needs more than the current event-owned roster.
|
needs more than the current event-owned roster.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
{
|
||||||
|
"format_version": 1,
|
||||||
|
"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 pins recovered scalar-band world descriptors as parity-only."
|
||||||
|
},
|
||||||
|
"state_save_slice_path": "packed-event-world-scalar-band-parity-save-slice.json",
|
||||||
|
"commands": [
|
||||||
|
{
|
||||||
|
"kind": "step_count",
|
||||||
|
"steps": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expected_summary": {
|
||||||
|
"calendar": {
|
||||||
|
"year": 1830,
|
||||||
|
"month_slot": 0,
|
||||||
|
"phase_slot": 0,
|
||||||
|
"tick_slot": 1
|
||||||
|
},
|
||||||
|
"calendar_projection_is_placeholder": true,
|
||||||
|
"packed_event_collection_present": true,
|
||||||
|
"packed_event_record_count": 3,
|
||||||
|
"packed_event_decoded_record_count": 3,
|
||||||
|
"packed_event_imported_runtime_record_count": 0,
|
||||||
|
"packed_event_parity_only_record_count": 3,
|
||||||
|
"packed_event_unsupported_record_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": 3,
|
||||||
|
"packed_event_blocked_structural_only_count": 0,
|
||||||
|
"event_runtime_record_count": 0,
|
||||||
|
"total_company_cash": 0
|
||||||
|
},
|
||||||
|
"expected_state_fragment": {
|
||||||
|
"metadata": {
|
||||||
|
"save_slice.import_projection": "partial-runtime-restore-v1"
|
||||||
|
},
|
||||||
|
"packed_event_collection": {
|
||||||
|
"live_entry_ids": [11, 12, 13],
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"import_outcome": "blocked_unmapped_world_descriptor",
|
||||||
|
"grouped_effect_rows": [
|
||||||
|
{
|
||||||
|
"descriptor_id": 230,
|
||||||
|
"descriptor_label": "Cargo Production Slot 1",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "cargo_production_scalar",
|
||||||
|
"semantic_family": "scalar_assignment",
|
||||||
|
"semantic_preview": "Set Cargo Production Slot 1 to 125",
|
||||||
|
"row_shape": "scalar_assignment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"import_outcome": "blocked_unmapped_world_descriptor",
|
||||||
|
"grouped_effect_rows": [
|
||||||
|
{
|
||||||
|
"descriptor_id": 352,
|
||||||
|
"descriptor_label": "Locomotive 1 Cost",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "locomotive_cost_scalar",
|
||||||
|
"semantic_family": "scalar_assignment",
|
||||||
|
"semantic_preview": "Set Locomotive 1 Cost to 250000",
|
||||||
|
"recovered_locomotive_id": 1,
|
||||||
|
"row_shape": "scalar_assignment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"import_outcome": "blocked_unmapped_world_descriptor",
|
||||||
|
"grouped_effect_rows": [
|
||||||
|
{
|
||||||
|
"descriptor_id": 453,
|
||||||
|
"descriptor_label": "Territory Access Cost",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "territory_access_cost_scalar",
|
||||||
|
"semantic_family": "scalar_assignment",
|
||||||
|
"semantic_preview": "Set Territory Access Cost to 750000",
|
||||||
|
"row_shape": "scalar_assignment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
{
|
||||||
|
"format_version": 1,
|
||||||
|
"save_slice_id": "packed-event-world-scalar-band-parity-save-slice",
|
||||||
|
"source": {
|
||||||
|
"description": "Tracked save-slice document pinning recovered locomotives-page scalar families that are still parity-only.",
|
||||||
|
"original_save_filename": "captured-world-scalar-band-parity.gms",
|
||||||
|
"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 without claiming executable runtime semantics"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
"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": 29696,
|
||||||
|
"records_tag_offset": 29952,
|
||||||
|
"close_tag_offset": 30720,
|
||||||
|
"packed_state_version": 1001,
|
||||||
|
"packed_state_version_hex": "0x000003e9",
|
||||||
|
"live_id_bound": 13,
|
||||||
|
"live_record_count": 3,
|
||||||
|
"live_entry_ids": [11, 12, 13],
|
||||||
|
"decoded_record_count": 3,
|
||||||
|
"imported_runtime_record_count": 0,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"record_index": 0,
|
||||||
|
"live_entry_id": 11,
|
||||||
|
"payload_offset": 29984,
|
||||||
|
"payload_len": 96,
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"trigger_kind": 6,
|
||||||
|
"one_shot": false,
|
||||||
|
"compact_control": {
|
||||||
|
"mode_byte_0x7ef": 6,
|
||||||
|
"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": [1, 0, 0, 0],
|
||||||
|
"grouped_effect_rows": [
|
||||||
|
{
|
||||||
|
"group_index": 0,
|
||||||
|
"row_index": 0,
|
||||||
|
"descriptor_id": 230,
|
||||||
|
"descriptor_label": "Cargo Production Slot 1",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "cargo_production_scalar",
|
||||||
|
"opcode": 3,
|
||||||
|
"raw_scalar_value": 125,
|
||||||
|
"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 Cargo Production Slot 1 to 125",
|
||||||
|
"recovered_locomotive_id": null,
|
||||||
|
"locomotive_name": null,
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decoded_actions": [],
|
||||||
|
"executable_import_ready": false,
|
||||||
|
"notes": [
|
||||||
|
"recovered cargo production metadata is now checked in, but no runtime landing surface exists yet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_index": 1,
|
||||||
|
"live_entry_id": 12,
|
||||||
|
"payload_offset": 30096,
|
||||||
|
"payload_len": 96,
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"trigger_kind": 6,
|
||||||
|
"one_shot": false,
|
||||||
|
"compact_control": {
|
||||||
|
"mode_byte_0x7ef": 6,
|
||||||
|
"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": [1, 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decoded_actions": [],
|
||||||
|
"executable_import_ready": false,
|
||||||
|
"notes": [
|
||||||
|
"recovered locomotive cost metadata is now checked in, but execution is still deferred"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"record_index": 2,
|
||||||
|
"live_entry_id": 13,
|
||||||
|
"payload_offset": 30208,
|
||||||
|
"payload_len": 96,
|
||||||
|
"decode_status": "parity_only",
|
||||||
|
"payload_family": "real_packed_v1",
|
||||||
|
"trigger_kind": 6,
|
||||||
|
"one_shot": false,
|
||||||
|
"compact_control": {
|
||||||
|
"mode_byte_0x7ef": 6,
|
||||||
|
"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": [1, 0, 0, 0],
|
||||||
|
"grouped_effect_rows": [
|
||||||
|
{
|
||||||
|
"group_index": 0,
|
||||||
|
"row_index": 0,
|
||||||
|
"descriptor_id": 453,
|
||||||
|
"descriptor_label": "Territory Access Cost",
|
||||||
|
"target_mask_bits": 8,
|
||||||
|
"parameter_family": "territory_access_cost_scalar",
|
||||||
|
"opcode": 3,
|
||||||
|
"raw_scalar_value": 750000,
|
||||||
|
"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 Territory Access Cost to 750000",
|
||||||
|
"recovered_locomotive_id": null,
|
||||||
|
"locomotive_name": null,
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decoded_actions": [],
|
||||||
|
"executable_import_ready": false,
|
||||||
|
"notes": [
|
||||||
|
"recovered territory access cost metadata is now checked in, but execution is still deferred"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
"world scalar parity sample"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue