Rehost route preference override mutation seam

This commit is contained in:
Jan Petykiewicz 2026-04-18 07:49:37 -07:00
commit cdab16476e
8 changed files with 361 additions and 16 deletions

View file

@ -144,6 +144,11 @@ chooser byte that sits beside the city-connection and linked-transit finance gat
That same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the That same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the
effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x` effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x`
route-quality multiplier as a normal runtime reader instead of leaving that bridge in atlas notes. route-quality multiplier as a normal runtime reader instead of leaving that bridge in atlas notes.
That same seam now also owns the first route-preference mutation path directly: beginning the
electric-only periodic-company override rewrites the world route-preference byte to the effective
company preference, ending it restores the base world byte, and runtime service state now carries
both the active and last applied override instead of treating the route-preference lane as a
reader-only bridge.
That same seam now also derives the current live coupon burden directly from owned bond slots, so That same seam now also derives the current live coupon burden directly from owned bond slots, so
later finance service work can consume a runtime reader instead of recomputing from scattered raw later finance service work can consume a runtime reader instead of recomputing from scattered raw
fields. fields.
@ -152,7 +157,10 @@ chairman personality byte, which is enough to run the annual stock-repurchase ga
pure reader over owned save-native state instead of a guessed finance-side approximation. pure reader over owned save-native state instead of a guessed finance-side approximation.
The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
should prefer rehosting the owning source state or the real reader/setter family rather than should prefer rehosting the owning source state or the real reader/setter family rather than
guessing one more derived leaf field from nearby offsets. A checked-in guessing one more derived leaf field from nearby offsets, and the checked-in
[`docs/rehost-queue.md`](docs/rehost-queue.md) file is now the control surface for that loop:
after each commit, check the queue and continue unless the queue is empty, a real blocker remains,
or approval is needed. A checked-in
`EventEffects` export now exists too in `EventEffects` export now exists too in
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now `artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered

View file

@ -14312,6 +14312,8 @@ mod tests {
world_issue_opinion_base_terms_raw_i32: Vec::new(), world_issue_opinion_base_terms_raw_i32: Vec::new(),
company_market_state: BTreeMap::new(), company_market_state: BTreeMap::new(),
company_periodic_side_latch_state: BTreeMap::new(), company_periodic_side_latch_state: BTreeMap::new(),
active_periodic_route_preference_override: None,
last_periodic_route_preference_override: None,
annual_finance_last_actions: BTreeMap::new(), annual_finance_last_actions: BTreeMap::new(),
annual_finance_action_counts: BTreeMap::new(), annual_finance_action_counts: BTreeMap::new(),
annual_dividend_adjustment_commit_count: 0, annual_dividend_adjustment_commit_count: 0,

View file

@ -70,11 +70,12 @@ pub use runtime::{
RuntimePlayerTarget, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, RuntimePlayerTarget, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric,
RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldFinanceNeighborhoodCandidate, RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldFinanceNeighborhoodCandidate,
RuntimeWorldIssueState, RuntimeWorldRestoreState, RuntimeWorldIssueState, RuntimeWorldRestoreState, RuntimeWorldRoutePreferenceOverrideState,
runtime_annual_bond_principal_flow_relation_label, runtime_annual_bond_principal_flow_relation_label,
runtime_annual_finance_news_family_candidate_label, runtime_company_annual_bond_policy_state, runtime_annual_finance_news_family_candidate_label,
runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state, runtime_begin_company_periodic_route_preference_override,
runtime_company_annual_dividend_policy_state, runtime_company_annual_bond_policy_state, runtime_company_annual_creditor_pressure_state,
runtime_company_annual_deep_distress_state, runtime_company_annual_dividend_policy_state,
runtime_company_annual_finance_policy_action_label, runtime_company_annual_finance_policy_action_label,
runtime_company_annual_finance_policy_state, runtime_company_annual_finance_state, runtime_company_annual_finance_policy_state, runtime_company_annual_finance_state,
runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state, runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state,
@ -84,12 +85,12 @@ pub use runtime::{
runtime_company_market_value, runtime_company_periodic_service_state, runtime_company_market_value, runtime_company_periodic_service_state,
runtime_company_prime_rate, runtime_company_recent_per_share_subscore, runtime_company_prime_rate, runtime_company_recent_per_share_subscore,
runtime_company_stat_value, runtime_company_stat_value_f64, runtime_company_stat_value, runtime_company_stat_value_f64,
runtime_company_unassigned_share_pool, runtime_world_annual_finance_mode_active, runtime_company_unassigned_share_pool, runtime_end_company_periodic_route_preference_override,
runtime_world_bankruptcy_allowed, runtime_world_bond_issue_and_repayment_allowed, runtime_world_annual_finance_mode_active, runtime_world_bankruptcy_allowed,
runtime_world_building_density_growth_setting, runtime_world_dividend_adjustment_allowed, runtime_world_bond_issue_and_repayment_allowed, runtime_world_building_density_growth_setting,
runtime_world_issue_opinion_multiplier, runtime_world_issue_opinion_term_sum_raw, runtime_world_dividend_adjustment_allowed, runtime_world_issue_opinion_multiplier,
runtime_world_issue_state, runtime_world_prime_rate_baseline, runtime_world_issue_opinion_term_sum_raw, runtime_world_issue_state,
runtime_world_stock_issue_and_buyback_allowed, runtime_world_prime_rate_baseline, runtime_world_stock_issue_and_buyback_allowed,
}; };
pub use smp::{ pub use smp::{
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane, SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,

View file

@ -209,6 +209,16 @@ pub struct RuntimeCompanyPeriodicServiceState {
pub effective_route_quality_multiplier_basis_points: i64, pub effective_route_quality_multiplier_basis_points: i64,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeWorldRoutePreferenceOverrideState {
pub company_id: u32,
#[serde(default)]
pub base_route_preference_raw_u8: Option<u8>,
#[serde(default)]
pub effective_route_preference_raw_u8: Option<u8>,
pub electric_route_preference_override_active: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeCompanyAnnualCreditorPressureState { pub struct RuntimeCompanyAnnualCreditorPressureState {
pub company_id: u32, pub company_id: u32,
@ -1272,6 +1282,10 @@ pub struct RuntimeServiceState {
#[serde(default)] #[serde(default)]
pub company_periodic_side_latch_state: BTreeMap<u32, RuntimeCompanyPeriodicSideLatchState>, pub company_periodic_side_latch_state: BTreeMap<u32, RuntimeCompanyPeriodicSideLatchState>,
#[serde(default)] #[serde(default)]
pub active_periodic_route_preference_override: Option<RuntimeWorldRoutePreferenceOverrideState>,
#[serde(default)]
pub last_periodic_route_preference_override: Option<RuntimeWorldRoutePreferenceOverrideState>,
#[serde(default)]
pub annual_finance_last_actions: BTreeMap<u32, RuntimeCompanyAnnualFinancePolicyAction>, pub annual_finance_last_actions: BTreeMap<u32, RuntimeCompanyAnnualFinancePolicyAction>,
#[serde(default)] #[serde(default)]
pub annual_finance_action_counts: BTreeMap<RuntimeCompanyAnnualFinancePolicyAction, u64>, pub annual_finance_action_counts: BTreeMap<RuntimeCompanyAnnualFinancePolicyAction, u64>,
@ -2252,6 +2266,23 @@ impl RuntimeState {
)); ));
} }
} }
if let Some(override_state) = &self.service_state.active_periodic_route_preference_override
{
if !seen_company_ids.contains(&override_state.company_id) {
return Err(format!(
"service_state.active_periodic_route_preference_override references unknown company_id {}",
override_state.company_id
));
}
}
if let Some(override_state) = &self.service_state.last_periodic_route_preference_override {
if !seen_company_ids.contains(&override_state.company_id) {
return Err(format!(
"service_state.last_periodic_route_preference_override references unknown company_id {}",
override_state.company_id
));
}
}
for company_id in self.service_state.annual_finance_last_actions.keys() { for company_id in self.service_state.annual_finance_last_actions.keys() {
if !seen_company_ids.contains(company_id) { if !seen_company_ids.contains(company_id) {
return Err(format!( return Err(format!(
@ -4683,6 +4714,41 @@ pub fn runtime_company_periodic_service_state(
}) })
} }
pub fn runtime_begin_company_periodic_route_preference_override(
state: &mut RuntimeState,
company_id: u32,
) -> Option<RuntimeWorldRoutePreferenceOverrideState> {
let periodic_service_state = runtime_company_periodic_service_state(state, company_id)?;
if !periodic_service_state.electric_route_preference_override_active {
return None;
}
let override_state = RuntimeWorldRoutePreferenceOverrideState {
company_id,
base_route_preference_raw_u8: periodic_service_state.base_route_preference_raw_u8,
effective_route_preference_raw_u8: periodic_service_state.effective_route_preference_raw_u8,
electric_route_preference_override_active: true,
};
state.world_restore.auto_show_grade_during_track_lay_raw_u8 =
override_state.effective_route_preference_raw_u8;
state
.service_state
.active_periodic_route_preference_override = Some(override_state.clone());
state.service_state.last_periodic_route_preference_override = Some(override_state.clone());
Some(override_state)
}
pub fn runtime_end_company_periodic_route_preference_override(
state: &mut RuntimeState,
) -> Option<RuntimeWorldRoutePreferenceOverrideState> {
let override_state = state
.service_state
.active_periodic_route_preference_override
.take()?;
state.world_restore.auto_show_grade_during_track_lay_raw_u8 =
override_state.base_route_preference_raw_u8;
Some(override_state)
}
pub fn runtime_company_market_value( pub fn runtime_company_market_value(
state: &RuntimeState, state: &RuntimeState,
company_id: u32, company_id: u32,
@ -9131,6 +9197,229 @@ mod tests {
); );
} }
#[test]
fn applies_and_restores_company_periodic_route_preference_override() {
let mut state = RuntimeState {
calendar: CalendarPoint {
year: 1845,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(1),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 4,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
}],
selected_company_id: Some(4),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: Vec::new(),
selected_chairman_profile_id: None,
trains: Vec::new(),
locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(),
packed_event_collection: None,
event_runtime_records: Vec::new(),
candidate_availability: BTreeMap::new(),
named_locomotive_availability: BTreeMap::new(),
named_locomotive_cost: BTreeMap::new(),
all_cargo_price_override: None,
named_cargo_price_overrides: BTreeMap::new(),
all_cargo_production_override: None,
factory_cargo_production_override: None,
farm_mine_cargo_production_override: None,
named_cargo_production_overrides: BTreeMap::new(),
cargo_production_overrides: BTreeMap::new(),
world_runtime_variables: BTreeMap::new(),
company_runtime_variables: BTreeMap::new(),
player_runtime_variables: BTreeMap::new(),
territory_runtime_variables: BTreeMap::new(),
world_scalar_overrides: BTreeMap::new(),
special_conditions: BTreeMap::new(),
service_state: RuntimeServiceState {
company_market_state: BTreeMap::from([(
4,
RuntimeCompanyMarketState {
city_connection_latch: true,
linked_transit_latch: false,
..RuntimeCompanyMarketState::default()
},
)]),
company_periodic_side_latch_state: BTreeMap::from([(
4,
RuntimeCompanyPeriodicSideLatchState {
preferred_locomotive_engine_type_raw_u8: Some(2),
city_connection_latch: true,
linked_transit_latch: false,
},
)]),
..RuntimeServiceState::default()
},
};
let applied = runtime_begin_company_periodic_route_preference_override(&mut state, 4)
.expect("electric override should apply");
assert_eq!(
applied,
RuntimeWorldRoutePreferenceOverrideState {
company_id: 4,
base_route_preference_raw_u8: Some(1),
effective_route_preference_raw_u8: Some(2),
electric_route_preference_override_active: true,
}
);
assert_eq!(
state.world_restore.auto_show_grade_during_track_lay_raw_u8,
Some(2)
);
assert_eq!(
state
.service_state
.active_periodic_route_preference_override,
Some(applied.clone())
);
assert_eq!(
state.service_state.last_periodic_route_preference_override,
Some(applied.clone())
);
let restored = runtime_end_company_periodic_route_preference_override(&mut state)
.expect("override should restore");
assert_eq!(restored, applied);
assert_eq!(
state.world_restore.auto_show_grade_during_track_lay_raw_u8,
Some(1)
);
assert_eq!(
state
.service_state
.active_periodic_route_preference_override,
None
);
assert_eq!(
state.service_state.last_periodic_route_preference_override,
Some(restored)
);
}
#[test]
fn skips_company_periodic_route_preference_override_without_electric_preference() {
let mut state = RuntimeState {
calendar: CalendarPoint {
year: 1845,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(3),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 8,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
}],
selected_company_id: Some(8),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: Vec::new(),
selected_chairman_profile_id: None,
trains: Vec::new(),
locomotive_catalog: Vec::new(),
cargo_catalog: Vec::new(),
territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(),
packed_event_collection: None,
event_runtime_records: Vec::new(),
candidate_availability: BTreeMap::new(),
named_locomotive_availability: BTreeMap::new(),
named_locomotive_cost: BTreeMap::new(),
all_cargo_price_override: None,
named_cargo_price_overrides: BTreeMap::new(),
all_cargo_production_override: None,
factory_cargo_production_override: None,
farm_mine_cargo_production_override: None,
named_cargo_production_overrides: BTreeMap::new(),
cargo_production_overrides: BTreeMap::new(),
world_runtime_variables: BTreeMap::new(),
company_runtime_variables: BTreeMap::new(),
player_runtime_variables: BTreeMap::new(),
territory_runtime_variables: BTreeMap::new(),
world_scalar_overrides: BTreeMap::new(),
special_conditions: BTreeMap::new(),
service_state: RuntimeServiceState {
company_market_state: BTreeMap::from([(
8,
RuntimeCompanyMarketState {
city_connection_latch: true,
linked_transit_latch: false,
..RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
assert_eq!(
runtime_begin_company_periodic_route_preference_override(&mut state, 8),
None
);
assert_eq!(
state.world_restore.auto_show_grade_during_track_lay_raw_u8,
Some(3)
);
assert_eq!(
state
.service_state
.active_periodic_route_preference_override,
None
);
assert_eq!(
state.service_state.last_periodic_route_preference_override,
None
);
}
#[test] #[test]
fn derives_annual_creditor_pressure_from_rehosted_finance_owner_state() { fn derives_annual_creditor_pressure_from_rehosted_finance_owner_state() {
let mut year_stat_family_qword_bits = vec![ let mut year_stat_family_qword_bits = vec![

View file

@ -132,6 +132,10 @@ pub struct RuntimeSummary {
pub selected_company_periodic_service_effective_route_preference_raw_u8: Option<u8>, pub selected_company_periodic_service_effective_route_preference_raw_u8: Option<u8>,
pub selected_company_periodic_service_electric_route_preference_override_active: Option<bool>, pub selected_company_periodic_service_electric_route_preference_override_active: Option<bool>,
pub selected_company_periodic_service_route_quality_multiplier_basis_points: Option<i64>, pub selected_company_periodic_service_route_quality_multiplier_basis_points: Option<i64>,
pub active_periodic_route_preference_override_company_id: Option<u32>,
pub active_periodic_route_preference_override_effective_raw_u8: Option<u8>,
pub last_periodic_route_preference_override_company_id: Option<u32>,
pub last_periodic_route_preference_override_effective_raw_u8: Option<u8>,
pub selected_company_chairman_bonus_year: Option<u32>, pub selected_company_chairman_bonus_year: Option<u32>,
pub selected_company_chairman_bonus_amount: Option<i32>, pub selected_company_chairman_bonus_amount: Option<i32>,
pub selected_company_creditor_pressure_recent_bad_net_profit_year_count: Option<u32>, pub selected_company_creditor_pressure_recent_bad_net_profit_year_count: Option<u32>,
@ -672,6 +676,26 @@ impl RuntimeSummary {
.map(|service_state| { .map(|service_state| {
service_state.effective_route_quality_multiplier_basis_points service_state.effective_route_quality_multiplier_basis_points
}), }),
active_periodic_route_preference_override_company_id: state
.service_state
.active_periodic_route_preference_override
.as_ref()
.map(|override_state| override_state.company_id),
active_periodic_route_preference_override_effective_raw_u8: state
.service_state
.active_periodic_route_preference_override
.as_ref()
.and_then(|override_state| override_state.effective_route_preference_raw_u8),
last_periodic_route_preference_override_company_id: state
.service_state
.last_periodic_route_preference_override
.as_ref()
.map(|override_state| override_state.company_id),
last_periodic_route_preference_override_effective_raw_u8: state
.service_state
.last_periodic_route_preference_override
.as_ref()
.and_then(|override_state| override_state.effective_route_preference_raw_u8),
selected_company_chairman_bonus_year: selected_company_market_state selected_company_chairman_bonus_year: selected_company_market_state
.map(|market_state| market_state.chairman_bonus_year) .map(|market_state| market_state.chairman_bonus_year)
.filter(|year| *year != 0), .filter(|year| *year != 0),

View file

@ -187,9 +187,16 @@ The highest-value next passes are now:
- that same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the - that same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the
effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x` effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x`
route-quality multiplier as a normal runtime reader instead of a pure atlas note route-quality multiplier as a normal runtime reader instead of a pure atlas note
- that same seam now also owns the first route-preference mutation path directly: beginning the
electric-only periodic-company override rewrites the world route-preference byte to the
effective company preference, ending it restores the base world byte, and runtime service state
now carries both the active and last applied override
- the project rule on the remaining closure work is now explicit too: when one runtime-facing field - the project rule on the remaining closure work is now explicit too: when one runtime-facing field
is still ambiguous, prefer rehosting the owning source state or real reader/setter family first is still ambiguous, prefer rehosting the owning source state or real reader/setter family first
instead of guessing another derived leaf field from neighboring raw offsets instead of guessing another derived leaf field from neighboring raw offsets; the checked-in
`docs/rehost-queue.md` file is the control surface for that work loop, and after each commit the
next queue item should run unless the queue is empty, a real blocker remains, or approval is
needed
- a checked-in `EventEffects` export now exists at - a checked-in `EventEffects` export now exists at
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer `artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json` now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`

View file

@ -12,10 +12,10 @@ Working rule:
- Rehost the next live branch inside - Rehost the next live branch inside
`company_service_periodic_city_connection_finance_and_linked_transit_lanes`, especially the `company_service_periodic_city_connection_finance_and_linked_transit_lanes`, especially the
city-connection announcement / linked-transit roster-maintenance side that now sits on top of city-connection announcement / linked-transit roster-maintenance side that now sits on top of
the owned periodic-service seam instead of loose atlas notes. the owned periodic-service seam and the new route-preference apply/restore mutation seam instead
- Keep widening the temporary world route-preference owner around `[world+0x4c74]` from a pure of loose atlas notes.
reader seam into a real service mutation seam when the linked-transit route search / balancing - Extend shellless clock advancement so more periodic-company service branches consume owned
branch is grounded strongly enough. runtime time state directly instead of only the explicit periodic service command.
- Keep widening selected-year world-owner state only when a full owning reader/rebuild family is - Keep widening selected-year world-owner state only when a full owning reader/rebuild family is
grounded strongly enough to avoid one-off leaf guesses. grounded strongly enough to avoid one-off leaf guesses.
@ -71,6 +71,11 @@ Working rule:
route-preference byte, the effective electric-only override fed by `0x0d17`, and the matching route-preference byte, the effective electric-only override fed by `0x0d17`, and the matching
`1.4x` versus `1.8x` route-quality multiplier through owned periodic-service state instead of `1.4x` versus `1.8x` route-quality multiplier through owned periodic-service state instead of
leaving that bridge in atlas notes. leaving that bridge in atlas notes.
- That same periodic-company seam now also owns a first-class route-preference apply/restore
mutation lane: runtime service state tracks the active and last electric override, beginning the
override rewrites `[world+0x4c74]` to the effective route preference for the selected company
service pass, and ending the override restores the base world byte instead of leaving the seam as
a pure reader bridge.
- Company cash, confiscation, and major governance effects now write through owner state instead of - Company cash, confiscation, and major governance effects now write through owner state instead of
drifting from market/cache readers. drifting from market/cache readers.
- Company credit rating, prime rate, book value per share, investor confidence, and management - Company credit rating, prime rate, book value per share, investor confidence, and management

View file

@ -264,6 +264,11 @@ engine-type chooser byte beside the city-connection and linked-transit finance g
That same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the That same seam now also resolves the base world route-preference byte at `[world+0x4c74]`, the
effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x` effective electric-only override fed by `0x0d17`, and the matching `1.4x` versus `1.8x`
route-quality multiplier as a first-class runtime reader rather than a loose atlas-only bridge. route-quality multiplier as a first-class runtime reader rather than a loose atlas-only bridge.
That same seam now also owns the first route-preference mutation lane directly: beginning the
electric-only periodic-company override rewrites `[world+0x4c74]` to the effective company
preference for the active service pass, ending the override restores the base world byte, and
runtime service state now carries both the active and last applied override instead of leaving the
route-preference seam as a pure reader note.
That same seam now also carries the fixed-world building-density growth setting plus the linked That same seam now also carries the fixed-world building-density growth setting plus the linked
chairman personality byte, which is enough to rehost the annual stock-repurchase gate on owned chairman personality byte, which is enough to rehost the annual stock-repurchase gate on owned
save/runtime state instead of another threshold-only note. The stock-capital issue branch now save/runtime state instead of another threshold-only note. The stock-capital issue branch now
@ -282,6 +287,10 @@ year and halve live bond principals in place instead of collapsing into a liquid
The same owned live bond-slot surface now also carries maturity years through save import, The same owned live bond-slot surface now also carries maturity years through save import,
runtime state, and annual bond summaries, which is the right next base for shellless repayment and runtime state, and annual bond summaries, which is the right next base for shellless repayment and
bond-service simulation. bond-service simulation.
The process rule for the remaining runtime work is explicit too: prefer rehosting owning state and
real reader/setter families over guessing leaf fields, and use `docs/rehost-queue.md` as the
checked-in control surface for the work loop. After each commit, check that queue and continue
unless the queue is empty, a real blocker remains, or approval is needed.
That same owner seam now also derives live coupon burden totals directly from saved bond slots, That same owner seam now also derives live coupon burden totals directly from saved bond slots,
which gives later finance service work a bounded runtime reader instead of another synthetic which gives later finance service work a bounded runtime reader instead of another synthetic
finance leaf. finance leaf.