Make cargo catalog save-native

This commit is contained in:
Jan Petykiewicz 2026-04-16 14:47:38 -07:00
commit c17b9f55f7
24 changed files with 575 additions and 52 deletions

View file

@ -68,7 +68,10 @@ metadata still does not ground, such as `All Factory Production`, now remain exp
unmapped world-condition and world-descriptor unmapped world-condition and world-descriptor
frontier buckets still remain where current checked-in metadata stops, and frontier buckets still remain where current checked-in metadata stops, and
`blocked_missing_locomotive_catalog_context` is now reserved for intentionally incomplete save-side `blocked_missing_locomotive_catalog_context` is now reserved for intentionally incomplete save-side
catalog context instead of the normal save-slice path. Shell purchase-flow, Trainbuy refresh, catalog context instead of the normal save-slice path. Cargo slot identity is now save-native too:
the recipe-book probe lowers into `RuntimeState.cargo_catalog`, so save-slice documents can carry
slot labels and token-stem evidence alongside the executable `cargo_production_overrides` surface
without introducing a live cargo-economy model. Shell purchase-flow, Trainbuy refresh,
cached locomotive-rating recomputation, and selected-profile parity remain out of scope. Mixed cached locomotive-rating recomputation, and selected-profile parity remain out of scope. Mixed
supported/unsupported real rows still stay parity-only. The PE32 hook remains useful as capture and supported/unsupported real rows still stay parity-only. The PE32 hook remains useful as capture and
integration tooling, but it is no longer the main execution milestone. integration tooling, but it is no longer the main execution milestone.

View file

@ -4483,6 +4483,8 @@ mod tests {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join( PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(
"../../fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json", "../../fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json",
); );
let cargo_catalog_fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../fixtures/runtime/packed-event-cargo-catalog-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");
@ -4522,6 +4524,8 @@ mod tests {
.expect("save-slice-backed executable world-scalar condition fixture should summarize"); .expect("save-slice-backed executable world-scalar condition fixture should summarize");
run_runtime_summarize_fixture(&world_scalar_condition_parity_fixture) run_runtime_summarize_fixture(&world_scalar_condition_parity_fixture)
.expect("save-slice-backed parity world-scalar condition fixture should summarize"); .expect("save-slice-backed parity world-scalar condition fixture should summarize");
run_runtime_summarize_fixture(&cargo_catalog_fixture)
.expect("save-slice-backed cargo catalog fixture should summarize");
} }
#[test] #[test]
@ -4548,6 +4552,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: None, event_runtime_collection: None,
notes: vec!["exported for test".to_string()], notes: vec!["exported for test".to_string()],

View file

@ -178,6 +178,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -265,6 +266,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: None, event_runtime_collection: None,
notes: vec![], notes: vec![],
@ -353,6 +355,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -383,6 +386,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some( event_runtime_collection: Some(
rrt_runtime::SmpLoadedEventRuntimeCollectionSummary { rrt_runtime::SmpLoadedEventRuntimeCollectionSummary {

View file

@ -80,6 +80,8 @@ pub struct ExpectedRuntimeSummary {
#[serde(default)] #[serde(default)]
pub locomotive_catalog_count: Option<usize>, pub locomotive_catalog_count: Option<usize>,
#[serde(default)] #[serde(default)]
pub cargo_catalog_count: Option<usize>,
#[serde(default)]
pub territory_count: Option<usize>, pub territory_count: Option<usize>,
#[serde(default)] #[serde(default)]
pub company_territory_track_count: Option<usize>, pub company_territory_track_count: Option<usize>,
@ -469,6 +471,14 @@ impl ExpectedRuntimeSummary {
)); ));
} }
} }
if let Some(count) = self.cargo_catalog_count {
if actual.cargo_catalog_count != count {
mismatches.push(format!(
"cargo_catalog_count mismatch: expected {count}, got {}",
actual.cargo_catalog_count
));
}
}
if let Some(count) = self.territory_count { if let Some(count) = self.territory_count {
if actual.territory_count != count { if actual.territory_count != count {
mismatches.push(format!( mismatches.push(format!(

View file

@ -5,17 +5,17 @@ use serde::{Deserialize, Serialize};
use crate::persistence::{load_runtime_snapshot_document, validate_runtime_snapshot_document}; use crate::persistence::{load_runtime_snapshot_document, validate_runtime_snapshot_document};
use crate::{ use crate::{
CalendarPoint, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, CalendarPoint, RuntimeCargoCatalogEntry, RuntimeCompanyConditionTestScope,
RuntimeCompanyTarget, RuntimeCondition, RuntimeEffect, RuntimeEventRecord, RuntimeCompanyControllerKind, RuntimeCompanyTarget, RuntimeCondition, RuntimeEffect,
RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary, RuntimeEventRecord, RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry,
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary, RuntimePackedEventCollectionSummary, RuntimePackedEventCompactControlSummary,
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary, RuntimePackedEventConditionRowSummary, RuntimePackedEventGroupedEffectRowSummary,
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePackedEventNegativeSentinelScopeSummary, RuntimePackedEventRecordSummary,
RuntimePlayerConditionTestScope, RuntimePlayerTarget, RuntimeSaveProfileState, RuntimePackedEventTextBandSummary, RuntimePlayerConditionTestScope, RuntimePlayerTarget,
RuntimeServiceState, RuntimeState, RuntimeTerritoryTarget, RuntimeWorldRestoreState, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, RuntimeTerritoryTarget,
SmpLoadedPackedEventConditionRowSummary, SmpLoadedPackedEventGroupedEffectRowSummary, RuntimeWorldRestoreState, SmpLoadedPackedEventConditionRowSummary,
SmpLoadedPackedEventNegativeSentinelScopeSummary, SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventNegativeSentinelScopeSummary,
SmpLoadedPackedEventTextBandSummary, SmpLoadedSaveSlice, SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventTextBandSummary, SmpLoadedSaveSlice,
}; };
pub const STATE_DUMP_FORMAT_VERSION: u32 = 1; pub const STATE_DUMP_FORMAT_VERSION: u32 = 1;
@ -96,6 +96,7 @@ struct SaveSliceProjection {
candidate_availability: BTreeMap<String, u32>, candidate_availability: BTreeMap<String, u32>,
named_locomotive_availability: BTreeMap<String, u32>, named_locomotive_availability: BTreeMap<String, u32>,
locomotive_catalog: Option<Vec<RuntimeLocomotiveCatalogEntry>>, locomotive_catalog: Option<Vec<RuntimeLocomotiveCatalogEntry>>,
cargo_catalog: Option<Vec<RuntimeCargoCatalogEntry>>,
named_locomotive_cost: BTreeMap<String, u32>, named_locomotive_cost: BTreeMap<String, u32>,
cargo_production_overrides: BTreeMap<u32, u32>, cargo_production_overrides: BTreeMap<u32, u32>,
special_conditions: BTreeMap<String, u32>, special_conditions: BTreeMap<String, u32>,
@ -245,6 +246,7 @@ pub fn project_save_slice_to_runtime_state_import(
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: projection.locomotive_catalog.unwrap_or_default(), locomotive_catalog: projection.locomotive_catalog.unwrap_or_default(),
cargo_catalog: projection.cargo_catalog.unwrap_or_default(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -309,6 +311,9 @@ pub fn project_save_slice_overlay_to_runtime_state_import(
locomotive_catalog: projection locomotive_catalog: projection
.locomotive_catalog .locomotive_catalog
.unwrap_or_else(|| base_state.locomotive_catalog.clone()), .unwrap_or_else(|| base_state.locomotive_catalog.clone()),
cargo_catalog: projection
.cargo_catalog
.unwrap_or_else(|| base_state.cargo_catalog.clone()),
territories: base_state.territories.clone(), territories: base_state.territories.clone(),
company_territory_track_piece_counts: base_state company_territory_track_piece_counts: base_state
.company_territory_track_piece_counts .company_territory_track_piece_counts
@ -359,6 +364,10 @@ fn project_save_slice_components(
save_slice.locomotive_catalog.is_some() save_slice.locomotive_catalog.is_some()
|| save_slice.named_locomotive_availability_table.is_some(), || save_slice.named_locomotive_availability_table.is_some(),
); );
world_flags.insert(
"save_slice.cargo_catalog_present".to_string(),
save_slice.cargo_catalog.is_some(),
);
world_flags.insert( world_flags.insert(
"save_slice.event_runtime_collection_present".to_string(), "save_slice.event_runtime_collection_present".to_string(),
save_slice.event_runtime_collection.is_some(), save_slice.event_runtime_collection.is_some(),
@ -690,6 +699,44 @@ fn project_save_slice_components(
} else { } else {
None None
}; };
let cargo_catalog = if let Some(catalog) = &save_slice.cargo_catalog {
metadata.insert(
"save_slice.cargo_catalog_source_kind".to_string(),
catalog.source_kind.clone(),
);
metadata.insert(
"save_slice.cargo_catalog_semantic_family".to_string(),
catalog.semantic_family.clone(),
);
metadata.insert(
"save_slice.cargo_catalog_entry_count".to_string(),
catalog.observed_entry_count.to_string(),
);
if let Some(root_offset) = catalog.root_offset {
metadata.insert(
"save_slice.cargo_catalog_root_offset".to_string(),
root_offset.to_string(),
);
}
Some(
catalog
.entries
.iter()
.map(|entry| RuntimeCargoCatalogEntry {
slot_id: entry.slot_id,
label: entry.label.clone(),
supplied_token_stem: entry
.supplied_cargo_token_probable_high16_ascii_stem
.clone(),
demanded_token_stem: entry
.demanded_cargo_token_probable_high16_ascii_stem
.clone(),
})
.collect::<Vec<_>>(),
)
} else {
None
};
let named_locomotive_cost = BTreeMap::new(); let named_locomotive_cost = BTreeMap::new();
let cargo_production_overrides = BTreeMap::new(); let cargo_production_overrides = BTreeMap::new();
@ -702,8 +749,11 @@ fn project_save_slice_components(
.collect(); .collect();
} }
let (packed_event_collection, event_runtime_records) = let (packed_event_collection, event_runtime_records) = project_packed_event_collection(
project_packed_event_collection(save_slice, &packed_event_context)?; save_slice,
&packed_event_context,
cargo_catalog.as_deref().unwrap_or(&[]),
)?;
if let Some(summary) = &save_slice.event_runtime_collection { if let Some(summary) = &save_slice.event_runtime_collection {
metadata.insert( metadata.insert(
"save_slice.event_runtime_collection_source_kind".to_string(), "save_slice.event_runtime_collection_source_kind".to_string(),
@ -741,6 +791,7 @@ fn project_save_slice_components(
candidate_availability, candidate_availability,
named_locomotive_availability, named_locomotive_availability,
locomotive_catalog, locomotive_catalog,
cargo_catalog,
named_locomotive_cost, named_locomotive_cost,
cargo_production_overrides, cargo_production_overrides,
special_conditions, special_conditions,
@ -750,6 +801,7 @@ fn project_save_slice_components(
fn project_packed_event_collection( fn project_packed_event_collection(
save_slice: &SmpLoadedSaveSlice, save_slice: &SmpLoadedSaveSlice,
company_context: &ImportRuntimeContext, company_context: &ImportRuntimeContext,
cargo_catalog: &[RuntimeCargoCatalogEntry],
) -> Result< ) -> Result<
( (
Option<RuntimePackedEventCollectionSummary>, Option<RuntimePackedEventCollectionSummary>,
@ -780,6 +832,7 @@ fn project_packed_event_collection(
runtime_packed_event_record_summary_from_smp( runtime_packed_event_record_summary_from_smp(
record, record,
company_context, company_context,
cargo_catalog,
imported_record_ids.contains(&record.live_entry_id), imported_record_ids.contains(&record.live_entry_id),
) )
}) })
@ -810,6 +863,7 @@ fn project_packed_event_collection(
fn runtime_packed_event_record_summary_from_smp( fn runtime_packed_event_record_summary_from_smp(
record: &SmpLoadedPackedEventRecordSummary, record: &SmpLoadedPackedEventRecordSummary,
company_context: &ImportRuntimeContext, company_context: &ImportRuntimeContext,
cargo_catalog: &[RuntimeCargoCatalogEntry],
imported: bool, imported: bool,
) -> RuntimePackedEventRecordSummary { ) -> RuntimePackedEventRecordSummary {
let lowered_decoded_conditions = lowered_record_decoded_conditions(record, company_context) let lowered_decoded_conditions = lowered_record_decoded_conditions(record, company_context)
@ -840,7 +894,7 @@ fn runtime_packed_event_record_summary_from_smp(
standalone_condition_rows: record standalone_condition_rows: record
.standalone_condition_rows .standalone_condition_rows
.iter() .iter()
.map(runtime_packed_event_condition_row_summary_from_smp) .map(|row| runtime_packed_event_condition_row_summary_from_smp(row, cargo_catalog))
.collect(), .collect(),
negative_sentinel_scope: record negative_sentinel_scope: record
.negative_sentinel_scope .negative_sentinel_scope
@ -850,7 +904,7 @@ fn runtime_packed_event_record_summary_from_smp(
grouped_effect_rows: record grouped_effect_rows: record
.grouped_effect_rows .grouped_effect_rows
.iter() .iter()
.map(runtime_packed_event_grouped_effect_row_summary_from_smp) .map(|row| runtime_packed_event_grouped_effect_row_summary_from_smp(row, cargo_catalog))
.collect(), .collect(),
grouped_company_targets: classify_real_grouped_company_targets(record), grouped_company_targets: classify_real_grouped_company_targets(record),
decoded_conditions: lowered_decoded_conditions, decoded_conditions: lowered_decoded_conditions,
@ -906,7 +960,11 @@ fn runtime_packed_event_text_band_summary_from_smp(
fn runtime_packed_event_condition_row_summary_from_smp( fn runtime_packed_event_condition_row_summary_from_smp(
row: &crate::SmpLoadedPackedEventConditionRowSummary, row: &crate::SmpLoadedPackedEventConditionRowSummary,
cargo_catalog: &[RuntimeCargoCatalogEntry],
) -> RuntimePackedEventConditionRowSummary { ) -> RuntimePackedEventConditionRowSummary {
let cargo_entry = row
.recovered_cargo_slot
.and_then(|slot| cargo_catalog.iter().find(|entry| entry.slot_id == slot));
RuntimePackedEventConditionRowSummary { RuntimePackedEventConditionRowSummary {
row_index: row.row_index, row_index: row.row_index,
raw_condition_id: row.raw_condition_id, raw_condition_id: row.raw_condition_id,
@ -918,13 +976,26 @@ fn runtime_packed_event_condition_row_summary_from_smp(
semantic_family: row.semantic_family.clone(), semantic_family: row.semantic_family.clone(),
semantic_preview: row.semantic_preview.clone(), semantic_preview: row.semantic_preview.clone(),
requires_candidate_name_binding: row.requires_candidate_name_binding, requires_candidate_name_binding: row.requires_candidate_name_binding,
recovered_cargo_slot: row.recovered_cargo_slot,
recovered_cargo_class: row.recovered_cargo_class.clone(),
recovered_cargo_label: cargo_entry
.map(|entry| entry.label.clone())
.or_else(|| row.recovered_cargo_slot.map(default_cargo_slot_label)),
recovered_cargo_supplied_token_stem: cargo_entry
.and_then(|entry| entry.supplied_token_stem.clone()),
recovered_cargo_demanded_token_stem: cargo_entry
.and_then(|entry| entry.demanded_token_stem.clone()),
notes: row.notes.clone(), notes: row.notes.clone(),
} }
} }
fn runtime_packed_event_grouped_effect_row_summary_from_smp( fn runtime_packed_event_grouped_effect_row_summary_from_smp(
row: &crate::SmpLoadedPackedEventGroupedEffectRowSummary, row: &crate::SmpLoadedPackedEventGroupedEffectRowSummary,
cargo_catalog: &[RuntimeCargoCatalogEntry],
) -> RuntimePackedEventGroupedEffectRowSummary { ) -> RuntimePackedEventGroupedEffectRowSummary {
let cargo_entry = row
.recovered_cargo_slot
.and_then(|slot| cargo_catalog.iter().find(|entry| entry.slot_id == slot));
RuntimePackedEventGroupedEffectRowSummary { RuntimePackedEventGroupedEffectRowSummary {
group_index: row.group_index, group_index: row.group_index,
row_index: row.row_index, row_index: row.row_index,
@ -943,12 +1014,25 @@ fn runtime_packed_event_grouped_effect_row_summary_from_smp(
row_shape: row.row_shape.clone(), row_shape: row.row_shape.clone(),
semantic_family: row.semantic_family.clone(), semantic_family: row.semantic_family.clone(),
semantic_preview: row.semantic_preview.clone(), semantic_preview: row.semantic_preview.clone(),
recovered_cargo_slot: row.recovered_cargo_slot,
recovered_cargo_class: row.recovered_cargo_class.clone(),
recovered_cargo_label: cargo_entry
.map(|entry| entry.label.clone())
.or_else(|| row.recovered_cargo_slot.map(default_cargo_slot_label)),
recovered_cargo_supplied_token_stem: cargo_entry
.and_then(|entry| entry.supplied_token_stem.clone()),
recovered_cargo_demanded_token_stem: cargo_entry
.and_then(|entry| entry.demanded_token_stem.clone()),
recovered_locomotive_id: row.recovered_locomotive_id, recovered_locomotive_id: row.recovered_locomotive_id,
locomotive_name: row.locomotive_name.clone(), locomotive_name: row.locomotive_name.clone(),
notes: row.notes.clone(), notes: row.notes.clone(),
} }
} }
fn default_cargo_slot_label(slot: u32) -> String {
format!("Cargo Production Slot {slot}")
}
fn smp_packed_record_to_runtime_event_record( fn smp_packed_record_to_runtime_event_record(
record: &SmpLoadedPackedEventRecordSummary, record: &SmpLoadedPackedEventRecordSummary,
company_context: &ImportRuntimeContext, company_context: &ImportRuntimeContext,
@ -2251,6 +2335,17 @@ fn determine_packed_event_import_outcome(
{ {
return "blocked_retire_train_variant".to_string(); return "blocked_retire_train_variant".to_string();
} }
if record
.standalone_condition_rows
.iter()
.any(|row| row.raw_condition_id >= 0)
{
if record_has_world_state_condition_rows(record) {
return "blocked_unmapped_world_condition".to_string();
} else {
return "blocked_unmapped_ordinary_condition".to_string();
}
}
if record if record
.grouped_effect_rows .grouped_effect_rows
.iter() .iter()
@ -2258,19 +2353,7 @@ fn determine_packed_event_import_outcome(
{ {
return "blocked_unmapped_world_descriptor".to_string(); return "blocked_unmapped_world_descriptor".to_string();
} }
return if record return "blocked_unmapped_real_descriptor".to_string();
.standalone_condition_rows
.iter()
.any(|row| row.raw_condition_id >= 0)
{
if record_has_world_state_condition_rows(record) {
"blocked_unmapped_world_condition".to_string()
} else {
"blocked_unmapped_ordinary_condition".to_string()
}
} else {
"blocked_unmapped_real_descriptor".to_string()
};
} }
if let Some(blocker) = packed_record_condition_scope_import_blocker(record, company_context) if let Some(blocker) = packed_record_condition_scope_import_blocker(record, company_context)
{ {
@ -2952,6 +3035,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -3717,6 +3801,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: None, event_runtime_collection: None,
notes: vec![], notes: vec![],
@ -3757,6 +3842,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: None, event_runtime_collection: None,
notes: vec![], notes: vec![],
@ -3871,6 +3957,7 @@ mod tests {
}, },
), ),
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable { special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable {
source_kind: "save-fixed-special-conditions-range".to_string(), source_kind: "save-fixed-special-conditions-range".to_string(),
table_offset: 0x0d64, table_offset: 0x0d64,
@ -4196,6 +4283,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4311,6 +4399,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4404,6 +4493,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4515,6 +4605,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4599,6 +4690,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4733,6 +4825,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -4975,6 +5068,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5052,6 +5146,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5153,6 +5248,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5227,6 +5323,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5328,6 +5425,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5405,6 +5503,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: Some(save_named_locomotive_table(112)), named_locomotive_availability_table: Some(save_named_locomotive_table(112)),
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5522,6 +5621,7 @@ mod tests {
name: "Locomotive 112".to_string(), name: "Locomotive 112".to_string(),
}, },
], ],
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -5548,6 +5648,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5650,6 +5751,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5726,6 +5828,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5802,6 +5905,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: Some(save_named_locomotive_table(112)), named_locomotive_availability_table: Some(save_named_locomotive_table(112)),
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -5912,6 +6016,7 @@ mod tests {
name: "Locomotive 101".to_string(), name: "Locomotive 101".to_string(),
}, },
], ],
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -5938,6 +6043,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6033,6 +6139,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6107,6 +6214,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6191,6 +6299,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6294,6 +6403,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -6317,6 +6427,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6464,6 +6575,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6568,6 +6680,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6653,6 +6766,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6759,6 +6873,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6865,6 +6980,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -6961,6 +7077,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7053,6 +7170,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7153,6 +7271,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7244,6 +7363,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7317,6 +7437,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7395,6 +7516,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7478,6 +7600,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7561,6 +7684,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7660,6 +7784,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7750,6 +7875,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7866,6 +7992,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -7995,6 +8122,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8292,6 +8420,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8402,6 +8531,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8575,6 +8705,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8668,6 +8799,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8757,6 +8889,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -8911,6 +9044,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9054,6 +9188,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9144,6 +9279,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9261,6 +9397,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9366,6 +9503,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9474,6 +9612,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -9512,6 +9651,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),
@ -9656,6 +9796,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -9687,6 +9828,7 @@ mod tests {
candidate_availability_table: None, candidate_availability_table: None,
named_locomotive_availability_table: None, named_locomotive_availability_table: None,
locomotive_catalog: None, locomotive_catalog: None,
cargo_catalog: None,
special_conditions_table: None, special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(), source_kind: "packed-event-runtime-collection".to_string(),

View file

@ -35,29 +35,30 @@ pub use pk4::{
extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file, extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file,
}; };
pub use runtime::{ pub use runtime::{
RuntimeCompany, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, RuntimeCargoCatalogEntry, RuntimeCompany, RuntimeCompanyConditionTestScope,
RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess, RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget,
RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition, RuntimeConditionComparator, RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition,
RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
RuntimePackedEventCollectionSummary, RuntimePackedEventCompactControlSummary, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
RuntimePackedEventConditionRowSummary, RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
RuntimePackedEventNegativeSentinelScopeSummary, RuntimePackedEventRecordSummary, RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
RuntimePackedEventTextBandSummary, RuntimePlayer, RuntimePlayerConditionTestScope, RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
RuntimePlayerTarget, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, RuntimePlayerConditionTestScope, RuntimePlayerTarget, RuntimeSaveProfileState,
RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeServiceState, RuntimeState, RuntimeTerritory, RuntimeTerritoryMetric,
RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldRestoreState, RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, RuntimeTrain,
RuntimeWorldRestoreState,
}; };
pub use smp::{ pub use smp::{
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane, SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock, SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock,
SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe, SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe,
SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit, SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit,
SmpLoadedCandidateAvailabilityTable, SmpLoadedEventRuntimeCollectionSummary, SmpLoadedCandidateAvailabilityTable, SmpLoadedCargoCatalog, SmpLoadedCargoCatalogEntry,
SmpLoadedNamedLocomotiveAvailabilityTable, SmpLoadedPackedEventCompactControlSummary, SmpLoadedEventRuntimeCollectionSummary, SmpLoadedNamedLocomotiveAvailabilityTable,
SmpLoadedPackedEventConditionRowSummary, SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventCompactControlSummary, SmpLoadedPackedEventConditionRowSummary,
SmpLoadedPackedEventNegativeSentinelScopeSummary, SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventNegativeSentinelScopeSummary,
SmpLoadedPackedEventTextBandSummary, SmpLoadedProfile, SmpLoadedSaveSlice, SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventTextBandSummary, SmpLoadedProfile,
SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation, SmpLoadedSaveSlice, SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation,
SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe, SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe,
SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane, SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane,
SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe, SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe,

View file

@ -98,6 +98,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),

View file

@ -113,6 +113,16 @@ pub struct RuntimeLocomotiveCatalogEntry {
pub name: String, pub name: String,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeCargoCatalogEntry {
pub slot_id: u32,
pub label: String,
#[serde(default)]
pub supplied_token_stem: Option<String>,
#[serde(default)]
pub demanded_token_stem: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")] #[serde(tag = "kind", rename_all = "snake_case")]
pub enum RuntimeCompanyTarget { pub enum RuntimeCompanyTarget {
@ -533,6 +543,16 @@ pub struct RuntimePackedEventConditionRowSummary {
#[serde(default)] #[serde(default)]
pub requires_candidate_name_binding: bool, pub requires_candidate_name_binding: bool,
#[serde(default)] #[serde(default)]
pub recovered_cargo_slot: Option<u32>,
#[serde(default)]
pub recovered_cargo_class: Option<String>,
#[serde(default)]
pub recovered_cargo_label: Option<String>,
#[serde(default)]
pub recovered_cargo_supplied_token_stem: Option<String>,
#[serde(default)]
pub recovered_cargo_demanded_token_stem: Option<String>,
#[serde(default)]
pub notes: Vec<String>, pub notes: Vec<String>,
} }
@ -561,6 +581,16 @@ pub struct RuntimePackedEventGroupedEffectRowSummary {
#[serde(default)] #[serde(default)]
pub semantic_preview: Option<String>, pub semantic_preview: Option<String>,
#[serde(default)] #[serde(default)]
pub recovered_cargo_slot: Option<u32>,
#[serde(default)]
pub recovered_cargo_class: Option<String>,
#[serde(default)]
pub recovered_cargo_label: Option<String>,
#[serde(default)]
pub recovered_cargo_supplied_token_stem: Option<String>,
#[serde(default)]
pub recovered_cargo_demanded_token_stem: Option<String>,
#[serde(default)]
pub recovered_locomotive_id: Option<u32>, pub recovered_locomotive_id: Option<u32>,
#[serde(default)] #[serde(default)]
pub locomotive_name: Option<String>, pub locomotive_name: Option<String>,
@ -684,6 +714,8 @@ pub struct RuntimeState {
#[serde(default)] #[serde(default)]
pub locomotive_catalog: Vec<RuntimeLocomotiveCatalogEntry>, pub locomotive_catalog: Vec<RuntimeLocomotiveCatalogEntry>,
#[serde(default)] #[serde(default)]
pub cargo_catalog: Vec<RuntimeCargoCatalogEntry>,
#[serde(default)]
pub territories: Vec<RuntimeTerritory>, pub territories: Vec<RuntimeTerritory>,
#[serde(default)] #[serde(default)]
pub company_territory_track_piece_counts: Vec<RuntimeCompanyTerritoryTrackPieceCount>, pub company_territory_track_piece_counts: Vec<RuntimeCompanyTerritoryTrackPieceCount>,
@ -837,6 +869,28 @@ impl RuntimeState {
)); ));
} }
} }
let mut seen_cargo_slots = BTreeSet::new();
let mut seen_cargo_labels = BTreeSet::new();
for entry in &self.cargo_catalog {
if !(1..=11).contains(&entry.slot_id) {
return Err(format!(
"cargo_catalog entry has out-of-range slot_id {}",
entry.slot_id
));
}
if !seen_cargo_slots.insert(entry.slot_id) {
return Err(format!("duplicate cargo_catalog.slot_id {}", entry.slot_id));
}
if entry.label.trim().is_empty() {
return Err(format!(
"cargo_catalog entry {} has an empty label",
entry.slot_id
));
}
if !seen_cargo_labels.insert(entry.label.clone()) {
return Err(format!("duplicate cargo_catalog.label {:?}", entry.label));
}
}
for entry in &self.company_territory_track_piece_counts { for entry in &self.company_territory_track_piece_counts {
if !seen_company_ids.contains(&entry.company_id) { if !seen_company_ids.contains(&entry.company_id) {
return Err(format!( return Err(format!(
@ -1550,6 +1604,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1610,6 +1665,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1655,6 +1711,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1713,6 +1770,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1771,6 +1829,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1880,6 +1939,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1925,6 +1985,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1987,6 +2048,7 @@ mod tests {
}, },
], ],
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -2039,6 +2101,7 @@ mod tests {
retired: false, retired: false,
}], }],
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -2091,6 +2154,7 @@ mod tests {
retired: false, retired: false,
}], }],
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: vec![RuntimeTerritory { territories: vec![RuntimeTerritory {
territory_id: 1, territory_id: 1,
name: Some("Appalachia".to_string()), name: Some("Appalachia".to_string()),
@ -2147,6 +2211,7 @@ mod tests {
retired: true, retired: true,
}], }],
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -2192,6 +2257,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: vec![RuntimeTerritory { territories: vec![RuntimeTerritory {
territory_id: 7, territory_id: 7,
name: Some("Appalachia".to_string()), name: Some("Appalachia".to_string()),
@ -2250,6 +2316,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: vec![RuntimeTerritory { territories: vec![RuntimeTerritory {
territory_id: 7, territory_id: 7,
name: Some("Appalachia".to_string()), name: Some("Appalachia".to_string()),
@ -2302,6 +2369,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: vec![RuntimeTerritory { territories: vec![RuntimeTerritory {
territory_id: 7, territory_id: 7,
name: Some("Appalachia".to_string()), name: Some("Appalachia".to_string()),

View file

@ -1625,6 +1625,33 @@ pub struct SmpLoadedLocomotiveCatalog {
pub entries: Vec<SmpLoadedLocomotiveCatalogEntry>, pub entries: Vec<SmpLoadedLocomotiveCatalogEntry>,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedCargoCatalogEntry {
pub slot_id: u32,
pub label: String,
pub book_index: usize,
pub max_annual_production_word: u32,
pub mode_word: u32,
pub runtime_import_branch_kind: String,
pub annual_amount_word: u32,
pub supplied_cargo_token_word: u32,
#[serde(default)]
pub supplied_cargo_token_probable_high16_ascii_stem: Option<String>,
pub demanded_cargo_token_word: u32,
#[serde(default)]
pub demanded_cargo_token_probable_high16_ascii_stem: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedCargoCatalog {
pub source_kind: String,
pub semantic_family: String,
#[serde(default)]
pub root_offset: Option<usize>,
pub observed_entry_count: usize,
pub entries: Vec<SmpLoadedCargoCatalogEntry>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedSpecialConditionsTable { pub struct SmpLoadedSpecialConditionsTable {
pub source_kind: String, pub source_kind: String,
@ -1808,6 +1835,8 @@ pub struct SmpLoadedSaveSlice {
pub named_locomotive_availability_table: Option<SmpLoadedNamedLocomotiveAvailabilityTable>, pub named_locomotive_availability_table: Option<SmpLoadedNamedLocomotiveAvailabilityTable>,
#[serde(default)] #[serde(default)]
pub locomotive_catalog: Option<SmpLoadedLocomotiveCatalog>, pub locomotive_catalog: Option<SmpLoadedLocomotiveCatalog>,
#[serde(default)]
pub cargo_catalog: Option<SmpLoadedCargoCatalog>,
pub special_conditions_table: Option<SmpLoadedSpecialConditionsTable>, pub special_conditions_table: Option<SmpLoadedSpecialConditionsTable>,
pub event_runtime_collection: Option<SmpLoadedEventRuntimeCollectionSummary>, pub event_runtime_collection: Option<SmpLoadedEventRuntimeCollectionSummary>,
pub notes: Vec<String>, pub notes: Vec<String>,
@ -1972,6 +2001,10 @@ pub fn load_save_slice_from_report(
let locomotive_catalog = named_locomotive_availability_table let locomotive_catalog = named_locomotive_availability_table
.as_ref() .as_ref()
.and_then(derive_locomotive_catalog_from_named_availability_table); .and_then(derive_locomotive_catalog_from_named_availability_table);
let cargo_catalog = report
.recipe_book_summary_probe
.as_ref()
.and_then(derive_cargo_catalog_from_recipe_book_probe);
let special_conditions_table = let special_conditions_table =
report report
.special_conditions_probe .special_conditions_probe
@ -1996,6 +2029,7 @@ pub fn load_save_slice_from_report(
candidate_availability_table, candidate_availability_table,
named_locomotive_availability_table, named_locomotive_availability_table,
locomotive_catalog, locomotive_catalog,
cargo_catalog,
special_conditions_table, special_conditions_table,
event_runtime_collection: report.event_runtime_collection_summary.clone(), event_runtime_collection: report.event_runtime_collection_summary.clone(),
notes: summary.notes.clone(), notes: summary.notes.clone(),
@ -2028,6 +2062,57 @@ fn derive_locomotive_catalog_from_named_availability_table(
}) })
} }
fn derive_cargo_catalog_from_recipe_book_probe(
probe: &SmpRecipeBookSummaryProbe,
) -> Option<SmpLoadedCargoCatalog> {
if probe.books.is_empty() {
return None;
}
let entries = probe
.books
.iter()
.filter(|book| book.book_index < 11)
.filter_map(|book| {
let line = book
.lines
.iter()
.find(|line| line.imports_to_runtime_descriptor)
.or_else(|| book.lines.first())?;
let slot_id = (book.book_index + 1) as u32;
Some(SmpLoadedCargoCatalogEntry {
slot_id,
label: format!("Cargo Production Slot {slot_id}"),
book_index: book.book_index,
max_annual_production_word: book.max_annual_production_word,
mode_word: line.mode_word,
runtime_import_branch_kind: line.runtime_import_branch_kind.clone(),
annual_amount_word: line.annual_amount_word,
supplied_cargo_token_word: line.supplied_cargo_token_word,
supplied_cargo_token_probable_high16_ascii_stem: line
.supplied_cargo_token_probable_high16_ascii_stem
.clone(),
demanded_cargo_token_word: line.demanded_cargo_token_word,
demanded_cargo_token_probable_high16_ascii_stem: line
.demanded_cargo_token_probable_high16_ascii_stem
.clone(),
})
})
.collect::<Vec<_>>();
if entries.is_empty() {
return None;
}
Some(SmpLoadedCargoCatalog {
source_kind: format!("{}-slot-catalog", probe.source_kind),
semantic_family: "scenario-save-derived-cargo-catalog".to_string(),
root_offset: Some(probe.root_offset),
observed_entry_count: entries.len(),
entries,
})
}
fn parse_event_runtime_collection_summary( fn parse_event_runtime_collection_summary(
bytes: &[u8], bytes: &[u8],
container_profile: Option<&SmpContainerProfile>, container_profile: Option<&SmpContainerProfile>,

View file

@ -1249,6 +1249,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),

View file

@ -37,6 +37,7 @@ pub struct RuntimeSummary {
pub active_train_count: usize, pub active_train_count: usize,
pub retired_train_count: usize, pub retired_train_count: usize,
pub locomotive_catalog_count: usize, pub locomotive_catalog_count: usize,
pub cargo_catalog_count: usize,
pub territory_count: usize, pub territory_count: usize,
pub company_territory_track_count: usize, pub company_territory_track_count: usize,
pub packed_event_collection_present: bool, pub packed_event_collection_present: bool,
@ -172,6 +173,7 @@ impl RuntimeSummary {
active_train_count: state.trains.iter().filter(|train| train.active).count(), active_train_count: state.trains.iter().filter(|train| train.active).count(),
retired_train_count: state.trains.iter().filter(|train| train.retired).count(), retired_train_count: state.trains.iter().filter(|train| train.retired).count(),
locomotive_catalog_count: state.locomotive_catalog.len(), locomotive_catalog_count: state.locomotive_catalog.len(),
cargo_catalog_count: state.cargo_catalog.len(),
territory_count: state.territories.len(), territory_count: state.territories.len(),
company_territory_track_count: state.company_territory_track_piece_counts.len(), company_territory_track_count: state.company_territory_track_piece_counts.len(),
packed_event_collection_present: state.packed_event_collection.is_some(), packed_event_collection_present: state.packed_event_collection.is_some(),
@ -675,6 +677,7 @@ mod tests {
name: "Locomotive 112".to_string(), name: "Locomotive 112".to_string(),
}, },
], ],
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -917,6 +920,7 @@ mod tests {
name: "Locomotive 112".to_string(), name: "Locomotive 112".to_string(),
}, },
], ],
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -963,6 +967,7 @@ mod tests {
name: "Locomotive 112".to_string(), name: "Locomotive 112".to_string(),
}, },
], ],
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1006,6 +1011,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1049,6 +1055,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1087,6 +1094,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),
@ -1194,6 +1202,7 @@ mod tests {
selected_player_id: None, selected_player_id: None,
trains: Vec::new(), trains: Vec::new(),
locomotive_catalog: Vec::new(), locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(), territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(), company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(), company_territory_access: Vec::new(),

View file

@ -138,12 +138,16 @@ The highest-value next passes are now:
- cargo-production `230..240` and territory-access-cost `453` now execute too through minimal - cargo-production `230..240` and territory-access-cost `453` now execute too through minimal
world-side scalar landing surfaces: slot-indexed `cargo_production_overrides` and world-side scalar landing surfaces: slot-indexed `cargo_production_overrides` and
`world_restore.territory_access_cost` `world_restore.territory_access_cost`
- recipe-book probing now derives a save-native `cargo_catalog` too, so save-slice documents carry
stable cargo slot labels and token-stem evidence into runtime state without requiring a separate
cargo simulation layer
- world-scalar ordinary-condition coverage now matches those runtime surfaces too: checked-in - world-scalar ordinary-condition coverage now matches those runtime surfaces too: checked-in
metadata lowers named locomotive availability, named locomotive cost, named cargo-production metadata lowers named locomotive availability, named locomotive cost, named cargo-production
slot thresholds, aggregate cargo production, limited-track-building-amount, and slot thresholds, aggregate cargo production, limited-track-building-amount, and
territory-access-cost rows into explicit runtime condition gates territory-access-cost rows into explicit runtime condition gates
- the remaining world-scalar condition frontier is now narrow and explicit: unsupported families - the remaining world-scalar condition frontier is now narrow and explicit: unsupported families
such as `All Factory Production` stay parity-only on `blocked_unmapped_world_condition` such as `All Factory Production` stay parity-only on `blocked_unmapped_world_condition`; the
remaining cargo frontier is slot-to-class classification, not save/import plumbing
- keep in mind that the current local `.gms` corpus still exports with no packed event collection, - keep in mind that the current local `.gms` corpus still exports with no packed event collection,
so real descriptor mapping needs to stay plumbing-first until better captures exist so real descriptor mapping needs to stay plumbing-first until better captures exist
- use `rrt-hook` primarily as optional capture or integration tooling, not as the first execution - use `rrt-hook` primarily as optional capture or integration tooling, not as the first execution

View file

@ -97,12 +97,16 @@ Implemented today:
- the remaining recovered scalar world families now execute as well: cargo-production `230..240` - the remaining recovered scalar world families now execute as well: cargo-production `230..240`
rows lower into slot-indexed `cargo_production_overrides`, and territory-access-cost descriptor rows lower into slot-indexed `cargo_production_overrides`, and territory-access-cost descriptor
`453` lowers into `world_restore.territory_access_cost` `453` lowers into `world_restore.territory_access_cost`
- cargo slot identity is now save-native as well: the recipe-book probe derives a bounded
`cargo_catalog` into save-slice documents and runtime state, so cargo descriptors and
`%1 Production` conditions can expose stable slot metadata without a live cargo simulation layer
- world-scalar ordinary-condition coverage now aligns with those runtime surfaces too: checked-in - world-scalar ordinary-condition coverage now aligns with those runtime surfaces too: checked-in
metadata lowers named locomotive availability, named locomotive cost, named cargo-production metadata lowers named locomotive availability, named locomotive cost, named cargo-production
slot thresholds, aggregate cargo production, limited-track-building-amount, and slot thresholds, aggregate cargo production, limited-track-building-amount, and
territory-access-cost rows into explicit runtime condition gates territory-access-cost rows into explicit runtime condition gates
- the remaining world-side condition frontier is now narrower and more honest: unsupported scalar - the remaining world-side condition frontier is now narrower and more honest: unsupported scalar
families such as `All Factory Production` stay visible on `blocked_unmapped_world_condition` families such as `All Factory Production` stay visible on `blocked_unmapped_world_condition`;
the remaining cargo frontier is slot classification rather than missing save/import context
instead of falling back to generic placeholder ids instead of falling back to generic placeholder ids
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

View file

@ -0,0 +1,44 @@
{
"format_version": 1,
"fixture_id": "packed-event-cargo-catalog-save-slice-fixture",
"source": {
"kind": "captured-runtime",
"description": "Fixture proving recipe-book-derived cargo catalog context imports into runtime state even without executable event records."
},
"state_save_slice_path": "packed-event-cargo-catalog-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,
"world_flag_count": 8,
"cargo_catalog_count": 11,
"packed_event_collection_present": false,
"event_runtime_record_count": 0
},
"expected_state_fragment": {
"cargo_catalog": [
{
"slot_id": 1,
"label": "Cargo Production Slot 1"
},
{
"slot_id": 2,
"label": "Cargo Production Slot 2"
}
],
"metadata": {
"save_slice.cargo_catalog_source_kind": "recipe-book-summary-slot-catalog",
"save_slice.cargo_catalog_entry_count": "11"
}
}
}

View file

@ -0,0 +1,48 @@
{
"format_version": 1,
"save_slice_id": "packed-event-cargo-catalog-save-slice",
"source": {
"description": "Tracked save-slice document proving save-native cargo catalog export/import without executable packed-event commands.",
"original_save_filename": "captured-cargo-catalog.gms",
"original_save_sha256": "cargo-catalog-sample-sha256",
"notes": [
"tracked as JSON save-slice document rather than raw .smp",
"pins the save-native recipe-book-derived cargo catalog surface independently of event execution"
]
},
"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,
"cargo_catalog": {
"source_kind": "recipe-book-summary-slot-catalog",
"semantic_family": "scenario-save-derived-cargo-catalog",
"root_offset": 4071,
"observed_entry_count": 11,
"entries": [
{ "slot_id": 1, "label": "Cargo Production Slot 1", "book_index": 0, "max_annual_production_word": 0, "mode_word": 1114112, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 2, "label": "Cargo Production Slot 2", "book_index": 1, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 3, "label": "Cargo Production Slot 3", "book_index": 2, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 4, "label": "Cargo Production Slot 4", "book_index": 3, "max_annual_production_word": 0, "mode_word": 1245184, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 5, "label": "Cargo Production Slot 5", "book_index": 4, "max_annual_production_word": 0, "mode_word": 1572864, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 6, "label": "Cargo Production Slot 6", "book_index": 5, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 7, "label": "Cargo Production Slot 7", "book_index": 6, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 8, "label": "Cargo Production Slot 8", "book_index": 7, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 9, "label": "Cargo Production Slot 9", "book_index": 8, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 10, "label": "Cargo Production Slot 10", "book_index": 9, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 11, "label": "Cargo Production Slot 11", "book_index": 10, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null }
]
},
"special_conditions_table": null,
"event_runtime_collection": null,
"notes": [
"cargo catalog only sample"
]
}
}

View file

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

View file

@ -26,6 +26,7 @@
"packed_event_imported_runtime_record_count": 2, "packed_event_imported_runtime_record_count": 2,
"packed_event_parity_only_record_count": 3, "packed_event_parity_only_record_count": 3,
"packed_event_unsupported_record_count": 0, "packed_event_unsupported_record_count": 0,
"cargo_catalog_count": 11,
"packed_event_blocked_missing_locomotive_catalog_context_count": 0, "packed_event_blocked_missing_locomotive_catalog_context_count": 0,
"packed_event_blocked_missing_condition_context_count": 0, "packed_event_blocked_missing_condition_context_count": 0,
"packed_event_blocked_territory_condition_scope_count": 0, "packed_event_blocked_territory_condition_scope_count": 0,
@ -52,6 +53,8 @@
{ {
"descriptor_id": 230, "descriptor_id": 230,
"descriptor_label": "Cargo Production Slot 1", "descriptor_label": "Cargo Production Slot 1",
"recovered_cargo_slot": 1,
"recovered_cargo_label": "Cargo Production Slot 1",
"target_mask_bits": 8, "target_mask_bits": 8,
"parameter_family": "cargo_production_scalar", "parameter_family": "cargo_production_scalar",
"semantic_family": "scalar_assignment", "semantic_family": "scalar_assignment",

View file

@ -20,6 +20,25 @@
"profile": null, "profile": null,
"candidate_availability_table": null, "candidate_availability_table": null,
"named_locomotive_availability_table": null, "named_locomotive_availability_table": null,
"cargo_catalog": {
"source_kind": "recipe-book-summary-slot-catalog",
"semantic_family": "scenario-save-derived-cargo-catalog",
"root_offset": 4071,
"observed_entry_count": 11,
"entries": [
{ "slot_id": 1, "label": "Cargo Production Slot 1", "book_index": 0, "max_annual_production_word": 0, "mode_word": 1114112, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 2, "label": "Cargo Production Slot 2", "book_index": 1, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 3, "label": "Cargo Production Slot 3", "book_index": 2, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 4, "label": "Cargo Production Slot 4", "book_index": 3, "max_annual_production_word": 0, "mode_word": 1245184, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 5, "label": "Cargo Production Slot 5", "book_index": 4, "max_annual_production_word": 0, "mode_word": 1572864, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 6, "label": "Cargo Production Slot 6", "book_index": 5, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 7, "label": "Cargo Production Slot 7", "book_index": 6, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 8, "label": "Cargo Production Slot 8", "book_index": 7, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 9, "label": "Cargo Production Slot 9", "book_index": 8, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 10, "label": "Cargo Production Slot 10", "book_index": 9, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 11, "label": "Cargo Production Slot 11", "book_index": 10, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null }
]
},
"special_conditions_table": null, "special_conditions_table": null,
"event_runtime_collection": { "event_runtime_collection": {
"source_kind": "packed-event-runtime-collection", "source_kind": "packed-event-runtime-collection",

View file

@ -18,17 +18,24 @@
"packed_event_decoded_record_count": 1, "packed_event_decoded_record_count": 1,
"packed_event_imported_runtime_record_count": 0, "packed_event_imported_runtime_record_count": 0,
"packed_event_parity_only_record_count": 1, "packed_event_parity_only_record_count": 1,
"packed_event_blocked_unmapped_world_descriptor_count": 1, "packed_event_blocked_unmapped_world_condition_count": 1,
"cargo_catalog_count": 11,
"event_runtime_record_count": 0, "event_runtime_record_count": 0,
"world_flag_count": 7, "world_flag_count": 8,
"total_event_record_service_count": 0, "total_event_record_service_count": 0,
"total_trigger_dispatch_count": 1 "total_trigger_dispatch_count": 1
}, },
"expected_state_fragment": { "expected_state_fragment": {
"cargo_catalog": [
{
"slot_id": 1,
"label": "Cargo Production Slot 1"
}
],
"packed_event_collection": { "packed_event_collection": {
"records": [ "records": [
{ {
"import_outcome": "blocked_unmapped_world_descriptor", "import_outcome": "blocked_unmapped_world_condition",
"standalone_condition_rows": [ "standalone_condition_rows": [
{ {
"raw_condition_id": 2419, "raw_condition_id": 2419,

View file

@ -20,6 +20,25 @@
"profile": null, "profile": null,
"candidate_availability_table": null, "candidate_availability_table": null,
"named_locomotive_availability_table": null, "named_locomotive_availability_table": null,
"cargo_catalog": {
"source_kind": "recipe-book-summary-slot-catalog",
"semantic_family": "scenario-save-derived-cargo-catalog",
"root_offset": 4071,
"observed_entry_count": 11,
"entries": [
{ "slot_id": 1, "label": "Cargo Production Slot 1", "book_index": 0, "max_annual_production_word": 0, "mode_word": 1114112, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 2, "label": "Cargo Production Slot 2", "book_index": 1, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 3, "label": "Cargo Production Slot 3", "book_index": 2, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 4, "label": "Cargo Production Slot 4", "book_index": 3, "max_annual_production_word": 0, "mode_word": 1245184, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 5, "label": "Cargo Production Slot 5", "book_index": 4, "max_annual_production_word": 0, "mode_word": 1572864, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 6, "label": "Cargo Production Slot 6", "book_index": 5, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 7, "label": "Cargo Production Slot 7", "book_index": 6, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 8, "label": "Cargo Production Slot 8", "book_index": 7, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 9, "label": "Cargo Production Slot 9", "book_index": 8, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 10, "label": "Cargo Production Slot 10", "book_index": 9, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 11, "label": "Cargo Production Slot 11", "book_index": 10, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null }
]
},
"special_conditions_table": null, "special_conditions_table": null,
"event_runtime_collection": { "event_runtime_collection": {
"source_kind": "packed-event-runtime-collection", "source_kind": "packed-event-runtime-collection",

View file

@ -22,13 +22,14 @@
"packed_event_decoded_record_count": 2, "packed_event_decoded_record_count": 2,
"packed_event_imported_runtime_record_count": 2, "packed_event_imported_runtime_record_count": 2,
"event_runtime_record_count": 2, "event_runtime_record_count": 2,
"cargo_catalog_count": 11,
"named_locomotive_availability_count": 1, "named_locomotive_availability_count": 1,
"zero_named_locomotive_availability_count": 0, "zero_named_locomotive_availability_count": 0,
"named_locomotive_cost_count": 1, "named_locomotive_cost_count": 1,
"cargo_production_override_count": 1, "cargo_production_override_count": 1,
"world_restore_limited_track_building_amount": 18, "world_restore_limited_track_building_amount": 18,
"world_restore_territory_access_cost": 750000, "world_restore_territory_access_cost": 750000,
"world_flag_count": 8, "world_flag_count": 9,
"total_event_record_service_count": 2, "total_event_record_service_count": 2,
"total_trigger_dispatch_count": 2 "total_trigger_dispatch_count": 2
}, },
@ -49,6 +50,12 @@
"cargo_production_overrides": { "cargo_production_overrides": {
"1": 125 "1": 125
}, },
"cargo_catalog": [
{
"slot_id": 1,
"label": "Cargo Production Slot 1"
}
],
"packed_event_collection": { "packed_event_collection": {
"records": [ "records": [
{ {

View file

@ -20,6 +20,25 @@
"profile": null, "profile": null,
"candidate_availability_table": null, "candidate_availability_table": null,
"named_locomotive_availability_table": null, "named_locomotive_availability_table": null,
"cargo_catalog": {
"source_kind": "recipe-book-summary-slot-catalog",
"semantic_family": "scenario-save-derived-cargo-catalog",
"root_offset": 4071,
"observed_entry_count": 11,
"entries": [
{ "slot_id": 1, "label": "Cargo Production Slot 1", "book_index": 0, "max_annual_production_word": 0, "mode_word": 1114112, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 2, "label": "Cargo Production Slot 2", "book_index": 1, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 3, "label": "Cargo Production Slot 3", "book_index": 2, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 4, "label": "Cargo Production Slot 4", "book_index": 3, "max_annual_production_word": 0, "mode_word": 1245184, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 5, "label": "Cargo Production Slot 5", "book_index": 4, "max_annual_production_word": 0, "mode_word": 1572864, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 6, "label": "Cargo Production Slot 6", "book_index": 5, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 7, "label": "Cargo Production Slot 7", "book_index": 6, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 8, "label": "Cargo Production Slot 8", "book_index": 7, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 9, "label": "Cargo Production Slot 9", "book_index": 8, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 10, "label": "Cargo Production Slot 10", "book_index": 9, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 11, "label": "Cargo Production Slot 11", "book_index": 10, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null }
]
},
"special_conditions_table": null, "special_conditions_table": null,
"event_runtime_collection": { "event_runtime_collection": {
"source_kind": "packed-event-runtime-collection", "source_kind": "packed-event-runtime-collection",

View file

@ -25,6 +25,7 @@
"packed_event_decoded_record_count": 1, "packed_event_decoded_record_count": 1,
"packed_event_imported_runtime_record_count": 1, "packed_event_imported_runtime_record_count": 1,
"packed_event_parity_only_record_count": 1, "packed_event_parity_only_record_count": 1,
"cargo_catalog_count": 11,
"packed_event_blocked_unmapped_world_descriptor_count": 0, "packed_event_blocked_unmapped_world_descriptor_count": 0,
"event_runtime_record_count": 1, "event_runtime_record_count": 1,
"cargo_production_override_count": 1, "cargo_production_override_count": 1,

View file

@ -20,6 +20,25 @@
"profile": null, "profile": null,
"candidate_availability_table": null, "candidate_availability_table": null,
"named_locomotive_availability_table": null, "named_locomotive_availability_table": null,
"cargo_catalog": {
"source_kind": "recipe-book-summary-slot-catalog",
"semantic_family": "scenario-save-derived-cargo-catalog",
"root_offset": 4071,
"observed_entry_count": 11,
"entries": [
{ "slot_id": 1, "label": "Cargo Production Slot 1", "book_index": 0, "max_annual_production_word": 0, "mode_word": 1114112, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 2, "label": "Cargo Production Slot 2", "book_index": 1, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 3, "label": "Cargo Production Slot 3", "book_index": 2, "max_annual_production_word": 0, "mode_word": 720896, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 4, "label": "Cargo Production Slot 4", "book_index": 3, "max_annual_production_word": 0, "mode_word": 1245184, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 5, "label": "Cargo Production Slot 5", "book_index": 4, "max_annual_production_word": 0, "mode_word": 1572864, "runtime_import_branch_kind": "nonzero-supply-branch", "annual_amount_word": 0, "supplied_cargo_token_word": 16544, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 6, "label": "Cargo Production Slot 6", "book_index": 5, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 7, "label": "Cargo Production Slot 7", "book_index": 6, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 8, "label": "Cargo Production Slot 8", "book_index": 7, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 9, "label": "Cargo Production Slot 9", "book_index": 8, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 10, "label": "Cargo Production Slot 10", "book_index": 9, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null },
{ "slot_id": 11, "label": "Cargo Production Slot 11", "book_index": 10, "max_annual_production_word": 0, "mode_word": 0, "runtime_import_branch_kind": "zero-mode-skipped", "annual_amount_word": 0, "supplied_cargo_token_word": 0, "supplied_cargo_token_probable_high16_ascii_stem": null, "demanded_cargo_token_word": 0, "demanded_cargo_token_probable_high16_ascii_stem": null }
]
},
"special_conditions_table": null, "special_conditions_table": null,
"event_runtime_collection": { "event_runtime_collection": {
"source_kind": "packed-event-runtime-collection", "source_kind": "packed-event-runtime-collection",