Rehost save-world governance issue byte strip

This commit is contained in:
Jan Petykiewicz 2026-04-17 22:14:08 -07:00
commit d99b7eb5c0
9 changed files with 242 additions and 15 deletions

View file

@ -43,7 +43,9 @@ surface also now exposes `runtime inspect-save-company-chairman <save.gms>` for
company/chairman scalar candidates, including fixed-world chairman slot / role-gate context, company/chairman scalar candidates, including fixed-world chairman slot / role-gate context,
explicit company dword candidate windows, richer chairman qword cache views, and derived explicit company dword candidate windows, richer chairman qword cache views, and derived
holdings-at-share-price / cached purchasing-power comparisons. The same fixed `0x32c8` world holdings-at-share-price / cached purchasing-power comparisons. The same fixed `0x32c8` world
block is now probed for the grounded issue-`0x37` pair at `[world+0x29/+0x2d]`, one broader block is now probed for the grounded issue-`0x37` pair at `[world+0x29/+0x2d]`, and the adjacent
raw issue-byte strip `0x37..0x3a` now also flows through save-slice/runtime restore state as
first-class owner data for later credit / prime-rate / management-attitude readers. One broader
fixed-dword finance neighborhood rooted at `[world+0x0d]` that now carries the saved calendar fixed-dword finance neighborhood rooted at `[world+0x0d]` that now carries the saved calendar
tuple and absolute-counter owner lanes directly, and the separate tuple and absolute-counter owner lanes directly, and the separate
six-float economic tuning band, but current atlas evidence still keeps that editor-facing six-float economic tuning band, but current atlas evidence still keeps that editor-facing
@ -68,8 +70,8 @@ counter. The next bundled annual-finance reader seam is now rehosted on top of t
state too, deriving assigned shares, public float, and rounded cached share price from one shared state too, deriving assigned shares, public float, and rounded cached share price from one shared
company market reader instead of scattering more finance helpers across the runtime. A checked-in company market reader instead of scattering more finance helpers across the runtime. A checked-in
The fixed-world finance neighborhood itself is now widened to 17 dwords rooted at `[world+0x0d]`, The fixed-world finance neighborhood itself is now widened to 17 dwords rooted at `[world+0x0d]`,
so future issue-`0x38/0x39` closure can build on a broader owned restore-state window rather than so later finance closure can build on a broader owned restore-state window rather than another
another narrow one-off probe; that same owner surface now also carries the saved absolute counter narrow one-off probe; that same owner surface now also carries the saved absolute counter
as first-class runtime restore state instead of leaving it on “requires shell context” metadata. as first-class runtime restore state instead of leaving it on “requires shell context” metadata.
The same save-world owner surface now also carries the packed year word and partial-year progress The same save-world owner surface now also carries the packed year word and partial-year progress
lane behind the annual-finance recent-history weighting path, so later finance readers can attach lane behind the annual-finance recent-history weighting path, so later finance readers can attach

View file

@ -74,6 +74,12 @@ pub struct ExpectedRuntimeSummary {
#[serde(default)] #[serde(default)]
pub world_restore_issue_37_value: Option<u32>, pub world_restore_issue_37_value: Option<u32>,
#[serde(default)] #[serde(default)]
pub world_restore_issue_38_value: Option<u32>,
#[serde(default)]
pub world_restore_issue_39_value: Option<u32>,
#[serde(default)]
pub world_restore_issue_3a_value: Option<u32>,
#[serde(default)]
pub world_restore_issue_37_multiplier_raw_u32: Option<u32>, pub world_restore_issue_37_multiplier_raw_u32: Option<u32>,
#[serde(default)] #[serde(default)]
pub world_restore_issue_37_multiplier_value_f32_text: Option<String>, pub world_restore_issue_37_multiplier_value_f32_text: Option<String>,
@ -545,6 +551,30 @@ impl ExpectedRuntimeSummary {
)); ));
} }
} }
if let Some(value) = self.world_restore_issue_38_value {
if actual.world_restore_issue_38_value != Some(value) {
mismatches.push(format!(
"world_restore_issue_38_value mismatch: expected {value}, got {:?}",
actual.world_restore_issue_38_value
));
}
}
if let Some(value) = self.world_restore_issue_39_value {
if actual.world_restore_issue_39_value != Some(value) {
mismatches.push(format!(
"world_restore_issue_39_value mismatch: expected {value}, got {:?}",
actual.world_restore_issue_39_value
));
}
}
if let Some(value) = self.world_restore_issue_3a_value {
if actual.world_restore_issue_3a_value != Some(value) {
mismatches.push(format!(
"world_restore_issue_3a_value mismatch: expected {value}, got {:?}",
actual.world_restore_issue_3a_value
));
}
}
if let Some(value) = self.world_restore_issue_37_multiplier_raw_u32 { if let Some(value) = self.world_restore_issue_37_multiplier_raw_u32 {
if actual.world_restore_issue_37_multiplier_raw_u32 != Some(value) { if actual.world_restore_issue_37_multiplier_raw_u32 != Some(value) {
mismatches.push(format!( mismatches.push(format!(

View file

@ -598,6 +598,30 @@ fn project_save_slice_components(
"save_slice.world_issue_37_value_hex".to_string(), "save_slice.world_issue_37_value_hex".to_string(),
issue_state.issue_value_hex.clone(), issue_state.issue_value_hex.clone(),
); );
metadata.insert(
"save_slice.world_issue_38_value".to_string(),
issue_state.issue_38_value.to_string(),
);
metadata.insert(
"save_slice.world_issue_38_value_hex".to_string(),
issue_state.issue_38_value_hex.clone(),
);
metadata.insert(
"save_slice.world_issue_39_value".to_string(),
issue_state.issue_39_value.to_string(),
);
metadata.insert(
"save_slice.world_issue_39_value_hex".to_string(),
issue_state.issue_39_value_hex.clone(),
);
metadata.insert(
"save_slice.world_issue_3a_value".to_string(),
issue_state.issue_3a_value.to_string(),
);
metadata.insert(
"save_slice.world_issue_3a_value_hex".to_string(),
issue_state.issue_3a_value_hex.clone(),
);
metadata.insert( metadata.insert(
"save_slice.world_issue_37_multiplier_raw_hex".to_string(), "save_slice.world_issue_37_multiplier_raw_hex".to_string(),
issue_state.multiplier_raw_hex.clone(), issue_state.multiplier_raw_hex.clone(),
@ -783,6 +807,18 @@ fn project_save_slice_components(
.world_issue_37_state .world_issue_37_state
.as_ref() .as_ref()
.map(|state| state.issue_value), .map(|state| state.issue_value),
issue_38_value: save_slice
.world_issue_37_state
.as_ref()
.map(|state| state.issue_38_value),
issue_39_value: save_slice
.world_issue_37_state
.as_ref()
.map(|state| state.issue_39_value),
issue_3a_value: save_slice
.world_issue_37_state
.as_ref()
.map(|state| state.issue_3a_value),
issue_37_multiplier_raw_u32: save_slice issue_37_multiplier_raw_u32: save_slice
.world_issue_37_state .world_issue_37_state
.as_ref() .as_ref()
@ -5833,6 +5869,12 @@ mod tests {
semantic_family: "world-issue-0x37".to_string(), semantic_family: "world-issue-0x37".to_string(),
issue_value: 3, issue_value: 3,
issue_value_hex: "0x00000003".to_string(), issue_value_hex: "0x00000003".to_string(),
issue_38_value: 1,
issue_38_value_hex: "0x01".to_string(),
issue_39_value: 2,
issue_39_value_hex: "0x02".to_string(),
issue_3a_value: 4,
issue_3a_value_hex: "0x04".to_string(),
multiplier_raw_u32: 0x3d75c28f, multiplier_raw_u32: 0x3d75c28f,
multiplier_raw_hex: "0x3d75c28f".to_string(), multiplier_raw_hex: "0x3d75c28f".to_string(),
multiplier_value_f32_text: "0.060000".to_string(), multiplier_value_f32_text: "0.060000".to_string(),
@ -6145,6 +6187,9 @@ mod tests {
Some(false) Some(false)
); );
assert_eq!(import.state.world_restore.issue_37_value, Some(3)); assert_eq!(import.state.world_restore.issue_37_value, Some(3));
assert_eq!(import.state.world_restore.issue_38_value, Some(1));
assert_eq!(import.state.world_restore.issue_39_value, Some(2));
assert_eq!(import.state.world_restore.issue_3a_value, Some(4));
assert_eq!( assert_eq!(
import.state.world_restore.issue_37_multiplier_raw_u32, import.state.world_restore.issue_37_multiplier_raw_u32,
Some(0x3d75c28f) Some(0x3d75c28f)
@ -6229,6 +6274,14 @@ mod tests {
.map(String::as_str), .map(String::as_str),
Some("3") Some("3")
); );
assert_eq!(
import
.state
.metadata
.get("save_slice.world_issue_39_value")
.map(String::as_str),
Some("2")
);
assert_eq!( assert_eq!(
import import
.state .state

View file

@ -45,7 +45,9 @@ pub use pk4::{
}; };
pub use runtime::{ pub use runtime::{
RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER, RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE, RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER, RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE,
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH, RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE, RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH, RUNTIME_WORLD_ISSUE_CREDIT_MARKET,
RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE, RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE,
RUNTIME_WORLD_ISSUE_PRIME_RATE,
RuntimeCargoCatalogEntry, RuntimeCargoClass, RuntimeCargoPriceTarget, RuntimeCargoCatalogEntry, RuntimeCargoClass, RuntimeCargoPriceTarget,
RuntimeCargoProductionTarget, RuntimeChairmanMetric, RuntimeChairmanProfile, RuntimeCargoProductionTarget, RuntimeChairmanMetric, RuntimeChairmanProfile,
RuntimeChairmanTarget, RuntimeCompany, RuntimeCompanyAnnualFinanceState, RuntimeChairmanTarget, RuntimeCompany, RuntimeCompanyAnnualFinanceState,

View file

@ -407,13 +407,18 @@ pub const RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER: u32 = 0x2329;
pub const RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH: u32 = 0x0d; pub const RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH: u32 = 0x0d;
pub const RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE: u32 = 0x1d; pub const RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE: u32 = 0x1d;
pub const RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE: u32 = 0x37; pub const RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE: u32 = 0x37;
pub const RUNTIME_WORLD_ISSUE_CREDIT_MARKET: u32 = 0x38;
pub const RUNTIME_WORLD_ISSUE_PRIME_RATE: u32 = 0x39;
pub const RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE: u32 = 0x3a;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeWorldIssueState { pub struct RuntimeWorldIssueState {
pub issue_id: u32, pub issue_id: u32,
pub raw_value_u32: u32, pub raw_value_u32: u32,
pub multiplier_raw_u32: u32, #[serde(default)]
pub multiplier_value_f32_text: String, pub multiplier_raw_u32: Option<u32>,
#[serde(default)]
pub multiplier_value_f32_text: Option<String>,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
@ -1027,6 +1032,12 @@ pub struct RuntimeWorldRestoreState {
#[serde(default)] #[serde(default)]
pub issue_37_value: Option<u32>, pub issue_37_value: Option<u32>,
#[serde(default)] #[serde(default)]
pub issue_38_value: Option<u32>,
#[serde(default)]
pub issue_39_value: Option<u32>,
#[serde(default)]
pub issue_3a_value: Option<u32>,
#[serde(default)]
pub issue_37_multiplier_raw_u32: Option<u32>, pub issue_37_multiplier_raw_u32: Option<u32>,
#[serde(default)] #[serde(default)]
pub issue_37_multiplier_value_f32_text: Option<String>, pub issue_37_multiplier_value_f32_text: Option<String>,
@ -1913,11 +1924,29 @@ pub fn runtime_world_issue_state(
RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE => Some(RuntimeWorldIssueState { RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE => Some(RuntimeWorldIssueState {
issue_id, issue_id,
raw_value_u32: state.world_restore.issue_37_value?, raw_value_u32: state.world_restore.issue_37_value?,
multiplier_raw_u32: state.world_restore.issue_37_multiplier_raw_u32?, multiplier_raw_u32: state.world_restore.issue_37_multiplier_raw_u32,
multiplier_value_f32_text: state multiplier_value_f32_text: state
.world_restore .world_restore
.issue_37_multiplier_value_f32_text .issue_37_multiplier_value_f32_text
.clone()?, .clone(),
}),
RUNTIME_WORLD_ISSUE_CREDIT_MARKET => Some(RuntimeWorldIssueState {
issue_id,
raw_value_u32: state.world_restore.issue_38_value?,
multiplier_raw_u32: None,
multiplier_value_f32_text: None,
}),
RUNTIME_WORLD_ISSUE_PRIME_RATE => Some(RuntimeWorldIssueState {
issue_id,
raw_value_u32: state.world_restore.issue_39_value?,
multiplier_raw_u32: None,
multiplier_value_f32_text: None,
}),
RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE => Some(RuntimeWorldIssueState {
issue_id,
raw_value_u32: state.world_restore.issue_3a_value?,
multiplier_raw_u32: None,
multiplier_value_f32_text: None,
}), }),
_ => None, _ => None,
} }
@ -2612,6 +2641,9 @@ mod tests {
economic_status_code: None, economic_status_code: None,
territory_access_cost: None, territory_access_cost: None,
issue_37_value: None, issue_37_value: None,
issue_38_value: None,
issue_39_value: None,
issue_3a_value: None,
issue_37_multiplier_raw_u32: None, issue_37_multiplier_raw_u32: None,
issue_37_multiplier_value_f32_text: None, issue_37_multiplier_value_f32_text: None,
finance_neighborhood_candidates: Vec::new(), finance_neighborhood_candidates: Vec::new(),
@ -4062,6 +4094,9 @@ mod tests {
save_profile: RuntimeSaveProfileState::default(), save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState { world_restore: RuntimeWorldRestoreState {
issue_37_value: Some(3), issue_37_value: Some(3),
issue_38_value: Some(1),
issue_39_value: Some(2),
issue_3a_value: Some(4),
issue_37_multiplier_raw_u32: Some(0x3d75c28f), issue_37_multiplier_raw_u32: Some(0x3d75c28f),
issue_37_multiplier_value_f32_text: Some("0.060000".to_string()), issue_37_multiplier_value_f32_text: Some("0.060000".to_string()),
..RuntimeWorldRestoreState::default() ..RuntimeWorldRestoreState::default()
@ -4104,9 +4139,27 @@ mod tests {
.expect("grounded issue 0x37 state"); .expect("grounded issue 0x37 state");
assert_eq!(issue.issue_id, RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE); assert_eq!(issue.issue_id, RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE);
assert_eq!(issue.raw_value_u32, 3); assert_eq!(issue.raw_value_u32, 3);
assert_eq!(issue.multiplier_raw_u32, 0x3d75c28f); assert_eq!(issue.multiplier_raw_u32, Some(0x3d75c28f));
assert_eq!(issue.multiplier_value_f32_text, "0.060000"); assert_eq!(issue.multiplier_value_f32_text.as_deref(), Some("0.060000"));
assert_eq!(runtime_world_issue_state(&state, 0x39), None); assert_eq!(
runtime_world_issue_state(&state, RUNTIME_WORLD_ISSUE_CREDIT_MARKET)
.expect("grounded issue 0x38 state")
.raw_value_u32,
1
);
assert_eq!(
runtime_world_issue_state(&state, RUNTIME_WORLD_ISSUE_PRIME_RATE)
.expect("grounded issue 0x39 state")
.raw_value_u32,
2
);
assert_eq!(
runtime_world_issue_state(&state, RUNTIME_WORLD_ISSUE_MANAGEMENT_ATTITUDE)
.expect("grounded issue 0x3a state")
.raw_value_u32,
4
);
assert_eq!(runtime_world_issue_state(&state, 0x40), None);
assert_eq!(runtime_world_absolute_counter(&state), None); assert_eq!(runtime_world_absolute_counter(&state), None);
} }

View file

@ -1538,6 +1538,14 @@ pub struct SmpSaveWorldIssue37Probe {
pub payload_offset: usize, pub payload_offset: usize,
pub payload_len: usize, pub payload_len: usize,
pub payload_len_hex: String, pub payload_len_hex: String,
pub issue_37_raw_u8: u8,
pub issue_37_raw_hex: String,
pub issue_38_raw_u8: u8,
pub issue_38_raw_hex: String,
pub issue_39_raw_u8: u8,
pub issue_39_raw_hex: String,
pub issue_3a_raw_u8: u8,
pub issue_3a_raw_hex: String,
pub issue_value_lane: SmpSaveDwordCandidate, pub issue_value_lane: SmpSaveDwordCandidate,
pub multiplier_lane: SmpSaveDwordCandidate, pub multiplier_lane: SmpSaveDwordCandidate,
pub evidence: Vec<String>, pub evidence: Vec<String>,
@ -2203,6 +2211,12 @@ pub struct SmpLoadedWorldIssue37State {
pub semantic_family: String, pub semantic_family: String,
pub issue_value: u32, pub issue_value: u32,
pub issue_value_hex: String, pub issue_value_hex: String,
pub issue_38_value: u32,
pub issue_38_value_hex: String,
pub issue_39_value: u32,
pub issue_39_value_hex: String,
pub issue_3a_value: u32,
pub issue_3a_value_hex: String,
pub multiplier_raw_u32: u32, pub multiplier_raw_u32: u32,
pub multiplier_raw_hex: String, pub multiplier_raw_hex: String,
pub multiplier_value_f32_text: String, pub multiplier_value_f32_text: String,
@ -3414,6 +3428,12 @@ fn derive_loaded_world_issue_37_state_from_probe(
semantic_family: probe.semantic_family.clone(), semantic_family: probe.semantic_family.clone(),
issue_value: probe.issue_value_lane.raw_u32, issue_value: probe.issue_value_lane.raw_u32,
issue_value_hex: probe.issue_value_lane.raw_u32_hex.clone(), issue_value_hex: probe.issue_value_lane.raw_u32_hex.clone(),
issue_38_value: u32::from(probe.issue_38_raw_u8),
issue_38_value_hex: probe.issue_38_raw_hex.clone(),
issue_39_value: u32::from(probe.issue_39_raw_u8),
issue_39_value_hex: probe.issue_39_raw_hex.clone(),
issue_3a_value: u32::from(probe.issue_3a_raw_u8),
issue_3a_value_hex: probe.issue_3a_raw_hex.clone(),
multiplier_raw_u32: probe.multiplier_lane.raw_u32, multiplier_raw_u32: probe.multiplier_lane.raw_u32,
multiplier_raw_hex: probe.multiplier_lane.raw_u32_hex.clone(), multiplier_raw_hex: probe.multiplier_lane.raw_u32_hex.clone(),
multiplier_value_f32_text: format!("{:.6}", probe.multiplier_lane.value_f32), multiplier_value_f32_text: format!("{:.6}", probe.multiplier_lane.value_f32),
@ -8798,6 +8818,22 @@ fn parse_save_world_issue_37_probe(
"issue_0x37_value", "issue_0x37_value",
RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET, RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
)?; )?;
let issue_37_raw_u8 = read_u8_at(
bytes,
payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
)?;
let issue_38_raw_u8 = read_u8_at(
bytes,
payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 1,
)?;
let issue_39_raw_u8 = read_u8_at(
bytes,
payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 2,
)?;
let issue_3a_raw_u8 = read_u8_at(
bytes,
payload_offset + RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 3,
)?;
let multiplier_lane = build_save_dword_candidate( let multiplier_lane = build_save_dword_candidate(
bytes, bytes,
payload_offset, payload_offset,
@ -8812,6 +8848,14 @@ fn parse_save_world_issue_37_probe(
payload_offset, payload_offset,
payload_len: RT3_SAVE_WORLD_BLOCK_LEN, payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN), payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
issue_37_raw_u8,
issue_37_raw_hex: format!("0x{issue_37_raw_u8:02x}"),
issue_38_raw_u8,
issue_38_raw_hex: format!("0x{issue_38_raw_u8:02x}"),
issue_39_raw_u8,
issue_39_raw_hex: format!("0x{issue_39_raw_u8:02x}"),
issue_3a_raw_u8,
issue_3a_raw_hex: format!("0x{issue_3a_raw_u8:02x}"),
issue_value_lane, issue_value_lane,
multiplier_lane, multiplier_lane,
evidence: vec![ evidence: vec![
@ -8829,6 +8873,15 @@ fn parse_save_world_issue_37_probe(
"multiplier lane uses payload +0x{:x} ([world+0x29]); atlas notes tie 0x004339b0 to one companion scalar at that lane before company share-price refresh", "multiplier lane uses payload +0x{:x} ([world+0x29]); atlas notes tie 0x004339b0 to one companion scalar at that lane before company share-price refresh",
RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET
), ),
format!(
"the adjacent byte strip at payload +0x{:x}..+0x{:x} carries raw issue slots 0x37..0x3a as {:02x} {:02x} {:02x} {:02x}",
RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET,
RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET + 3,
issue_37_raw_u8,
issue_38_raw_u8,
issue_39_raw_u8,
issue_3a_raw_u8
),
], ],
}); });
} }
@ -15638,6 +15691,14 @@ mod tests {
assert_eq!(probe.payload_offset, payload_offset); assert_eq!(probe.payload_offset, payload_offset);
assert_eq!(probe.issue_value_lane.relative_offset_hex, "0x29"); assert_eq!(probe.issue_value_lane.relative_offset_hex, "0x29");
assert_eq!(probe.issue_value_lane.value_i32, 3); assert_eq!(probe.issue_value_lane.value_i32, 3);
assert_eq!(probe.issue_37_raw_u8, 3);
assert_eq!(probe.issue_37_raw_hex, "0x03");
assert_eq!(probe.issue_38_raw_u8, 0);
assert_eq!(probe.issue_38_raw_hex, "0x00");
assert_eq!(probe.issue_39_raw_u8, 0);
assert_eq!(probe.issue_39_raw_hex, "0x00");
assert_eq!(probe.issue_3a_raw_u8, 0);
assert_eq!(probe.issue_3a_raw_hex, "0x00");
assert_eq!(probe.multiplier_lane.relative_offset_hex, "0x25"); assert_eq!(probe.multiplier_lane.relative_offset_hex, "0x25");
assert!((probe.multiplier_lane.value_f32 - 0.06).abs() < f32::EPSILON); assert!((probe.multiplier_lane.value_f32 - 0.06).abs() < f32::EPSILON);
} }
@ -15765,6 +15826,14 @@ mod tests {
payload_offset: 0x3d2, payload_offset: 0x3d2,
payload_len: RT3_SAVE_WORLD_BLOCK_LEN, payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN), payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
issue_37_raw_u8: 3,
issue_37_raw_hex: "0x03".to_string(),
issue_38_raw_u8: 1,
issue_38_raw_hex: "0x01".to_string(),
issue_39_raw_u8: 2,
issue_39_raw_hex: "0x02".to_string(),
issue_3a_raw_u8: 4,
issue_3a_raw_hex: "0x04".to_string(),
issue_value_lane: SmpSaveDwordCandidate { issue_value_lane: SmpSaveDwordCandidate {
label: "issue_0x37_value".to_string(), label: "issue_0x37_value".to_string(),
relative_offset: 0x29, relative_offset: 0x29,
@ -15895,6 +15964,9 @@ mod tests {
.world_issue_37_state .world_issue_37_state
.expect("world issue-0x37 state should load"); .expect("world issue-0x37 state should load");
assert_eq!(issue_37_state.issue_value, 3); assert_eq!(issue_37_state.issue_value, 3);
assert_eq!(issue_37_state.issue_38_value, 1);
assert_eq!(issue_37_state.issue_39_value, 2);
assert_eq!(issue_37_state.issue_3a_value, 4);
assert_eq!(issue_37_state.multiplier_raw_hex, "0x3d75c28f"); assert_eq!(issue_37_state.multiplier_raw_hex, "0x3d75c28f");
assert_eq!(issue_37_state.multiplier_value_f32_text, "0.060000"); assert_eq!(issue_37_state.multiplier_value_f32_text, "0.060000");
let tuning_state = slice let tuning_state = slice

View file

@ -41,6 +41,9 @@ pub struct RuntimeSummary {
pub world_restore_economic_status_code: Option<i32>, pub world_restore_economic_status_code: Option<i32>,
pub world_restore_territory_access_cost: Option<u32>, pub world_restore_territory_access_cost: Option<u32>,
pub world_restore_issue_37_value: Option<u32>, pub world_restore_issue_37_value: Option<u32>,
pub world_restore_issue_38_value: Option<u32>,
pub world_restore_issue_39_value: Option<u32>,
pub world_restore_issue_3a_value: Option<u32>,
pub world_restore_issue_37_multiplier_raw_u32: Option<u32>, pub world_restore_issue_37_multiplier_raw_u32: Option<u32>,
pub world_restore_issue_37_multiplier_value_f32_text: Option<String>, pub world_restore_issue_37_multiplier_value_f32_text: Option<String>,
pub world_restore_finance_neighborhood_count: usize, pub world_restore_finance_neighborhood_count: usize,
@ -236,6 +239,9 @@ impl RuntimeSummary {
world_restore_economic_status_code: state.world_restore.economic_status_code, world_restore_economic_status_code: state.world_restore.economic_status_code,
world_restore_territory_access_cost: state.world_restore.territory_access_cost, world_restore_territory_access_cost: state.world_restore.territory_access_cost,
world_restore_issue_37_value: state.world_restore.issue_37_value, world_restore_issue_37_value: state.world_restore.issue_37_value,
world_restore_issue_38_value: state.world_restore.issue_38_value,
world_restore_issue_39_value: state.world_restore.issue_39_value,
world_restore_issue_3a_value: state.world_restore.issue_3a_value,
world_restore_issue_37_multiplier_raw_u32: state world_restore_issue_37_multiplier_raw_u32: state
.world_restore .world_restore
.issue_37_multiplier_raw_u32, .issue_37_multiplier_raw_u32,
@ -1177,6 +1183,9 @@ mod tests {
absolute_counter_raw_u32: Some(5), absolute_counter_raw_u32: Some(5),
absolute_counter_mirror_raw_u32: Some(5), absolute_counter_mirror_raw_u32: Some(5),
issue_37_value: Some(3), issue_37_value: Some(3),
issue_38_value: Some(1),
issue_39_value: Some(2),
issue_3a_value: Some(4),
issue_37_multiplier_raw_u32: Some(0x3d75c28f), issue_37_multiplier_raw_u32: Some(0x3d75c28f),
issue_37_multiplier_value_f32_text: Some("0.06".to_string()), issue_37_multiplier_value_f32_text: Some("0.06".to_string()),
economic_tuning_mirror_raw_u32: Some(0x3f46dff5), economic_tuning_mirror_raw_u32: Some(0x3f46dff5),
@ -1256,6 +1265,9 @@ mod tests {
Some(5) Some(5)
); );
assert_eq!(summary.world_restore_issue_37_value, Some(3)); assert_eq!(summary.world_restore_issue_37_value, Some(3));
assert_eq!(summary.world_restore_issue_38_value, Some(1));
assert_eq!(summary.world_restore_issue_39_value, Some(2));
assert_eq!(summary.world_restore_issue_3a_value, Some(4));
assert_eq!( assert_eq!(
summary.world_restore_issue_37_multiplier_raw_u32, summary.world_restore_issue_37_multiplier_raw_u32,
Some(0x3d75c28f) Some(0x3d75c28f)

View file

@ -118,12 +118,14 @@ The highest-value next passes are now:
owned runtime data instead of one more guessed save offset; the first runtime-side `0x2329` owned runtime data instead of one more guessed save offset; the first runtime-side `0x2329`
stat-family reader seam is now also rehosted for slots `0x0d` and `0x1d`, and the saved stat-family reader seam is now also rehosted for slots `0x0d` and `0x1d`, and the saved
stat-band windows themselves now carry 32 dwords per root; the matching world-side issue reader stat-band windows themselves now carry 32 dwords per root; the matching world-side issue reader
seam is now rehosted for the grounded `0x37` lane, and selected-company summaries now expose the seam is now rehosted for the grounded `0x37` lane, and the adjacent raw issue-byte strip
`0x37..0x3a` now also flows through save-slice/runtime restore state for later credit / prime
/ management readers; selected-company summaries now expose the
unassigned share pool derived from outstanding shares minus chairman-held shares for later annual unassigned share pool derived from outstanding shares minus chairman-held shares for later annual
finance logic; that same owned company market state now also backs a bundled annual-finance finance logic; that same owned company market state now also backs a bundled annual-finance
reader seam for assigned shares, public float, and rounded cached share price; the fixed-world reader seam for assigned shares, public float, and rounded cached share price; the fixed-world
finance neighborhood is now widened to 17 dwords rooted at `[world+0x0d]` so later issue-family finance neighborhood is now widened to 17 dwords rooted at `[world+0x0d]` so later issue-family
closure can target a broader owned restore-state window, and the saved absolute counter now readers can target a broader owned restore-state window, and the saved absolute counter now
flows through normal runtime restore state instead of staying on shell-context metadata; that flows through normal runtime restore state instead of staying on shell-context metadata; that
same world owner surface now also carries the packed year word and partial-year progress lane same world owner surface now also carries the packed year word and partial-year progress lane
behind annual-finance recent-history weighting; the same annual-finance state now also behind annual-finance recent-history weighting; the same annual-finance state now also

View file

@ -210,8 +210,9 @@ reader instead of guessing another finance leaf. The same owned company market s
supports a bundled annual-finance reader seam for assigned shares, public float, and rounded supports a bundled annual-finance reader seam for assigned shares, public float, and rounded
cached share price, which is a better base for later dividend / issue-calendar simulation than cached share price, which is a better base for later dividend / issue-calendar simulation than
scattered single-field helpers. The fixed-world finance neighborhood is now widened to 17 dwords scattered single-field helpers. The fixed-world finance neighborhood is now widened to 17 dwords
rooted at `[world+0x0d]`, so later issue-`0x38/0x39` closure can build on a broader owned rooted at `[world+0x0d]`, and the adjacent raw world issue-byte strip `0x37..0x3a` now also
restore-state window instead of another narrow probe; that same owner surface now also carries flows through save-slice/runtime restore state, so later credit / prime / management readers can
build on owned issue state instead of another narrow probe; that same owner surface now also carries
the saved world absolute counter as first-class runtime restore state instead of shell-context the saved world absolute counter as first-class runtime restore state instead of shell-context
metadata, plus the packed year word and partial-year progress lane that feed the annual-finance metadata, plus the packed year word and partial-year progress lane that feed the annual-finance
recent-history weighting path. The same owned company annual-finance state recent-history weighting path. The same owned company annual-finance state