Rehost save-world partial-year weighting inputs
This commit is contained in:
parent
2441fe6374
commit
b81b67d2b3
8 changed files with 119 additions and 2 deletions
|
|
@ -71,6 +71,9 @@ The fixed-world finance neighborhood itself is now widened to 17 dwords rooted a
|
|||
so future issue-`0x38/0x39` closure can build on a broader owned restore-state window rather than
|
||||
another 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.
|
||||
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
|
||||
to real world-calendar state instead of candidate bytes.
|
||||
The next company-side seam is now bundled too: a shared company
|
||||
market reader now exposes outstanding shares, assigned shares, public float, rounded cached share
|
||||
price, salary lanes, bonus amount, and the full two-word current/prior issue-calendar tuples from
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ pub struct ExpectedRuntimeSummary {
|
|||
#[serde(default)]
|
||||
pub world_restore_absolute_counter_reconstructible_from_save: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_packed_year_word_raw_u16: Option<u16>,
|
||||
#[serde(default)]
|
||||
pub world_restore_partial_year_progress_raw_u8: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub world_restore_current_calendar_tuple_word_raw_u32: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub world_restore_current_calendar_tuple_word_2_raw_u32: Option<u32>,
|
||||
|
|
@ -130,6 +134,8 @@ pub struct ExpectedRuntimeSummary {
|
|||
#[serde(default)]
|
||||
pub selected_company_years_since_last_dividend: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub selected_company_current_partial_year_weight_numerator: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub selected_company_chairman_bonus_year: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub selected_company_chairman_bonus_amount: Option<i32>,
|
||||
|
|
@ -377,6 +383,22 @@ impl ExpectedRuntimeSummary {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = self.world_restore_packed_year_word_raw_u16 {
|
||||
if actual.world_restore_packed_year_word_raw_u16 != Some(value) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_packed_year_word_raw_u16 mismatch: expected {value}, got {:?}",
|
||||
actual.world_restore_packed_year_word_raw_u16
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = self.world_restore_partial_year_progress_raw_u8 {
|
||||
if actual.world_restore_partial_year_progress_raw_u8 != Some(value) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_partial_year_progress_raw_u8 mismatch: expected {value}, got {:?}",
|
||||
actual.world_restore_partial_year_progress_raw_u8
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = self.world_restore_current_calendar_tuple_word_raw_u32 {
|
||||
if actual.world_restore_current_calendar_tuple_word_raw_u32 != Some(value) {
|
||||
mismatches.push(format!(
|
||||
|
|
@ -783,6 +805,14 @@ impl ExpectedRuntimeSummary {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = self.selected_company_current_partial_year_weight_numerator {
|
||||
if actual.selected_company_current_partial_year_weight_numerator != Some(value) {
|
||||
mismatches.push(format!(
|
||||
"selected_company_current_partial_year_weight_numerator mismatch: expected {value}, got {:?}",
|
||||
actual.selected_company_current_partial_year_weight_numerator
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(value) = self.selected_company_chairman_bonus_year {
|
||||
if actual.selected_company_chairman_bonus_year != Some(value) {
|
||||
mismatches.push(format!(
|
||||
|
|
|
|||
|
|
@ -743,6 +743,14 @@ fn project_save_slice_components(
|
|||
absolute_counter_reconstructible_from_save: Some(
|
||||
save_slice.world_finance_neighborhood_state.is_some(),
|
||||
),
|
||||
packed_year_word_raw_u16: save_slice
|
||||
.world_finance_neighborhood_state
|
||||
.as_ref()
|
||||
.map(|state| state.packed_year_word_raw_u16),
|
||||
partial_year_progress_raw_u8: save_slice
|
||||
.world_finance_neighborhood_state
|
||||
.as_ref()
|
||||
.map(|state| state.partial_year_progress_raw_u8),
|
||||
current_calendar_tuple_word_raw_u32: save_slice
|
||||
.world_finance_neighborhood_state
|
||||
.as_ref()
|
||||
|
|
@ -5842,6 +5850,10 @@ mod tests {
|
|||
world_finance_neighborhood_state: Some(crate::SmpLoadedWorldFinanceNeighborhoodState {
|
||||
source_kind: "save-fixed-world-block".to_string(),
|
||||
semantic_family: "world-finance-neighborhood".to_string(),
|
||||
packed_year_word_raw_u16: 0x0201,
|
||||
packed_year_word_raw_hex: "0x0201".to_string(),
|
||||
partial_year_progress_raw_u8: 3,
|
||||
partial_year_progress_raw_hex: "0x03".to_string(),
|
||||
current_calendar_tuple_word_raw_u32: 1,
|
||||
current_calendar_tuple_word_raw_hex: "0x00000001".to_string(),
|
||||
current_calendar_tuple_word_2_raw_u32: 2,
|
||||
|
|
@ -6045,6 +6057,14 @@ mod tests {
|
|||
.absolute_counter_reconstructible_from_save,
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.packed_year_word_raw_u16,
|
||||
Some(0x0201)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.partial_year_progress_raw_u8,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ pub struct RuntimeCompanyAnnualFinanceState {
|
|||
pub years_since_last_bankruptcy: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub years_since_last_dividend: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub current_partial_year_weight_numerator: Option<i64>,
|
||||
pub current_issue_calendar_word: u32,
|
||||
#[serde(default)]
|
||||
pub current_issue_calendar_word_2: u32,
|
||||
|
|
@ -989,6 +991,10 @@ pub struct RuntimeWorldRestoreState {
|
|||
#[serde(default)]
|
||||
pub current_calendar_tuple_word_raw_u32: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub packed_year_word_raw_u16: Option<u16>,
|
||||
#[serde(default)]
|
||||
pub partial_year_progress_raw_u8: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub current_calendar_tuple_word_2_raw_u32: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub absolute_counter_raw_u32: Option<u32>,
|
||||
|
|
@ -1921,6 +1927,10 @@ pub fn runtime_world_absolute_counter(state: &RuntimeState) -> Option<u32> {
|
|||
state.world_restore.absolute_counter_raw_u32
|
||||
}
|
||||
|
||||
pub fn runtime_world_partial_year_weight_numerator(state: &RuntimeState) -> Option<i64> {
|
||||
Some(i64::from(state.world_restore.partial_year_progress_raw_u8?) * 5 - 5)
|
||||
}
|
||||
|
||||
pub fn runtime_company_unassigned_share_pool(state: &RuntimeState, company_id: u32) -> Option<u32> {
|
||||
let outstanding_shares = state
|
||||
.service_state
|
||||
|
|
@ -1976,6 +1986,7 @@ pub fn runtime_company_annual_finance_state(
|
|||
years_since_founding,
|
||||
years_since_last_bankruptcy,
|
||||
years_since_last_dividend,
|
||||
current_partial_year_weight_numerator: runtime_world_partial_year_weight_numerator(state),
|
||||
current_issue_calendar_word: market_state.current_issue_calendar_word,
|
||||
current_issue_calendar_word_2: market_state.current_issue_calendar_word_2,
|
||||
prior_issue_calendar_word: market_state.prior_issue_calendar_word,
|
||||
|
|
@ -2582,6 +2593,8 @@ mod tests {
|
|||
seed_tuple_written_from_raw_lane: Some(true),
|
||||
absolute_counter_requires_shell_context: Some(true),
|
||||
absolute_counter_reconstructible_from_save: Some(false),
|
||||
packed_year_word_raw_u16: None,
|
||||
partial_year_progress_raw_u8: None,
|
||||
current_calendar_tuple_word_raw_u32: None,
|
||||
current_calendar_tuple_word_2_raw_u32: None,
|
||||
absolute_counter_raw_u32: None,
|
||||
|
|
@ -4111,6 +4124,8 @@ mod tests {
|
|||
world_restore: RuntimeWorldRestoreState {
|
||||
absolute_counter_raw_u32: Some(5),
|
||||
absolute_counter_mirror_raw_u32: Some(5),
|
||||
packed_year_word_raw_u16: Some(0x0210),
|
||||
partial_year_progress_raw_u8: Some(8),
|
||||
current_calendar_tuple_word_raw_u32: Some(0x0108_0210),
|
||||
current_calendar_tuple_word_2_raw_u32: Some(0x35e6_3160),
|
||||
..RuntimeWorldRestoreState::default()
|
||||
|
|
@ -4150,6 +4165,7 @@ mod tests {
|
|||
};
|
||||
|
||||
assert_eq!(runtime_world_absolute_counter(&state), Some(5));
|
||||
assert_eq!(runtime_world_partial_year_weight_numerator(&state), Some(35));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -4386,6 +4402,7 @@ mod tests {
|
|||
years_since_founding: None,
|
||||
years_since_last_bankruptcy: None,
|
||||
years_since_last_dividend: None,
|
||||
current_partial_year_weight_numerator: None,
|
||||
current_issue_calendar_word: 5,
|
||||
current_issue_calendar_word_2: 6,
|
||||
prior_issue_calendar_word: 4,
|
||||
|
|
|
|||
|
|
@ -1552,6 +1552,10 @@ pub struct SmpSaveWorldFinanceNeighborhoodProbe {
|
|||
pub payload_offset: usize,
|
||||
pub payload_len: usize,
|
||||
pub payload_len_hex: String,
|
||||
pub packed_year_word_raw_u16: u16,
|
||||
pub packed_year_word_raw_hex: String,
|
||||
pub partial_year_progress_raw_u8: u8,
|
||||
pub partial_year_progress_raw_hex: String,
|
||||
pub current_calendar_tuple_word_lane: SmpSaveDwordCandidate,
|
||||
pub current_calendar_tuple_word_2_lane: SmpSaveDwordCandidate,
|
||||
pub absolute_counter_lane: SmpSaveDwordCandidate,
|
||||
|
|
@ -2220,6 +2224,10 @@ pub struct SmpLoadedWorldEconomicTuningState {
|
|||
pub struct SmpLoadedWorldFinanceNeighborhoodState {
|
||||
pub source_kind: String,
|
||||
pub semantic_family: String,
|
||||
pub packed_year_word_raw_u16: u16,
|
||||
pub packed_year_word_raw_hex: String,
|
||||
pub partial_year_progress_raw_u8: u8,
|
||||
pub partial_year_progress_raw_hex: String,
|
||||
pub current_calendar_tuple_word_raw_u32: u32,
|
||||
pub current_calendar_tuple_word_raw_hex: String,
|
||||
pub current_calendar_tuple_word_2_raw_u32: u32,
|
||||
|
|
@ -3441,6 +3449,10 @@ fn derive_loaded_world_finance_neighborhood_state_from_probe(
|
|||
SmpLoadedWorldFinanceNeighborhoodState {
|
||||
source_kind: probe.source_kind.clone(),
|
||||
semantic_family: probe.semantic_family.clone(),
|
||||
packed_year_word_raw_u16: probe.packed_year_word_raw_u16,
|
||||
packed_year_word_raw_hex: probe.packed_year_word_raw_hex.clone(),
|
||||
partial_year_progress_raw_u8: probe.partial_year_progress_raw_u8,
|
||||
partial_year_progress_raw_hex: probe.partial_year_progress_raw_hex.clone(),
|
||||
current_calendar_tuple_word_raw_u32: probe.current_calendar_tuple_word_lane.raw_u32,
|
||||
current_calendar_tuple_word_raw_hex: probe
|
||||
.current_calendar_tuple_word_lane
|
||||
|
|
@ -8857,6 +8869,14 @@ fn parse_save_world_finance_neighborhood_probe(
|
|||
"current_calendar_tuple_word",
|
||||
RT3_SAVE_WORLD_BLOCK_CURRENT_CALENDAR_TUPLE_WORD_RELATIVE_OFFSET,
|
||||
)?;
|
||||
let packed_year_word_raw_u16 = read_u16_at(
|
||||
bytes,
|
||||
payload_offset + RT3_SAVE_WORLD_BLOCK_CURRENT_CALENDAR_TUPLE_WORD_RELATIVE_OFFSET,
|
||||
)?;
|
||||
let partial_year_progress_raw_u8 = read_u8_at(
|
||||
bytes,
|
||||
payload_offset + RT3_SAVE_WORLD_BLOCK_CURRENT_CALENDAR_TUPLE_WORD_RELATIVE_OFFSET + 2,
|
||||
)?;
|
||||
let current_calendar_tuple_word_2_lane = build_save_dword_candidate(
|
||||
bytes,
|
||||
payload_offset,
|
||||
|
|
@ -8886,6 +8906,10 @@ fn parse_save_world_finance_neighborhood_probe(
|
|||
payload_offset,
|
||||
payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
|
||||
payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
|
||||
packed_year_word_raw_u16,
|
||||
packed_year_word_raw_hex: format!("0x{packed_year_word_raw_u16:04x}"),
|
||||
partial_year_progress_raw_u8,
|
||||
partial_year_progress_raw_hex: format!("0x{partial_year_progress_raw_u8:02x}"),
|
||||
current_calendar_tuple_word_lane,
|
||||
current_calendar_tuple_word_2_lane,
|
||||
absolute_counter_lane,
|
||||
|
|
@ -15653,6 +15677,10 @@ mod tests {
|
|||
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS
|
||||
);
|
||||
assert_eq!(probe.current_calendar_tuple_word_lane.relative_offset_hex, "0xd");
|
||||
assert_eq!(probe.packed_year_word_raw_u16, 1);
|
||||
assert_eq!(probe.packed_year_word_raw_hex, "0x0001");
|
||||
assert_eq!(probe.partial_year_progress_raw_u8, 0);
|
||||
assert_eq!(probe.partial_year_progress_raw_hex, "0x00");
|
||||
assert_eq!(probe.current_calendar_tuple_word_lane.value_i32, 1);
|
||||
assert_eq!(probe.current_calendar_tuple_word_2_lane.relative_offset_hex, "0x11");
|
||||
assert_eq!(probe.current_calendar_tuple_word_2_lane.value_i32, 2);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ pub struct RuntimeSummary {
|
|||
pub world_restore_seed_tuple_written_from_raw_lane: Option<bool>,
|
||||
pub world_restore_absolute_counter_requires_shell_context: Option<bool>,
|
||||
pub world_restore_absolute_counter_reconstructible_from_save: Option<bool>,
|
||||
pub world_restore_packed_year_word_raw_u16: Option<u16>,
|
||||
pub world_restore_partial_year_progress_raw_u8: Option<u8>,
|
||||
pub world_restore_current_calendar_tuple_word_raw_u32: Option<u32>,
|
||||
pub world_restore_current_calendar_tuple_word_2_raw_u32: Option<u32>,
|
||||
pub world_restore_absolute_counter_raw_u32: Option<u32>,
|
||||
|
|
@ -69,6 +71,7 @@ pub struct RuntimeSummary {
|
|||
pub selected_company_years_since_founding: Option<u32>,
|
||||
pub selected_company_years_since_last_bankruptcy: Option<u32>,
|
||||
pub selected_company_years_since_last_dividend: Option<u32>,
|
||||
pub selected_company_current_partial_year_weight_numerator: Option<i64>,
|
||||
pub selected_company_chairman_bonus_year: Option<u32>,
|
||||
pub selected_company_chairman_bonus_amount: Option<i32>,
|
||||
pub player_count: usize,
|
||||
|
|
@ -182,6 +185,12 @@ impl RuntimeSummary {
|
|||
world_restore_absolute_counter_reconstructible_from_save: state
|
||||
.world_restore
|
||||
.absolute_counter_reconstructible_from_save,
|
||||
world_restore_packed_year_word_raw_u16: state
|
||||
.world_restore
|
||||
.packed_year_word_raw_u16,
|
||||
world_restore_partial_year_progress_raw_u8: state
|
||||
.world_restore
|
||||
.partial_year_progress_raw_u8,
|
||||
world_restore_current_calendar_tuple_word_raw_u32: state
|
||||
.world_restore
|
||||
.current_calendar_tuple_word_raw_u32,
|
||||
|
|
@ -319,6 +328,9 @@ impl RuntimeSummary {
|
|||
selected_company_years_since_last_dividend: selected_company_annual_finance_state
|
||||
.as_ref()
|
||||
.and_then(|finance_state| finance_state.years_since_last_dividend),
|
||||
selected_company_current_partial_year_weight_numerator: selected_company_annual_finance_state
|
||||
.as_ref()
|
||||
.and_then(|finance_state| finance_state.current_partial_year_weight_numerator),
|
||||
selected_company_chairman_bonus_year: selected_company_market_state
|
||||
.map(|market_state| market_state.chairman_bonus_year)
|
||||
.filter(|year| *year != 0),
|
||||
|
|
@ -1158,6 +1170,8 @@ mod tests {
|
|||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState {
|
||||
packed_year_word_raw_u16: Some(0x0201),
|
||||
partial_year_progress_raw_u8: Some(3),
|
||||
current_calendar_tuple_word_raw_u32: Some(0x0108_0210),
|
||||
current_calendar_tuple_word_2_raw_u32: Some(0x35e6_3160),
|
||||
absolute_counter_raw_u32: Some(5),
|
||||
|
|
@ -1226,6 +1240,8 @@ mod tests {
|
|||
|
||||
let summary = RuntimeSummary::from_state(&state);
|
||||
|
||||
assert_eq!(summary.world_restore_packed_year_word_raw_u16, Some(0x0201));
|
||||
assert_eq!(summary.world_restore_partial_year_progress_raw_u8, Some(3));
|
||||
assert_eq!(
|
||||
summary.world_restore_current_calendar_tuple_word_raw_u32,
|
||||
Some(0x0108_0210)
|
||||
|
|
|
|||
|
|
@ -124,7 +124,9 @@ The highest-value next passes are now:
|
|||
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
|
||||
closure 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; the same annual-finance state now also
|
||||
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
|
||||
behind annual-finance recent-history weighting; the same annual-finance state now also
|
||||
feeds a shared company market reader for stock-capital, salary, bonus, and the full two-word
|
||||
current/prior issue-calendar tuples, and now derives elapsed years since founding, last dividend,
|
||||
and last bankruptcy for later annual finance-policy rehosting; live bond-slot count now travels through that same owned annual-finance
|
||||
|
|
|
|||
|
|
@ -213,7 +213,8 @@ scattered single-field helpers. The fixed-world finance neighborhood is now wide
|
|||
rooted at `[world+0x0d]`, so later issue-`0x38/0x39` closure can build on a broader owned
|
||||
restore-state window 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
|
||||
metadata. The same owned company annual-finance state
|
||||
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
|
||||
now also drives a shared company market reader seam for stock-capital, salary, bonus, and the full
|
||||
two-word current/prior issue-calendar tuples, which is a better base for shellless finance
|
||||
simulation than summary-only helpers. That same owned annual-finance state now also derives elapsed
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue