diff --git a/README.md b/README.md index 4107edf..e1b910a 100644 --- a/README.md +++ b/README.md @@ -61,17 +61,17 @@ catalog context. The remaining recovered scalar world families execute too: carg `world_restore.territory_access_cost`. Whole-game ordinary-condition breadth now aligns with those same world-scalar runtime surfaces too: named locomotive availability thresholds, named locomotive cost thresholds, named cargo-production slot thresholds, aggregate cargo-production -thresholds, limited-track-building-amount thresholds, and territory-access-cost thresholds all -gate imported runtime records through the same service path. Families the current checked-in -metadata still does not ground, such as `All Factory Production`, now remain explicitly visible on -`blocked_unmapped_world_condition` rather than collapsing back to generic residue. Explicit +thresholds, factory/farm-mine/other cargo-production thresholds, limited-track-building-amount +thresholds, and territory-access-cost thresholds all gate imported runtime records through the +same service path. Explicit unmapped world-condition and world-descriptor frontier buckets still remain where current checked-in metadata stops, and `blocked_missing_locomotive_catalog_context` is now reserved for intentionally incomplete save-side -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, +catalog context instead of the normal save-slice path. Cargo slot identity and class metadata are +now save-native too: the recipe-book probe lowers into `RuntimeState.cargo_catalog`, so save-slice +documents can carry slot labels, class tags, 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 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. diff --git a/crates/rrt-runtime/src/import.rs b/crates/rrt-runtime/src/import.rs index e720a62..6d417af 100644 --- a/crates/rrt-runtime/src/import.rs +++ b/crates/rrt-runtime/src/import.rs @@ -725,6 +725,7 @@ fn project_save_slice_components( .map(|entry| RuntimeCargoCatalogEntry { slot_id: entry.slot_id, label: entry.label.clone(), + cargo_class: entry.cargo_class, supplied_token_stem: entry .supplied_cargo_token_probable_high16_ascii_stem .clone(), @@ -977,7 +978,10 @@ fn runtime_packed_event_condition_row_summary_from_smp( semantic_preview: row.semantic_preview.clone(), 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_class: cargo_entry + .map(|entry| format!("{:?}", entry.cargo_class).to_ascii_lowercase()) + .map(|value| value.replace("farmmine", "farm_mine")) + .or_else(|| 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)), @@ -1015,7 +1019,10 @@ fn runtime_packed_event_grouped_effect_row_summary_from_smp( semantic_family: row.semantic_family.clone(), semantic_preview: row.semantic_preview.clone(), recovered_cargo_slot: row.recovered_cargo_slot, - recovered_cargo_class: row.recovered_cargo_class.clone(), + recovered_cargo_class: cargo_entry + .map(|entry| format!("{:?}", entry.cargo_class).to_ascii_lowercase()) + .map(|value| value.replace("farmmine", "farm_mine")) + .or_else(|| 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)), @@ -1663,6 +1670,24 @@ fn lower_condition_targets_in_condition( value: *value, } } + RuntimeCondition::FactoryProductionTotalThreshold { comparator, value } => { + RuntimeCondition::FactoryProductionTotalThreshold { + comparator: *comparator, + value: *value, + } + } + RuntimeCondition::FarmMineProductionTotalThreshold { comparator, value } => { + RuntimeCondition::FarmMineProductionTotalThreshold { + comparator: *comparator, + value: *value, + } + } + RuntimeCondition::OtherCargoProductionTotalThreshold { comparator, value } => { + RuntimeCondition::OtherCargoProductionTotalThreshold { + comparator: *comparator, + value: *value, + } + } RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator, value } => { RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator: *comparator, @@ -1768,6 +1793,9 @@ fn condition_uses_condition_true_company(condition: &RuntimeCondition) -> bool { | RuntimeCondition::NamedLocomotiveCostThreshold { .. } | RuntimeCondition::CargoProductionSlotThreshold { .. } | RuntimeCondition::CargoProductionTotalThreshold { .. } + | RuntimeCondition::FactoryProductionTotalThreshold { .. } + | RuntimeCondition::FarmMineProductionTotalThreshold { .. } + | RuntimeCondition::OtherCargoProductionTotalThreshold { .. } | RuntimeCondition::LimitedTrackBuildingAmountThreshold { .. } | RuntimeCondition::TerritoryAccessCostThreshold { .. } | RuntimeCondition::EconomicStatusCodeThreshold { .. } @@ -2391,6 +2419,9 @@ fn runtime_condition_is_world_state(condition: &RuntimeCondition) -> bool { | RuntimeCondition::NamedLocomotiveCostThreshold { .. } | RuntimeCondition::CargoProductionSlotThreshold { .. } | RuntimeCondition::CargoProductionTotalThreshold { .. } + | RuntimeCondition::FactoryProductionTotalThreshold { .. } + | RuntimeCondition::FarmMineProductionTotalThreshold { .. } + | RuntimeCondition::OtherCargoProductionTotalThreshold { .. } | RuntimeCondition::LimitedTrackBuildingAmountThreshold { .. } | RuntimeCondition::TerritoryAccessCostThreshold { .. } | RuntimeCondition::EconomicStatusCodeThreshold { .. } @@ -2489,6 +2520,9 @@ fn runtime_condition_company_target_import_blocker( | RuntimeCondition::NamedLocomotiveCostThreshold { .. } | RuntimeCondition::CargoProductionSlotThreshold { .. } | RuntimeCondition::CargoProductionTotalThreshold { .. } + | RuntimeCondition::FactoryProductionTotalThreshold { .. } + | RuntimeCondition::FarmMineProductionTotalThreshold { .. } + | RuntimeCondition::OtherCargoProductionTotalThreshold { .. } | RuntimeCondition::LimitedTrackBuildingAmountThreshold { .. } | RuntimeCondition::TerritoryAccessCostThreshold { .. } | RuntimeCondition::EconomicStatusCodeThreshold { .. } @@ -3532,12 +3566,49 @@ mod tests { } } + fn save_cargo_catalog( + entries: &[(u32, crate::RuntimeCargoClass)], + ) -> crate::SmpLoadedCargoCatalog { + crate::SmpLoadedCargoCatalog { + source_kind: "recipe-book-summary-slot-catalog".to_string(), + semantic_family: "scenario-save-derived-cargo-catalog".to_string(), + root_offset: Some(0x0fe7), + observed_entry_count: entries.len(), + entries: entries + .iter() + .enumerate() + .map( + |(index, (slot_id, cargo_class))| crate::SmpLoadedCargoCatalogEntry { + slot_id: *slot_id, + label: format!("Cargo Production Slot {slot_id}"), + cargo_class: *cargo_class, + book_index: index, + max_annual_production_word: 0, + mode_word: 0, + runtime_import_branch_kind: "zero-mode-skipped".to_string(), + annual_amount_word: 0, + supplied_cargo_token_word: 0, + supplied_cargo_token_probable_high16_ascii_stem: None, + demanded_cargo_token_word: 0, + demanded_cargo_token_probable_high16_ascii_stem: None, + }, + ) + .collect(), + } + } + fn real_cargo_production_row( descriptor_id: u32, value: i32, ) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary { let slot = descriptor_id.saturating_sub(229); let descriptor_label = format!("Cargo Production Slot {slot}"); + let recovered_cargo_class = match slot { + 1..=4 => Some("factory".to_string()), + 5..=8 => Some("farm_mine".to_string()), + 9..=11 => Some("other".to_string()), + _ => None, + }; crate::SmpLoadedPackedEventGroupedEffectRowSummary { group_index: 0, row_index: 0, @@ -3557,7 +3628,7 @@ mod tests { semantic_family: Some("scalar_assignment".to_string()), semantic_preview: Some(format!("Set {descriptor_label} to {value}")), recovered_cargo_slot: Some(slot), - recovered_cargo_class: None, + recovered_cargo_class, recovered_locomotive_id: None, locomotive_name: None, notes: vec![], @@ -3957,7 +4028,11 @@ mod tests { }, ), locomotive_catalog: None, - cargo_catalog: None, + cargo_catalog: Some(save_cargo_catalog(&[ + (1, crate::RuntimeCargoClass::Factory), + (5, crate::RuntimeCargoClass::FarmMine), + (9, crate::RuntimeCargoClass::Other), + ])), special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable { source_kind: "save-fixed-special-conditions-range".to_string(), table_offset: 0x0d64, @@ -4283,7 +4358,11 @@ mod tests { candidate_availability_table: None, named_locomotive_availability_table: None, locomotive_catalog: None, - cargo_catalog: None, + cargo_catalog: Some(save_cargo_catalog(&[ + (1, crate::RuntimeCargoClass::Factory), + (5, crate::RuntimeCargoClass::FarmMine), + (9, crate::RuntimeCargoClass::Other), + ])), special_conditions_table: None, event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { source_kind: "packed-event-runtime-collection".to_string(), @@ -4399,7 +4478,11 @@ mod tests { candidate_availability_table: None, named_locomotive_availability_table: None, locomotive_catalog: None, - cargo_catalog: None, + cargo_catalog: Some(save_cargo_catalog(&[ + (1, crate::RuntimeCargoClass::Factory), + (5, crate::RuntimeCargoClass::FarmMine), + (9, crate::RuntimeCargoClass::Other), + ])), special_conditions_table: None, event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { source_kind: "packed-event-runtime-collection".to_string(), @@ -4493,7 +4576,11 @@ mod tests { candidate_availability_table: None, named_locomotive_availability_table: None, locomotive_catalog: None, - cargo_catalog: None, + cargo_catalog: Some(save_cargo_catalog(&[ + (1, crate::RuntimeCargoClass::Factory), + (5, crate::RuntimeCargoClass::FarmMine), + (9, crate::RuntimeCargoClass::Other), + ])), special_conditions_table: None, event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { source_kind: "packed-event-runtime-collection".to_string(), @@ -8122,7 +8209,11 @@ mod tests { candidate_availability_table: None, named_locomotive_availability_table: None, locomotive_catalog: None, - cargo_catalog: None, + cargo_catalog: Some(save_cargo_catalog(&[ + (1, crate::RuntimeCargoClass::Factory), + (5, crate::RuntimeCargoClass::FarmMine), + (9, crate::RuntimeCargoClass::Other), + ])), special_conditions_table: None, event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary { source_kind: "packed-event-runtime-collection".to_string(), @@ -8156,11 +8247,13 @@ mod tests { standalone_condition_row_count: 0, standalone_condition_rows: vec![], negative_sentinel_scope: None, - grouped_effect_row_counts: vec![5, 0, 0, 0], + grouped_effect_row_counts: vec![7, 0, 0, 0], grouped_effect_rows: vec![ real_locomotive_availability_row(250, 42), real_locomotive_cost_row(352, 250000), real_cargo_production_row(230, 125), + real_cargo_production_row(234, 75), + real_cargo_production_row(238, 30), real_limited_track_building_amount_row(18), real_territory_access_cost_row(750000), ], @@ -8178,6 +8271,8 @@ mod tests { slot: 1, value: 125, }, + RuntimeEffect::SetCargoProductionSlot { slot: 5, value: 75 }, + RuntimeEffect::SetCargoProductionSlot { slot: 9, value: 30 }, RuntimeEffect::SetLimitedTrackBuildingAmount { value: 18 }, RuntimeEffect::SetTerritoryAccessCost { value: 750000 }, ], @@ -8197,7 +8292,7 @@ mod tests { one_shot: Some(false), compact_control: Some(real_compact_control()), text_bands: packed_text_bands(), - standalone_condition_row_count: 6, + standalone_condition_row_count: 9, standalone_condition_rows: vec![ crate::SmpLoadedPackedEventConditionRowSummary { row_index: 0, @@ -8262,7 +8357,7 @@ mod tests { .to_string(), ), recovered_cargo_slot: Some(1), - recovered_cargo_class: None, + recovered_cargo_class: Some("factory".to_string()), requires_candidate_name_binding: false, notes: vec![], }, @@ -8280,7 +8375,7 @@ mod tests { metric: Some("Cargo Production Total".to_string()), semantic_family: Some("world_scalar_threshold".to_string()), semantic_preview: Some( - "Test Cargo Production Total == 125".to_string(), + "Test Cargo Production Total == 230".to_string(), ), recovered_cargo_slot: None, recovered_cargo_class: None, @@ -8289,6 +8384,69 @@ mod tests { }, crate::SmpLoadedPackedEventConditionRowSummary { row_index: 4, + raw_condition_id: 2419, + subtype: 4, + flag_bytes: { + let mut bytes = vec![0; 25]; + bytes[0..4].copy_from_slice(&125_i32.to_le_bytes()); + bytes + }, + candidate_name: None, + comparator: Some("eq".to_string()), + metric: Some("Factory Production Total".to_string()), + semantic_family: Some("world_scalar_threshold".to_string()), + semantic_preview: Some( + "Test Factory Production Total == 125".to_string(), + ), + recovered_cargo_slot: None, + recovered_cargo_class: Some("factory".to_string()), + requires_candidate_name_binding: false, + notes: vec![], + }, + crate::SmpLoadedPackedEventConditionRowSummary { + row_index: 5, + raw_condition_id: 2420, + subtype: 4, + flag_bytes: { + let mut bytes = vec![0; 25]; + bytes[0..4].copy_from_slice(&75_i32.to_le_bytes()); + bytes + }, + candidate_name: None, + comparator: Some("eq".to_string()), + metric: Some("Farm/Mine Production Total".to_string()), + semantic_family: Some("world_scalar_threshold".to_string()), + semantic_preview: Some( + "Test Farm/Mine Production Total == 75".to_string(), + ), + recovered_cargo_slot: None, + recovered_cargo_class: Some("farm_mine".to_string()), + requires_candidate_name_binding: false, + notes: vec![], + }, + crate::SmpLoadedPackedEventConditionRowSummary { + row_index: 6, + raw_condition_id: 2421, + subtype: 4, + flag_bytes: { + let mut bytes = vec![0; 25]; + bytes[0..4].copy_from_slice(&30_i32.to_le_bytes()); + bytes + }, + candidate_name: None, + comparator: Some("eq".to_string()), + metric: Some("Other Cargo Production Total".to_string()), + semantic_family: Some("world_scalar_threshold".to_string()), + semantic_preview: Some( + "Test Other Cargo Production Total == 30".to_string(), + ), + recovered_cargo_slot: None, + recovered_cargo_class: Some("other".to_string()), + requires_candidate_name_binding: false, + notes: vec![], + }, + crate::SmpLoadedPackedEventConditionRowSummary { + row_index: 7, raw_condition_id: 2547, subtype: 4, flag_bytes: { @@ -8309,7 +8467,7 @@ mod tests { notes: vec![], }, crate::SmpLoadedPackedEventConditionRowSummary { - row_index: 5, + row_index: 8, raw_condition_id: 1516, subtype: 4, flag_bytes: { @@ -8355,9 +8513,21 @@ mod tests { value: 125, }, RuntimeCondition::CargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 230, + }, + RuntimeCondition::FactoryProductionTotalThreshold { comparator: RuntimeConditionComparator::Eq, value: 125, }, + RuntimeCondition::FarmMineProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 75, + }, + RuntimeCondition::OtherCargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 30, + }, RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator: RuntimeConditionComparator::Eq, value: 18, @@ -8391,6 +8561,76 @@ mod tests { &crate::StepCommand::ServiceTriggerKind { trigger_kind: 6 }, ) .expect("setup trigger should execute"); + assert_eq!( + import.state.named_locomotive_availability.get("Big Boy"), + Some(&42) + ); + assert_eq!( + import.state.named_locomotive_cost.get("Locomotive 1"), + Some(&250000) + ); + assert_eq!(import.state.cargo_production_overrides.get(&1), Some(&125)); + assert_eq!(import.state.cargo_production_overrides.get(&5), Some(&75)); + assert_eq!(import.state.cargo_production_overrides.get(&9), Some(&30)); + assert_eq!(import.state.cargo_catalog.len(), 3); + assert_eq!( + import.state.cargo_catalog[0].cargo_class, + crate::RuntimeCargoClass::Factory + ); + assert_eq!( + import.state.cargo_catalog[1].cargo_class, + crate::RuntimeCargoClass::FarmMine + ); + assert_eq!( + import.state.cargo_catalog[2].cargo_class, + crate::RuntimeCargoClass::Other + ); + assert_eq!(import.state.event_runtime_records.len(), 2); + assert_eq!( + import.state.event_runtime_records[1].conditions, + vec![ + RuntimeCondition::NamedLocomotiveAvailabilityThreshold { + name: "Big Boy".to_string(), + comparator: RuntimeConditionComparator::Eq, + value: 42, + }, + RuntimeCondition::NamedLocomotiveCostThreshold { + name: "Locomotive 1".to_string(), + comparator: RuntimeConditionComparator::Eq, + value: 250000, + }, + RuntimeCondition::CargoProductionSlotThreshold { + slot: 1, + label: "Cargo Production Slot 1".to_string(), + comparator: RuntimeConditionComparator::Eq, + value: 125, + }, + RuntimeCondition::CargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 230, + }, + RuntimeCondition::FactoryProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 125, + }, + RuntimeCondition::FarmMineProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 75, + }, + RuntimeCondition::OtherCargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 30, + }, + RuntimeCondition::LimitedTrackBuildingAmountThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 18, + }, + RuntimeCondition::TerritoryAccessCostThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 750000, + }, + ] + ); crate::execute_step_command( &mut import.state, &crate::StepCommand::ServiceTriggerKind { trigger_kind: 7 }, diff --git a/crates/rrt-runtime/src/lib.rs b/crates/rrt-runtime/src/lib.rs index 6c4ecb2..e7711aa 100644 --- a/crates/rrt-runtime/src/lib.rs +++ b/crates/rrt-runtime/src/lib.rs @@ -35,7 +35,7 @@ pub use pk4::{ extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file, }; pub use runtime::{ - RuntimeCargoCatalogEntry, RuntimeCompany, RuntimeCompanyConditionTestScope, + RuntimeCargoCatalogEntry, RuntimeCargoClass, RuntimeCompany, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate, diff --git a/crates/rrt-runtime/src/runtime.rs b/crates/rrt-runtime/src/runtime.rs index 79cf3c6..755c9c7 100644 --- a/crates/rrt-runtime/src/runtime.rs +++ b/crates/rrt-runtime/src/runtime.rs @@ -118,11 +118,22 @@ pub struct RuntimeCargoCatalogEntry { pub slot_id: u32, pub label: String, #[serde(default)] + pub cargo_class: RuntimeCargoClass, + #[serde(default)] pub supplied_token_stem: Option, #[serde(default)] pub demanded_token_stem: Option, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum RuntimeCargoClass { + #[default] + Other, + Factory, + FarmMine, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "kind", rename_all = "snake_case")] pub enum RuntimeCompanyTarget { @@ -274,6 +285,18 @@ pub enum RuntimeCondition { comparator: RuntimeConditionComparator, value: i64, }, + FactoryProductionTotalThreshold { + comparator: RuntimeConditionComparator, + value: i64, + }, + FarmMineProductionTotalThreshold { + comparator: RuntimeConditionComparator, + value: i64, + }, + OtherCargoProductionTotalThreshold { + comparator: RuntimeConditionComparator, + value: i64, + }, LimitedTrackBuildingAmountThreshold { comparator: RuntimeConditionComparator, value: i64, @@ -1475,6 +1498,9 @@ fn validate_runtime_condition( } } RuntimeCondition::CargoProductionTotalThreshold { .. } + | RuntimeCondition::FactoryProductionTotalThreshold { .. } + | RuntimeCondition::FarmMineProductionTotalThreshold { .. } + | RuntimeCondition::OtherCargoProductionTotalThreshold { .. } | RuntimeCondition::LimitedTrackBuildingAmountThreshold { .. } | RuntimeCondition::TerritoryAccessCostThreshold { .. } => Ok(()), RuntimeCondition::EconomicStatusCodeThreshold { .. } => Ok(()), diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index 0f423eb..db5f9fb 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -7,10 +7,10 @@ use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use crate::{ - RuntimeCompanyConditionTestScope, RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCondition, - RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecordTemplate, - RuntimePlayerConditionTestScope, RuntimePlayerTarget, RuntimeTerritoryMetric, - RuntimeTerritoryTarget, RuntimeTrackMetric, + RuntimeCargoClass, RuntimeCompanyConditionTestScope, RuntimeCompanyMetric, + RuntimeCompanyTarget, RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, + RuntimeEventRecordTemplate, RuntimePlayerConditionTestScope, RuntimePlayerTarget, + RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric, }; pub const SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION: u32 = 0x03ec; @@ -266,6 +266,83 @@ struct RealOrdinaryConditionMetadata { kind: RealOrdinaryConditionKind, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +struct KnownCargoSlotDefinition { + slot_id: u32, + label: &'static str, + cargo_class: RuntimeCargoClass, + descriptor_id: u32, +} + +const KNOWN_CARGO_SLOT_DEFINITIONS: [KnownCargoSlotDefinition; 11] = [ + KnownCargoSlotDefinition { + slot_id: 1, + label: "Cargo Production Slot 1", + cargo_class: RuntimeCargoClass::Factory, + descriptor_id: 230, + }, + KnownCargoSlotDefinition { + slot_id: 2, + label: "Cargo Production Slot 2", + cargo_class: RuntimeCargoClass::Factory, + descriptor_id: 231, + }, + KnownCargoSlotDefinition { + slot_id: 3, + label: "Cargo Production Slot 3", + cargo_class: RuntimeCargoClass::Factory, + descriptor_id: 232, + }, + KnownCargoSlotDefinition { + slot_id: 4, + label: "Cargo Production Slot 4", + cargo_class: RuntimeCargoClass::Factory, + descriptor_id: 233, + }, + KnownCargoSlotDefinition { + slot_id: 5, + label: "Cargo Production Slot 5", + cargo_class: RuntimeCargoClass::FarmMine, + descriptor_id: 234, + }, + KnownCargoSlotDefinition { + slot_id: 6, + label: "Cargo Production Slot 6", + cargo_class: RuntimeCargoClass::FarmMine, + descriptor_id: 235, + }, + KnownCargoSlotDefinition { + slot_id: 7, + label: "Cargo Production Slot 7", + cargo_class: RuntimeCargoClass::FarmMine, + descriptor_id: 236, + }, + KnownCargoSlotDefinition { + slot_id: 8, + label: "Cargo Production Slot 8", + cargo_class: RuntimeCargoClass::FarmMine, + descriptor_id: 237, + }, + KnownCargoSlotDefinition { + slot_id: 9, + label: "Cargo Production Slot 9", + cargo_class: RuntimeCargoClass::Other, + descriptor_id: 238, + }, + KnownCargoSlotDefinition { + slot_id: 10, + label: "Cargo Production Slot 10", + cargo_class: RuntimeCargoClass::Other, + descriptor_id: 239, + }, + KnownCargoSlotDefinition { + slot_id: 11, + label: "Cargo Production Slot 11", + cargo_class: RuntimeCargoClass::Other, + descriptor_id: 240, + }, +]; + const REAL_CANDIDATE_AVAILABILITY_CONDITION_TEMPLATE_ID: i32 = 435; const REAL_CARGO_PRODUCTION_CONDITION_TEMPLATE_ID: i32 = 200; const REAL_NAMED_LOCOMOTIVE_AVAILABILITY_CONDITION_ID: i32 = 2422; @@ -1629,6 +1706,8 @@ pub struct SmpLoadedLocomotiveCatalog { pub struct SmpLoadedCargoCatalogEntry { pub slot_id: u32, pub label: String, + #[serde(default)] + pub cargo_class: RuntimeCargoClass, pub book_index: usize, pub max_annual_production_word: u32, pub mode_word: u32, @@ -2080,9 +2159,11 @@ fn derive_cargo_catalog_from_recipe_book_probe( .find(|line| line.imports_to_runtime_descriptor) .or_else(|| book.lines.first())?; let slot_id = (book.book_index + 1) as u32; + let definition = known_cargo_slot_definition(slot_id)?; Some(SmpLoadedCargoCatalogEntry { slot_id, - label: format!("Cargo Production Slot {slot_id}"), + label: definition.label.to_string(), + cargo_class: definition.cargo_class, book_index: book.book_index, max_annual_production_word: book.max_annual_production_word, mode_word: line.mode_word, @@ -2113,6 +2194,30 @@ fn derive_cargo_catalog_from_recipe_book_probe( }) } +fn known_cargo_slot_definition(slot_id: u32) -> Option { + KNOWN_CARGO_SLOT_DEFINITIONS + .iter() + .copied() + .find(|definition| definition.slot_id == slot_id) +} + +fn known_cargo_slot_definition_for_descriptor_id( + descriptor_id: u32, +) -> Option { + KNOWN_CARGO_SLOT_DEFINITIONS + .iter() + .copied() + .find(|definition| definition.descriptor_id == descriptor_id) +} + +fn runtime_cargo_class_name(cargo_class: RuntimeCargoClass) -> &'static str { + match cargo_class { + RuntimeCargoClass::Factory => "factory", + RuntimeCargoClass::FarmMine => "farm_mine", + RuntimeCargoClass::Other => "other", + } +} + fn parse_event_runtime_collection_summary( bytes: &[u8], container_profile: Option<&SmpContainerProfile>, @@ -2766,6 +2871,12 @@ fn parse_real_condition_row_summary( _ => None, }), recovered_cargo_class: ordinary_metadata.and_then(|metadata| match metadata.kind { + RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CargoProductionSlot) => { + candidate_name_ref + .and_then(recovered_cargo_production_slot_from_condition_name) + .and_then(known_cargo_slot_definition) + .map(|definition| runtime_cargo_class_name(definition.cargo_class).to_string()) + } RealOrdinaryConditionKind::WorldState( RealWorldConditionKind::FactoryProductionTotal, ) => Some("factory".to_string()), @@ -3083,7 +3194,9 @@ fn parse_real_grouped_effect_row_summary( value_word_0x16, )), recovered_cargo_slot: recovered_cargo_production_slot(descriptor_id), - recovered_cargo_class: None, + recovered_cargo_class: recovered_cargo_production_slot(descriptor_id) + .and_then(known_cargo_slot_definition) + .map(|definition| runtime_cargo_class_name(definition.cargo_class).to_string()), recovered_locomotive_id: recovered_locomotive_availability_loco_id(descriptor_id) .or_else(|| recovered_locomotive_cost_loco_id(descriptor_id)), locomotive_name, @@ -3156,9 +3269,12 @@ fn decode_real_condition_row( RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CargoProductionSlot) => { row.candidate_name.as_ref().and_then(|name| { recovered_cargo_production_slot_from_condition_name(name).map(|slot| { + let label = known_cargo_slot_definition(slot) + .map(|definition| definition.label.to_string()) + .unwrap_or_else(|| name.clone()); RuntimeCondition::CargoProductionSlotThreshold { slot, - label: name.clone(), + label, comparator, value, } @@ -3185,11 +3301,15 @@ fn decode_real_condition_row( RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::CargoProductionTotal) => { Some(RuntimeCondition::CargoProductionTotalThreshold { comparator, value }) } + RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::FactoryProductionTotal) => { + Some(RuntimeCondition::FactoryProductionTotalThreshold { comparator, value }) + } + RealOrdinaryConditionKind::WorldState(RealWorldConditionKind::FarmMineProductionTotal) => { + Some(RuntimeCondition::FarmMineProductionTotalThreshold { comparator, value }) + } RealOrdinaryConditionKind::WorldState( - RealWorldConditionKind::FactoryProductionTotal - | RealWorldConditionKind::FarmMineProductionTotal - | RealWorldConditionKind::OtherCargoProductionTotal, - ) => None, + RealWorldConditionKind::OtherCargoProductionTotal, + ) => Some(RuntimeCondition::OtherCargoProductionTotalThreshold { comparator, value }), RealOrdinaryConditionKind::WorldState( RealWorldConditionKind::LimitedTrackBuildingAmount, ) => Some(RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator, value }), @@ -3295,27 +3415,14 @@ fn recovered_locomotive_availability_loco_id(descriptor_id: u32) -> Option } fn recovered_cargo_production_label(descriptor_id: u32) -> Option<&'static str> { - static LABELS: OnceLock> = OnceLock::new(); - LABELS - .get_or_init(|| { - (230..=240) - .enumerate() - .map(|(slot_index, descriptor_id)| { - let label = Box::leak( - format!("Cargo Production Slot {}", slot_index + 1).into_boxed_str(), - ) as &'static str; - (descriptor_id, label) - }) - .collect() - }) - .get(&descriptor_id) - .copied() + known_cargo_slot_definition_for_descriptor_id(descriptor_id).map(|definition| definition.label) } fn recovered_cargo_production_slot_from_condition_name(name: &str) -> Option { - let suffix = name.strip_prefix("Cargo Production Slot ")?; - let slot = suffix.parse::().ok()?; - (1..=11).contains(&slot).then_some(slot) + KNOWN_CARGO_SLOT_DEFINITIONS + .iter() + .find(|definition| definition.label == name) + .map(|definition| definition.slot_id) } fn recovered_locomotive_cost_loco_id(descriptor_id: u32) -> Option { @@ -3998,6 +4105,9 @@ fn runtime_condition_supported_for_save_import(condition: &RuntimeCondition) -> | RuntimeCondition::NamedLocomotiveCostThreshold { .. } | RuntimeCondition::CargoProductionSlotThreshold { .. } | RuntimeCondition::CargoProductionTotalThreshold { .. } + | RuntimeCondition::FactoryProductionTotalThreshold { .. } + | RuntimeCondition::FarmMineProductionTotalThreshold { .. } + | RuntimeCondition::OtherCargoProductionTotalThreshold { .. } | RuntimeCondition::LimitedTrackBuildingAmountThreshold { .. } | RuntimeCondition::TerritoryAccessCostThreshold { .. } | RuntimeCondition::EconomicStatusCodeThreshold { .. } @@ -9979,6 +10089,24 @@ mod tests { 200, None, ), + build_real_condition_row_with_threshold( + REAL_FACTORY_PRODUCTION_TOTAL_CONDITION_ID, + 4, + 125, + None, + ), + build_real_condition_row_with_threshold( + REAL_FARM_MINE_PRODUCTION_TOTAL_CONDITION_ID, + 4, + 75, + None, + ), + build_real_condition_row_with_threshold( + REAL_OTHER_CARGO_PRODUCTION_TOTAL_CONDITION_ID, + 4, + 30, + None, + ), build_real_condition_row_with_threshold( REAL_LIMITED_TRACK_BUILDING_AMOUNT_CONDITION_ID, 4, @@ -10048,6 +10176,18 @@ mod tests { comparator: RuntimeConditionComparator::Ge, value: 200, }, + RuntimeCondition::FactoryProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 125, + }, + RuntimeCondition::FarmMineProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 75, + }, + RuntimeCondition::OtherCargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 30, + }, RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator: RuntimeConditionComparator::Eq, value: 18, diff --git a/crates/rrt-runtime/src/step.rs b/crates/rrt-runtime/src/step.rs index 001d9e3..f5540dc 100644 --- a/crates/rrt-runtime/src/step.rs +++ b/crates/rrt-runtime/src/step.rs @@ -3,10 +3,11 @@ use std::collections::BTreeSet; use serde::{Deserialize, Serialize}; use crate::{ - RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCondition, - RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecordTemplate, RuntimePlayerTarget, - RuntimeState, RuntimeSummary, RuntimeTerritoryMetric, RuntimeTerritoryTarget, - RuntimeTrackMetric, RuntimeTrackPieceCounts, calendar::BoundaryEventKind, + RuntimeCargoClass, RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget, + RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecordTemplate, + RuntimePlayerTarget, RuntimeState, RuntimeSummary, RuntimeTerritoryMetric, + RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, + calendar::BoundaryEventKind, }; const PERIODIC_TRIGGER_KIND_ORDER: [u8; 6] = [1, 0, 3, 2, 5, 4]; @@ -779,6 +780,24 @@ fn evaluate_record_conditions( return Ok(None); } } + RuntimeCondition::FactoryProductionTotalThreshold { comparator, value } => { + let actual = cargo_production_total_for_class(state, RuntimeCargoClass::Factory); + if !compare_condition_value(actual, *comparator, *value) { + return Ok(None); + } + } + RuntimeCondition::FarmMineProductionTotalThreshold { comparator, value } => { + let actual = cargo_production_total_for_class(state, RuntimeCargoClass::FarmMine); + if !compare_condition_value(actual, *comparator, *value) { + return Ok(None); + } + } + RuntimeCondition::OtherCargoProductionTotalThreshold { comparator, value } => { + let actual = cargo_production_total_for_class(state, RuntimeCargoClass::Other); + if !compare_condition_value(actual, *comparator, *value) { + return Ok(None); + } + } RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator, value } => { let actual = state .world_restore @@ -1142,6 +1161,17 @@ fn compare_condition_value( } } +fn cargo_production_total_for_class(state: &RuntimeState, cargo_class: RuntimeCargoClass) -> i64 { + state + .cargo_catalog + .iter() + .filter(|entry| entry.cargo_class == cargo_class) + .filter_map(|entry| state.cargo_production_overrides.get(&entry.slot_id)) + .copied() + .map(i64::from) + .sum() +} + fn apply_u64_delta(current: u64, delta: i64, company_id: u32) -> Result { if delta >= 0 { current @@ -2228,9 +2258,32 @@ mod tests { territory_access_cost: Some(750000), ..RuntimeWorldRestoreState::default() }, + cargo_catalog: vec![ + crate::RuntimeCargoCatalogEntry { + slot_id: 1, + label: "Cargo Production Slot 1".to_string(), + cargo_class: RuntimeCargoClass::Factory, + supplied_token_stem: None, + demanded_token_stem: None, + }, + crate::RuntimeCargoCatalogEntry { + slot_id: 5, + label: "Cargo Production Slot 5".to_string(), + cargo_class: RuntimeCargoClass::FarmMine, + supplied_token_stem: None, + demanded_token_stem: None, + }, + crate::RuntimeCargoCatalogEntry { + slot_id: 9, + label: "Cargo Production Slot 9".to_string(), + cargo_class: RuntimeCargoClass::Other, + supplied_token_stem: None, + demanded_token_stem: None, + }, + ], named_locomotive_availability: BTreeMap::from([(String::from("Big Boy"), 42)]), named_locomotive_cost: BTreeMap::from([(String::from("GP7"), 175000)]), - cargo_production_overrides: BTreeMap::from([(1, 125), (2, 75)]), + cargo_production_overrides: BTreeMap::from([(1, 125), (5, 75), (9, 30)]), event_runtime_records: vec![ RuntimeEventRecord { record_id: 25, @@ -2259,7 +2312,19 @@ mod tests { }, RuntimeCondition::CargoProductionTotalThreshold { comparator: RuntimeConditionComparator::Eq, - value: 200, + value: 230, + }, + RuntimeCondition::FactoryProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 125, + }, + RuntimeCondition::FarmMineProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 75, + }, + RuntimeCondition::OtherCargoProductionTotalThreshold { + comparator: RuntimeConditionComparator::Eq, + value: 30, }, RuntimeCondition::LimitedTrackBuildingAmountThreshold { comparator: RuntimeConditionComparator::Eq, diff --git a/docs/README.md b/docs/README.md index e530e56..e10dbe6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -143,11 +143,11 @@ The highest-value next passes are now: cargo simulation layer - world-scalar ordinary-condition coverage now matches those runtime surfaces too: checked-in metadata lowers named locomotive availability, named locomotive cost, named cargo-production - slot thresholds, aggregate cargo production, limited-track-building-amount, and - territory-access-cost rows into explicit runtime condition gates -- 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`; the - remaining cargo frontier is slot-to-class classification, not save/import plumbing + slot thresholds, aggregate cargo production, factory/farm-mine/other cargo production, + limited-track-building-amount, and territory-access-cost rows into explicit runtime condition + gates +- cargo slot classification is now checked in and save-native too, so the remaining cargo frontier + is broader descriptor/condition breadth rather than classification or save/import plumbing - 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 - use `rrt-hook` primarily as optional capture or integration tooling, not as the first execution diff --git a/docs/runtime-rehost-plan.md b/docs/runtime-rehost-plan.md index 4f630ae..43492d3 100644 --- a/docs/runtime-rehost-plan.md +++ b/docs/runtime-rehost-plan.md @@ -102,12 +102,12 @@ Implemented today: `%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 metadata lowers named locomotive availability, named locomotive cost, named cargo-production - slot thresholds, aggregate cargo production, limited-track-building-amount, and - territory-access-cost rows into explicit runtime condition gates -- 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`; - the remaining cargo frontier is slot classification rather than missing save/import context - instead of falling back to generic placeholder ids + slot thresholds, aggregate cargo production, factory/farm-mine/other cargo production, + limited-track-building-amount, and territory-access-cost rows into explicit runtime condition + gates +- cargo slot classification is now checked in across the full 11-slot recipe-book surface, so the + remaining world-side frontier is broader descriptor/condition breadth rather than missing cargo + classification or save/import context That means the next implementation work is breadth, not bootstrap. The recommended next slice is broader real grouped-descriptor and ordinary condition-id coverage beyond the current access, diff --git a/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json b/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json index 44a618f..81c7759 100644 --- a/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json @@ -29,11 +29,13 @@ "cargo_catalog": [ { "slot_id": 1, - "label": "Cargo Production Slot 1" + "label": "Cargo Production Slot 1", + "cargo_class": "factory" }, { "slot_id": 2, - "label": "Cargo Production Slot 2" + "label": "Cargo Production Slot 2", + "cargo_class": "factory" } ], "metadata": { diff --git a/fixtures/runtime/packed-event-cargo-catalog-save-slice.json b/fixtures/runtime/packed-event-cargo-catalog-save-slice.json index dcc1093..4cc69ac 100644 --- a/fixtures/runtime/packed-event-cargo-catalog-save-slice.json +++ b/fixtures/runtime/packed-event-cargo-catalog-save-slice.json @@ -26,17 +26,17 @@ "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 } + { "slot_id": 1, "label": "Cargo Production Slot 1", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "other", "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", "cargo_class": "other", "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", "cargo_class": "other", "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, diff --git a/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice-fixture.json index 21328a5..93c8844 100644 --- a/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice-fixture.json @@ -55,6 +55,7 @@ "descriptor_label": "Cargo Production Slot 1", "recovered_cargo_slot": 1, "recovered_cargo_label": "Cargo Production Slot 1", + "recovered_cargo_class": "factory", "target_mask_bits": 8, "parameter_family": "cargo_production_scalar", "semantic_family": "scalar_assignment", diff --git a/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice.json b/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice.json index cd43fe8..68e9556 100644 --- a/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice.json +++ b/fixtures/runtime/packed-event-world-scalar-band-parity-save-slice.json @@ -26,17 +26,17 @@ "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 } + { "slot_id": 1, "label": "Cargo Production Slot 1", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "other", "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", "cargo_class": "other", "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", "cargo_class": "other", "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, @@ -101,7 +101,7 @@ "semantic_family": "scalar_assignment", "semantic_preview": "Set Cargo Production Slot 1 to 125", "recovered_cargo_slot": 1, - "recovered_cargo_class": null, + "recovered_cargo_class": "factory", "recovered_locomotive_id": null, "locomotive_name": null, "notes": [] diff --git a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json index 3ead76f..ee88925 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json @@ -3,10 +3,14 @@ "fixture_id": "packed-event-world-scalar-condition-parity-save-slice-fixture", "source": { "kind": "captured-runtime", - "description": "Fixture pinning one remaining unmapped world-scalar ordinary-condition family after the grounded batch." + "description": "Fixture proving the three aggregate cargo-class conditions execute through the world-scalar runtime path." }, "state_save_slice_path": "packed-event-world-scalar-condition-parity-save-slice.json", "commands": [ + { + "kind": "service_trigger_kind", + "trigger_kind": 6 + }, { "kind": "service_trigger_kind", "trigger_kind": 7 @@ -14,33 +18,70 @@ ], "expected_summary": { "packed_event_collection_present": true, - "packed_event_record_count": 1, - "packed_event_decoded_record_count": 1, - "packed_event_imported_runtime_record_count": 0, - "packed_event_parity_only_record_count": 1, - "packed_event_blocked_unmapped_world_condition_count": 1, + "packed_event_record_count": 2, + "packed_event_decoded_record_count": 2, + "packed_event_imported_runtime_record_count": 2, + "packed_event_parity_only_record_count": 0, + "packed_event_blocked_unmapped_world_condition_count": 0, "cargo_catalog_count": 11, - "event_runtime_record_count": 0, - "world_flag_count": 8, - "total_event_record_service_count": 0, - "total_trigger_dispatch_count": 1 + "event_runtime_record_count": 2, + "cargo_production_override_count": 3, + "world_flag_count": 9, + "total_event_record_service_count": 2, + "total_trigger_dispatch_count": 2 }, "expected_state_fragment": { + "world_flags": { + "world.aggregate_cargo_conditions_passed": true + }, "cargo_catalog": [ { "slot_id": 1, - "label": "Cargo Production Slot 1" + "label": "Cargo Production Slot 1", + "cargo_class": "factory" } ], + "cargo_production_overrides": { + "1": 125, + "5": 75, + "9": 30 + }, "packed_event_collection": { "records": [ { - "import_outcome": "blocked_unmapped_world_condition", + "import_outcome": "imported" + }, + { + "import_outcome": "imported", "standalone_condition_rows": [ { "raw_condition_id": 2419, - "metric": "All Factory Production", - "semantic_family": "world_scalar_threshold" + "recovered_cargo_class": "factory" + }, + { + "raw_condition_id": 2420, + "recovered_cargo_class": "farm_mine" + }, + { + "raw_condition_id": 2421, + "recovered_cargo_class": "other" + } + ], + "decoded_conditions": [ + { + "kind": "factory_production_total_threshold", + "comparator": "eq", + "value": 125 + }, + { + "kind": "farm_mine_production_total_threshold", + "comparator": "eq", + "value": 75 + }, + { + "kind": "other_cargo_production_total_threshold", + "comparator": "eq", + "value": 30 } ] } diff --git a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice.json b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice.json index bef90fa..2f814ff 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice.json @@ -2,12 +2,12 @@ "format_version": 1, "save_slice_id": "packed-event-world-scalar-condition-parity-save-slice", "source": { - "description": "Tracked save-slice document pinning one remaining unmapped world-scalar condition family after the grounded batch.", + "description": "Tracked save-slice document proving aggregate cargo-class conditions execute through the world-scalar runtime path.", "original_save_filename": "captured-world-scalar-condition-parity.gms", "original_save_sha256": "world-scalar-condition-parity-sample-sha256", "notes": [ "tracked as JSON save-slice document rather than raw .smp", - "keeps the broader all-factory-production family parity-only until a stronger runtime landing surface is grounded" + "historical fixture id retained, but the tracked sample now proves aggregate cargo condition execution for all three cargo classes" ] }, "save_slice": { @@ -26,17 +26,17 @@ "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 } + { "slot_id": 1, "label": "Cargo Production Slot 1", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "other", "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", "cargo_class": "other", "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", "cargo_class": "other", "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, @@ -47,21 +47,144 @@ "container_profile_family": "rt3-classic-save-container-v1", "metadata_tag_offset": 31232, "records_tag_offset": 31488, - "close_tag_offset": 31872, + "close_tag_offset": 32128, "packed_state_version": 1001, "packed_state_version_hex": "0x000003e9", - "live_id_bound": 33, - "live_record_count": 1, - "live_entry_ids": [33], - "decoded_record_count": 1, - "imported_runtime_record_count": 0, + "live_id_bound": 35, + "live_record_count": 2, + "live_entry_ids": [31, 35], + "decoded_record_count": 2, + "imported_runtime_record_count": 2, "records": [ { "record_index": 0, - "live_entry_id": 33, + "live_entry_id": 31, "payload_offset": 31520, - "payload_len": 152, - "decode_status": "parity_only", + "payload_len": 160, + "decode_status": "executable", + "payload_family": "real_packed_v1", + "trigger_kind": 6, + "one_shot": false, + "compact_control": { + "mode_byte_0x7ef": 6, + "primary_selector_0x7f0": 0, + "grouped_mode_0x7f4": 2, + "one_shot_header_0x7f5": 0, + "modifier_flag_0x7f9": 0, + "modifier_flag_0x7fa": 0, + "grouped_target_scope_ordinals_0x7fb": [0, 0, 0, 0], + "grouped_scope_checkboxes_0x7ff": [1, 0, 0, 0], + "summary_toggle_0x800": 1, + "grouped_territory_selectors_0x80f": [-1, -1, -1, -1] + }, + "text_bands": [], + "standalone_condition_row_count": 0, + "standalone_condition_rows": [], + "negative_sentinel_scope": null, + "grouped_effect_row_counts": [3, 0, 0, 0], + "grouped_effect_rows": [ + { + "group_index": 0, + "row_index": 0, + "descriptor_id": 230, + "descriptor_label": "Cargo Production Slot 1", + "target_mask_bits": 8, + "parameter_family": "cargo_production_scalar", + "opcode": 3, + "raw_scalar_value": 125, + "value_byte_0x09": 0, + "value_dword_0x0d": 0, + "value_byte_0x11": 0, + "value_byte_0x12": 0, + "value_word_0x14": 0, + "value_word_0x16": 0, + "row_shape": "scalar_assignment", + "semantic_family": "scalar_assignment", + "semantic_preview": "Set Cargo Production Slot 1 to 125", + "recovered_cargo_slot": 1, + "recovered_cargo_class": "factory", + "recovered_locomotive_id": null, + "locomotive_name": null, + "notes": [] + }, + { + "group_index": 0, + "row_index": 1, + "descriptor_id": 234, + "descriptor_label": "Cargo Production Slot 5", + "target_mask_bits": 8, + "parameter_family": "cargo_production_scalar", + "opcode": 3, + "raw_scalar_value": 75, + "value_byte_0x09": 0, + "value_dword_0x0d": 0, + "value_byte_0x11": 0, + "value_byte_0x12": 0, + "value_word_0x14": 0, + "value_word_0x16": 0, + "row_shape": "scalar_assignment", + "semantic_family": "scalar_assignment", + "semantic_preview": "Set Cargo Production Slot 5 to 75", + "recovered_cargo_slot": 5, + "recovered_cargo_class": "farm_mine", + "recovered_locomotive_id": null, + "locomotive_name": null, + "notes": [] + }, + { + "group_index": 0, + "row_index": 2, + "descriptor_id": 238, + "descriptor_label": "Cargo Production Slot 9", + "target_mask_bits": 8, + "parameter_family": "cargo_production_scalar", + "opcode": 3, + "raw_scalar_value": 30, + "value_byte_0x09": 0, + "value_dword_0x0d": 0, + "value_byte_0x11": 0, + "value_byte_0x12": 0, + "value_word_0x14": 0, + "value_word_0x16": 0, + "row_shape": "scalar_assignment", + "semantic_family": "scalar_assignment", + "semantic_preview": "Set Cargo Production Slot 9 to 30", + "recovered_cargo_slot": 9, + "recovered_cargo_class": "other", + "recovered_locomotive_id": null, + "locomotive_name": null, + "notes": [] + } + ], + "decoded_conditions": [], + "decoded_actions": [ + { + "kind": "set_cargo_production_slot", + "slot": 1, + "value": 125 + }, + { + "kind": "set_cargo_production_slot", + "slot": 5, + "value": 75 + }, + { + "kind": "set_cargo_production_slot", + "slot": 9, + "value": 30 + } + ], + "executable_import_ready": true, + "notes": [ + "aggregate cargo setup record" + ] + }, + { + "record_index": 1, + "live_entry_id": 35, + "payload_offset": 31712, + "payload_len": 168, + "decode_status": "executable", "payload_family": "real_packed_v1", "trigger_kind": 7, "one_shot": false, @@ -78,21 +201,54 @@ "grouped_territory_selectors_0x80f": [-1, -1, -1, -1] }, "text_bands": [], - "standalone_condition_row_count": 1, + "standalone_condition_row_count": 3, "standalone_condition_rows": [ { "row_index": 0, "raw_condition_id": 2419, "subtype": 4, - "flag_bytes": [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "flag_bytes": [125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "candidate_name": null, - "comparator": null, - "metric": "All Factory Production", + "comparator": "eq", + "metric": "Factory Production Total", "semantic_family": "world_scalar_threshold", - "semantic_preview": null, + "semantic_preview": "Test Factory Production Total == 125", + "recovered_cargo_class": "factory", "requires_candidate_name_binding": false, "notes": [ - "checked-in RT3.lng label is known, but this world-scalar condition family is not yet lowered" + "checked-in world-scalar condition metadata sample" + ] + }, + { + "row_index": 1, + "raw_condition_id": 2420, + "subtype": 4, + "flag_bytes": [75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "candidate_name": null, + "comparator": "eq", + "metric": "Farm/Mine Production Total", + "semantic_family": "world_scalar_threshold", + "semantic_preview": "Test Farm/Mine Production Total == 75", + "recovered_cargo_class": "farm_mine", + "requires_candidate_name_binding": false, + "notes": [ + "checked-in world-scalar condition metadata sample" + ] + }, + { + "row_index": 2, + "raw_condition_id": 2421, + "subtype": 4, + "flag_bytes": [30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "candidate_name": null, + "comparator": "eq", + "metric": "Other Cargo Production Total", + "semantic_family": "world_scalar_threshold", + "semantic_preview": "Test Other Cargo Production Total == 30", + "recovered_cargo_class": "other", + "requires_candidate_name_binding": false, + "notes": [ + "checked-in world-scalar condition metadata sample" ] } ], @@ -122,23 +278,39 @@ "notes": [] } ], - "decoded_conditions": [], + "decoded_conditions": [ + { + "kind": "factory_production_total_threshold", + "comparator": "eq", + "value": 125 + }, + { + "kind": "farm_mine_production_total_threshold", + "comparator": "eq", + "value": 75 + }, + { + "kind": "other_cargo_production_total_threshold", + "comparator": "eq", + "value": 30 + } + ], "decoded_actions": [ { "kind": "set_world_flag", - "key": "world.disable_stock_buying_and_selling", + "key": "world.aggregate_cargo_conditions_passed", "value": true } ], - "executable_import_ready": false, + "executable_import_ready": true, "notes": [ - "unmapped world-scalar condition parity sample" + "aggregate cargo conditions gate a whole-game effect" ] } ] }, "notes": [ - "world-scalar condition parity sample" + "aggregate cargo condition executable sample" ] } } diff --git a/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json index 2275e12..8aa5fc9 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json @@ -26,7 +26,7 @@ "named_locomotive_availability_count": 1, "zero_named_locomotive_availability_count": 0, "named_locomotive_cost_count": 1, - "cargo_production_override_count": 1, + "cargo_production_override_count": 3, "world_restore_limited_track_building_amount": 18, "world_restore_territory_access_cost": 750000, "world_flag_count": 9, @@ -48,12 +48,15 @@ "Locomotive 1": 250000 }, "cargo_production_overrides": { - "1": 125 + "1": 125, + "5": 75, + "9": 30 }, "cargo_catalog": [ { "slot_id": 1, - "label": "Cargo Production Slot 1" + "label": "Cargo Production Slot 1", + "cargo_class": "factory" } ], "packed_event_collection": { @@ -63,6 +66,34 @@ }, { "import_outcome": "imported", + "standalone_condition_rows": [ + { + "raw_condition_id": 2422 + }, + { + "raw_condition_id": 2423 + }, + { + "raw_condition_id": 200, + "recovered_cargo_slot": 1, + "recovered_cargo_class": "factory" + }, + { + "raw_condition_id": 2418 + }, + { + "raw_condition_id": 2419, + "recovered_cargo_class": "factory" + }, + { + "raw_condition_id": 2420, + "recovered_cargo_class": "farm_mine" + }, + { + "raw_condition_id": 2421, + "recovered_cargo_class": "other" + } + ], "decoded_conditions": [ { "kind": "named_locomotive_availability_threshold", @@ -86,8 +117,23 @@ { "kind": "cargo_production_total_threshold", "comparator": "eq", + "value": 230 + }, + { + "kind": "factory_production_total_threshold", + "comparator": "eq", "value": 125 }, + { + "kind": "farm_mine_production_total_threshold", + "comparator": "eq", + "value": 75 + }, + { + "kind": "other_cargo_production_total_threshold", + "comparator": "eq", + "value": 30 + }, { "kind": "limited_track_building_amount_threshold", "comparator": "eq", diff --git a/fixtures/runtime/packed-event-world-scalar-condition-save-slice.json b/fixtures/runtime/packed-event-world-scalar-condition-save-slice.json index f9bf4a0..11916da 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-save-slice.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-save-slice.json @@ -7,7 +7,7 @@ "original_save_sha256": "world-scalar-condition-sample-sha256", "notes": [ "tracked as JSON save-slice document rather than raw .smp", - "uses checked-in RT3.lng condition ids for named locomotive availability, named locomotive cost, named cargo-production slot, aggregate cargo production, limited track building amount, and access rights cost" + "uses checked-in RT3.lng condition ids for named locomotive availability, named locomotive cost, named cargo-production slot, aggregate cargo production, factory production, farm/mine production, other cargo production, limited track building amount, and access rights cost" ] }, "save_slice": { @@ -26,17 +26,17 @@ "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 } + { "slot_id": 1, "label": "Cargo Production Slot 1", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "other", "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", "cargo_class": "other", "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", "cargo_class": "other", "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, @@ -81,7 +81,7 @@ "standalone_condition_row_count": 0, "standalone_condition_rows": [], "negative_sentinel_scope": null, - "grouped_effect_row_counts": [5, 0, 0, 0], + "grouped_effect_row_counts": [7, 0, 0, 0], "grouped_effect_rows": [ { "group_index": 0, @@ -150,7 +150,7 @@ "semantic_family": "scalar_assignment", "semantic_preview": "Set Cargo Production Slot 1 to 125", "recovered_cargo_slot": 1, - "recovered_cargo_class": null, + "recovered_cargo_class": "factory", "recovered_locomotive_id": null, "locomotive_name": null, "notes": [] @@ -158,6 +158,54 @@ { "group_index": 0, "row_index": 3, + "descriptor_id": 234, + "descriptor_label": "Cargo Production Slot 5", + "target_mask_bits": 8, + "parameter_family": "cargo_production_scalar", + "opcode": 3, + "raw_scalar_value": 75, + "value_byte_0x09": 0, + "value_dword_0x0d": 0, + "value_byte_0x11": 0, + "value_byte_0x12": 0, + "value_word_0x14": 0, + "value_word_0x16": 0, + "row_shape": "scalar_assignment", + "semantic_family": "scalar_assignment", + "semantic_preview": "Set Cargo Production Slot 5 to 75", + "recovered_cargo_slot": 5, + "recovered_cargo_class": "farm_mine", + "recovered_locomotive_id": null, + "locomotive_name": null, + "notes": [] + }, + { + "group_index": 0, + "row_index": 4, + "descriptor_id": 238, + "descriptor_label": "Cargo Production Slot 9", + "target_mask_bits": 8, + "parameter_family": "cargo_production_scalar", + "opcode": 3, + "raw_scalar_value": 30, + "value_byte_0x09": 0, + "value_dword_0x0d": 0, + "value_byte_0x11": 0, + "value_byte_0x12": 0, + "value_word_0x14": 0, + "value_word_0x16": 0, + "row_shape": "scalar_assignment", + "semantic_family": "scalar_assignment", + "semantic_preview": "Set Cargo Production Slot 9 to 30", + "recovered_cargo_slot": 9, + "recovered_cargo_class": "other", + "recovered_locomotive_id": null, + "locomotive_name": null, + "notes": [] + }, + { + "group_index": 0, + "row_index": 5, "descriptor_id": 122, "descriptor_label": "Limited Track Building Amount", "target_mask_bits": 8, @@ -179,7 +227,7 @@ }, { "group_index": 0, - "row_index": 4, + "row_index": 6, "descriptor_id": 453, "descriptor_label": "Territory Access Cost", "target_mask_bits": 8, @@ -217,6 +265,16 @@ "slot": 1, "value": 125 }, + { + "kind": "set_cargo_production_slot", + "slot": 5, + "value": 75 + }, + { + "kind": "set_cargo_production_slot", + "slot": 9, + "value": 30 + }, { "kind": "set_limited_track_building_amount", "value": 18 @@ -253,7 +311,7 @@ "grouped_territory_selectors_0x80f": [-1, -1, -1, -1] }, "text_bands": [], - "standalone_condition_row_count": 6, + "standalone_condition_row_count": 9, "standalone_condition_rows": [ { "row_index": 0, @@ -296,7 +354,7 @@ "semantic_family": "world_scalar_threshold", "semantic_preview": "Test Cargo Production: Cargo Production Slot 1 == 125", "recovered_cargo_slot": 1, - "recovered_cargo_class": null, + "recovered_cargo_class": "factory", "requires_candidate_name_binding": false, "notes": [ "checked-in world-scalar condition metadata sample" @@ -311,7 +369,7 @@ "comparator": "eq", "metric": "Cargo Production Total", "semantic_family": "world_scalar_threshold", - "semantic_preview": "Test Cargo Production Total == 125", + "semantic_preview": "Test Cargo Production Total == 230", "requires_candidate_name_binding": false, "notes": [ "checked-in world-scalar condition metadata sample" @@ -319,6 +377,54 @@ }, { "row_index": 4, + "raw_condition_id": 2419, + "subtype": 4, + "flag_bytes": [125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "candidate_name": null, + "comparator": "eq", + "metric": "Factory Production Total", + "semantic_family": "world_scalar_threshold", + "semantic_preview": "Test Factory Production Total == 125", + "recovered_cargo_class": "factory", + "requires_candidate_name_binding": false, + "notes": [ + "checked-in world-scalar condition metadata sample" + ] + }, + { + "row_index": 5, + "raw_condition_id": 2420, + "subtype": 4, + "flag_bytes": [75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "candidate_name": null, + "comparator": "eq", + "metric": "Farm/Mine Production Total", + "semantic_family": "world_scalar_threshold", + "semantic_preview": "Test Farm/Mine Production Total == 75", + "recovered_cargo_class": "farm_mine", + "requires_candidate_name_binding": false, + "notes": [ + "checked-in world-scalar condition metadata sample" + ] + }, + { + "row_index": 6, + "raw_condition_id": 2421, + "subtype": 4, + "flag_bytes": [30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "candidate_name": null, + "comparator": "eq", + "metric": "Other Cargo Production Total", + "semantic_family": "world_scalar_threshold", + "semantic_preview": "Test Other Cargo Production Total == 30", + "recovered_cargo_class": "other", + "requires_candidate_name_binding": false, + "notes": [ + "checked-in world-scalar condition metadata sample" + ] + }, + { + "row_index": 7, "raw_condition_id": 2547, "subtype": 4, "flag_bytes": [18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -333,7 +439,7 @@ ] }, { - "row_index": 5, + "row_index": 8, "raw_condition_id": 1516, "subtype": 4, "flag_bytes": [176, 113, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -397,8 +503,23 @@ { "kind": "cargo_production_total_threshold", "comparator": "eq", + "value": 230 + }, + { + "kind": "factory_production_total_threshold", + "comparator": "eq", "value": 125 }, + { + "kind": "farm_mine_production_total_threshold", + "comparator": "eq", + "value": 75 + }, + { + "kind": "other_cargo_production_total_threshold", + "comparator": "eq", + "value": 30 + }, { "kind": "limited_track_building_amount_threshold", "comparator": "eq", @@ -419,7 +540,7 @@ ], "executable_import_ready": true, "notes": [ - "world-scalar conditions gate a whole-game effect, including a checked-in named cargo-production slot threshold" + "world-scalar conditions gate a whole-game effect, including checked-in aggregate cargo-class thresholds" ] } ] diff --git a/fixtures/runtime/packed-event-world-scalar-executable-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-executable-save-slice-fixture.json index ca4c34a..1c8a2ff 100644 --- a/fixtures/runtime/packed-event-world-scalar-executable-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-executable-save-slice-fixture.json @@ -47,7 +47,13 @@ "live_entry_ids": [41], "records": [ { - "import_outcome": "imported" + "import_outcome": "imported", + "grouped_effect_rows": [ + { + "descriptor_id": 230, + "recovered_cargo_class": "factory" + } + ] } ] }, diff --git a/fixtures/runtime/packed-event-world-scalar-executable-save-slice.json b/fixtures/runtime/packed-event-world-scalar-executable-save-slice.json index 02b3bb5..7b5e97b 100644 --- a/fixtures/runtime/packed-event-world-scalar-executable-save-slice.json +++ b/fixtures/runtime/packed-event-world-scalar-executable-save-slice.json @@ -26,17 +26,17 @@ "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 } + { "slot_id": 1, "label": "Cargo Production Slot 1", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "factory", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "farm_mine", "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", "cargo_class": "other", "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", "cargo_class": "other", "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", "cargo_class": "other", "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, @@ -101,7 +101,7 @@ "semantic_family": "scalar_assignment", "semantic_preview": "Set Cargo Production Slot 1 to 125", "recovered_cargo_slot": 1, - "recovered_cargo_class": null, + "recovered_cargo_class": "factory", "recovered_locomotive_id": null, "locomotive_name": null, "notes": []