Scan numbered candidate table run families
This commit is contained in:
parent
87a5667c9e
commit
dd973ad44b
3 changed files with 264 additions and 1 deletions
|
|
@ -246,6 +246,9 @@ enum Command {
|
||||||
RuntimeScanCandidateTableHeaders {
|
RuntimeScanCandidateTableHeaders {
|
||||||
root_path: PathBuf,
|
root_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
RuntimeScanCandidateTableNamedRuns {
|
||||||
|
root_path: PathBuf,
|
||||||
|
},
|
||||||
RuntimeScanSpecialConditions {
|
RuntimeScanSpecialConditions {
|
||||||
root_path: PathBuf,
|
root_path: PathBuf,
|
||||||
},
|
},
|
||||||
|
|
@ -857,6 +860,41 @@ struct RuntimeCandidateTableHeaderScanSample {
|
||||||
zero_trailer_entry_names: Vec<String>,
|
zero_trailer_entry_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
struct RuntimeCandidateTableNamedRun {
|
||||||
|
prefix: String,
|
||||||
|
start_index: usize,
|
||||||
|
end_index: usize,
|
||||||
|
count: usize,
|
||||||
|
first_name: String,
|
||||||
|
last_name: String,
|
||||||
|
start_offset: usize,
|
||||||
|
end_offset: usize,
|
||||||
|
distinct_trailer_hex_words: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
struct RuntimeCandidateTableNamedRunScanSample {
|
||||||
|
path: String,
|
||||||
|
profile_family: String,
|
||||||
|
source_kind: String,
|
||||||
|
observed_entry_count: usize,
|
||||||
|
port_runs: Vec<RuntimeCandidateTableNamedRun>,
|
||||||
|
warehouse_runs: Vec<RuntimeCandidateTableNamedRun>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct RuntimeCandidateTableNamedRunScanReport {
|
||||||
|
root_path: String,
|
||||||
|
file_count: usize,
|
||||||
|
files_with_probe_count: usize,
|
||||||
|
files_with_any_numbered_port_runs_count: usize,
|
||||||
|
files_with_any_numbered_warehouse_runs_count: usize,
|
||||||
|
files_with_both_numbered_run_families_count: usize,
|
||||||
|
skipped_file_count: usize,
|
||||||
|
samples: Vec<RuntimeCandidateTableNamedRunScanSample>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct RuntimeSpecialConditionsScanSample {
|
struct RuntimeSpecialConditionsScanSample {
|
||||||
path: String,
|
path: String,
|
||||||
|
|
@ -1220,6 +1258,9 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Command::RuntimeScanCandidateTableHeaders { root_path } => {
|
Command::RuntimeScanCandidateTableHeaders { root_path } => {
|
||||||
run_runtime_scan_candidate_table_headers(&root_path)?;
|
run_runtime_scan_candidate_table_headers(&root_path)?;
|
||||||
}
|
}
|
||||||
|
Command::RuntimeScanCandidateTableNamedRuns { root_path } => {
|
||||||
|
run_runtime_scan_candidate_table_named_runs(&root_path)?;
|
||||||
|
}
|
||||||
Command::RuntimeScanSpecialConditions { root_path } => {
|
Command::RuntimeScanSpecialConditions { root_path } => {
|
||||||
run_runtime_scan_special_conditions(&root_path)?;
|
run_runtime_scan_special_conditions(&root_path)?;
|
||||||
}
|
}
|
||||||
|
|
@ -1603,6 +1644,13 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
root_path: PathBuf::from(root_path),
|
root_path: PathBuf::from(root_path),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
[command, subcommand, root_path]
|
||||||
|
if command == "runtime" && subcommand == "scan-candidate-table-named-runs" =>
|
||||||
|
{
|
||||||
|
Ok(Command::RuntimeScanCandidateTableNamedRuns {
|
||||||
|
root_path: PathBuf::from(root_path),
|
||||||
|
})
|
||||||
|
}
|
||||||
[command, subcommand, root_path]
|
[command, subcommand, root_path]
|
||||||
if command == "runtime" && subcommand == "scan-special-conditions" =>
|
if command == "runtime" && subcommand == "scan-special-conditions" =>
|
||||||
{
|
{
|
||||||
|
|
@ -1647,7 +1695,7 @@ fn parse_command() -> Result<Command, Box<dyn std::error::Error>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(
|
_ => Err(
|
||||||
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime inspect-candidate-table <file.smp> | runtime inspect-compact-event-dispatch-cluster <maps-dir> | runtime inspect-compact-event-dispatch-cluster-counts <maps-dir> | runtime inspect-map-title-hints <maps-dir> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-save-placed-structure-triplets <file.smp> | runtime compare-region-fixed-row-runs <left.gms> <right.gms> | runtime inspect-periodic-company-service-trace <file.smp> | runtime inspect-region-service-trace <file.smp> | runtime inspect-infrastructure-asset-trace <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-building-type-sources <BuildingTypes-dir> [building-bindings.json] | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
"usage: rrt-cli [validate [repo-root] | finance eval <snapshot.json> | finance diff <left.json> <right.json> | runtime validate-fixture <fixture.json> | runtime summarize-fixture <fixture.json> | runtime export-fixture-state <fixture.json> <snapshot.json> | runtime diff-state <left.json> <right.json> | runtime summarize-state <snapshot.json> | runtime import-state <input.json> <snapshot.json> | runtime inspect-smp <file.smp> | runtime inspect-candidate-table <file.smp> | runtime inspect-compact-event-dispatch-cluster <maps-dir> | runtime inspect-compact-event-dispatch-cluster-counts <maps-dir> | runtime inspect-map-title-hints <maps-dir> | runtime summarize-save-load <file.smp> | runtime load-save-slice <file.smp> | runtime inspect-save-company-chairman <file.smp> | runtime inspect-save-placed-structure-triplets <file.smp> | runtime compare-region-fixed-row-runs <left.gms> <right.gms> | runtime inspect-periodic-company-service-trace <file.smp> | runtime inspect-region-service-trace <file.smp> | runtime inspect-infrastructure-asset-trace <file.smp> | runtime inspect-save-region-queued-notice-records <file.smp> | runtime inspect-placed-structure-dynamic-side-buffer <file.smp> | runtime inspect-unclassified-save-collections <file.smp> | runtime import-save-state <file.smp> <snapshot.json> | runtime export-save-slice <file.smp> <save-slice.json> | runtime export-overlay-import <snapshot.json> <save-slice.json> <overlay-import.json> | runtime inspect-pk4 <file.pk4> | runtime inspect-cargo-types <CargoTypes-dir> | runtime inspect-building-type-sources <BuildingTypes-dir> [building-bindings.json] | runtime inspect-cargo-skins <Cargo106.PK4> | runtime inspect-cargo-economy-sources <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-production-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-cargo-price-selector <CargoTypes-dir> <Cargo106.PK4> | runtime inspect-win <file.win> | runtime extract-pk4-entry <file.pk4> <entry-name> <output-path> | runtime inspect-campaign-exe <RT3.exe> | runtime compare-classic-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-105-profile <save1.gms> <save2.gms> [saveN.gms...] | runtime compare-candidate-table <file1> <file2> [fileN...] | runtime compare-recipe-book-lines <file1> <file2> [fileN...] | runtime compare-setup-payload-core <file1> <file2> [fileN...] | runtime compare-setup-launch-payload <file1> <file2> [fileN...] | runtime compare-post-special-conditions-scalars <file1> <file2> [fileN...] | runtime scan-candidate-table-headers <root-dir> | runtime scan-candidate-table-named-runs <root-dir> | runtime scan-special-conditions <root-dir> | runtime scan-aligned-runtime-rule-band <root-dir> | runtime scan-post-special-conditions-scalars <root-dir> | runtime scan-post-special-conditions-tail <root-dir> | runtime scan-recipe-book-lines <root-dir> | runtime export-profile-block <save.gms> <profile.json>]"
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
@ -2938,6 +2986,50 @@ fn run_runtime_scan_candidate_table_headers(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_runtime_scan_candidate_table_named_runs(
|
||||||
|
root_path: &Path,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut candidate_paths = Vec::new();
|
||||||
|
collect_candidate_table_input_paths(root_path, &mut candidate_paths)?;
|
||||||
|
|
||||||
|
let file_count = candidate_paths.len();
|
||||||
|
let mut samples = Vec::new();
|
||||||
|
let mut skipped_file_count = 0usize;
|
||||||
|
for path in candidate_paths {
|
||||||
|
match load_candidate_table_named_run_scan_sample(&path) {
|
||||||
|
Ok(sample) => samples.push(sample),
|
||||||
|
Err(_) => skipped_file_count += 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let files_with_probe_count = samples.len();
|
||||||
|
let files_with_any_numbered_port_runs_count = samples
|
||||||
|
.iter()
|
||||||
|
.filter(|sample| !sample.port_runs.is_empty())
|
||||||
|
.count();
|
||||||
|
let files_with_any_numbered_warehouse_runs_count = samples
|
||||||
|
.iter()
|
||||||
|
.filter(|sample| !sample.warehouse_runs.is_empty())
|
||||||
|
.count();
|
||||||
|
let files_with_both_numbered_run_families_count = samples
|
||||||
|
.iter()
|
||||||
|
.filter(|sample| !sample.port_runs.is_empty() && !sample.warehouse_runs.is_empty())
|
||||||
|
.count();
|
||||||
|
|
||||||
|
let report = RuntimeCandidateTableNamedRunScanReport {
|
||||||
|
root_path: root_path.display().to_string(),
|
||||||
|
file_count,
|
||||||
|
files_with_probe_count,
|
||||||
|
files_with_any_numbered_port_runs_count,
|
||||||
|
files_with_any_numbered_warehouse_runs_count,
|
||||||
|
files_with_both_numbered_run_families_count,
|
||||||
|
skipped_file_count,
|
||||||
|
samples,
|
||||||
|
};
|
||||||
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn run_runtime_scan_special_conditions(root_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
fn run_runtime_scan_special_conditions(root_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut candidate_paths = Vec::new();
|
let mut candidate_paths = Vec::new();
|
||||||
collect_special_conditions_input_paths(root_path, &mut candidate_paths)?;
|
collect_special_conditions_input_paths(root_path, &mut candidate_paths)?;
|
||||||
|
|
@ -4152,6 +4244,23 @@ fn load_candidate_table_header_scan_sample(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_candidate_table_named_run_scan_sample(
|
||||||
|
smp_path: &Path,
|
||||||
|
) -> Result<RuntimeCandidateTableNamedRunScanSample, Box<dyn std::error::Error>> {
|
||||||
|
let report = load_candidate_table_inspection_report(smp_path)?;
|
||||||
|
let port_runs = collect_numbered_candidate_name_runs(&report.entries, "Port");
|
||||||
|
let warehouse_runs = collect_numbered_candidate_name_runs(&report.entries, "Warehouse");
|
||||||
|
|
||||||
|
Ok(RuntimeCandidateTableNamedRunScanSample {
|
||||||
|
path: report.path,
|
||||||
|
profile_family: report.profile_family,
|
||||||
|
source_kind: report.source_kind,
|
||||||
|
observed_entry_count: report.observed_entry_count,
|
||||||
|
port_runs,
|
||||||
|
warehouse_runs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn load_special_conditions_scan_sample(
|
fn load_special_conditions_scan_sample(
|
||||||
smp_path: &Path,
|
smp_path: &Path,
|
||||||
) -> Result<RuntimeSpecialConditionsScanSample, Box<dyn std::error::Error>> {
|
) -> Result<RuntimeSpecialConditionsScanSample, Box<dyn std::error::Error>> {
|
||||||
|
|
@ -4495,6 +4604,61 @@ fn collect_candidate_table_input_paths(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_numbered_candidate_name_runs(
|
||||||
|
entries: &[RuntimeCandidateTableEntrySample],
|
||||||
|
prefix: &str,
|
||||||
|
) -> Vec<RuntimeCandidateTableNamedRun> {
|
||||||
|
let mut numbered_entries = entries
|
||||||
|
.iter()
|
||||||
|
.filter_map(|entry| {
|
||||||
|
parse_numbered_candidate_name(&entry.text, prefix).map(|number| (entry, number))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
numbered_entries.sort_by_key(|(entry, number)| (entry.index, *number));
|
||||||
|
|
||||||
|
let mut runs = Vec::new();
|
||||||
|
let mut cursor = 0usize;
|
||||||
|
while cursor < numbered_entries.len() {
|
||||||
|
let (first_entry, first_number) = numbered_entries[cursor];
|
||||||
|
let mut last_entry = first_entry;
|
||||||
|
let mut last_number = first_number;
|
||||||
|
let mut distinct_trailer_hex_words = BTreeSet::from([first_entry.trailer_word_hex.clone()]);
|
||||||
|
let mut next = cursor + 1;
|
||||||
|
while next < numbered_entries.len() {
|
||||||
|
let (entry, number) = numbered_entries[next];
|
||||||
|
if entry.index != last_entry.index + 1 || number != last_number + 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
distinct_trailer_hex_words.insert(entry.trailer_word_hex.clone());
|
||||||
|
last_entry = entry;
|
||||||
|
last_number = number;
|
||||||
|
next += 1;
|
||||||
|
}
|
||||||
|
runs.push(RuntimeCandidateTableNamedRun {
|
||||||
|
prefix: prefix.to_string(),
|
||||||
|
start_index: first_entry.index,
|
||||||
|
end_index: last_entry.index,
|
||||||
|
count: next - cursor,
|
||||||
|
first_name: first_entry.text.clone(),
|
||||||
|
last_name: last_entry.text.clone(),
|
||||||
|
start_offset: first_entry.offset,
|
||||||
|
end_offset: last_entry.offset,
|
||||||
|
distinct_trailer_hex_words: distinct_trailer_hex_words.into_iter().collect(),
|
||||||
|
});
|
||||||
|
cursor = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
runs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_numbered_candidate_name(text: &str, prefix: &str) -> Option<usize> {
|
||||||
|
let digits = text.strip_prefix(prefix)?;
|
||||||
|
if digits.is_empty() || !digits.bytes().all(|byte| byte.is_ascii_digit()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
digits.parse().ok()
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_special_conditions_input_paths(
|
fn collect_special_conditions_input_paths(
|
||||||
root_path: &Path,
|
root_path: &Path,
|
||||||
out: &mut Vec<PathBuf>,
|
out: &mut Vec<PathBuf>,
|
||||||
|
|
@ -6551,6 +6715,83 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn collects_numbered_candidate_name_runs_by_prefix() {
|
||||||
|
let entries = vec![
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 35,
|
||||||
|
offset: 28535,
|
||||||
|
text: "Port00".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 43,
|
||||||
|
offset: 28807,
|
||||||
|
text: "Warehouse00".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 45,
|
||||||
|
offset: 28875,
|
||||||
|
text: "Port01".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 46,
|
||||||
|
offset: 28909,
|
||||||
|
text: "Port02".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 56,
|
||||||
|
offset: 29249,
|
||||||
|
text: "Warehouse01".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
RuntimeCandidateTableEntrySample {
|
||||||
|
index: 57,
|
||||||
|
offset: 29283,
|
||||||
|
text: "Warehouse02".to_string(),
|
||||||
|
availability_dword: 1,
|
||||||
|
availability_dword_hex: "0x00000001".to_string(),
|
||||||
|
trailer_word: 1,
|
||||||
|
trailer_word_hex: "0x00000001".to_string(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let port_runs = collect_numbered_candidate_name_runs(&entries, "Port");
|
||||||
|
let warehouse_runs = collect_numbered_candidate_name_runs(&entries, "Warehouse");
|
||||||
|
|
||||||
|
assert_eq!(port_runs.len(), 2);
|
||||||
|
assert_eq!(port_runs[0].first_name, "Port00");
|
||||||
|
assert_eq!(port_runs[0].count, 1);
|
||||||
|
assert_eq!(port_runs[1].first_name, "Port01");
|
||||||
|
assert_eq!(port_runs[1].last_name, "Port02");
|
||||||
|
assert_eq!(port_runs[1].count, 2);
|
||||||
|
|
||||||
|
assert_eq!(warehouse_runs.len(), 2);
|
||||||
|
assert_eq!(warehouse_runs[0].first_name, "Warehouse00");
|
||||||
|
assert_eq!(warehouse_runs[0].count, 1);
|
||||||
|
assert_eq!(warehouse_runs[1].first_name, "Warehouse01");
|
||||||
|
assert_eq!(warehouse_runs[1].last_name, "Warehouse02");
|
||||||
|
assert_eq!(warehouse_runs[1].count, 2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn diffs_recipe_book_line_samples_across_multiple_files() {
|
fn diffs_recipe_book_line_samples_across_multiple_files() {
|
||||||
let sample_a = RuntimeRecipeBookLineSample {
|
let sample_a = RuntimeRecipeBookLineSample {
|
||||||
|
|
|
||||||
|
|
@ -1244,6 +1244,17 @@
|
||||||
problem is no longer whether those names exist as stable scenario rows; it is how that fixed
|
problem is no longer whether those names exist as stable scenario rows; it is how that fixed
|
||||||
candidate-table cluster is projected into the later aux-record bank and then into the live clone
|
candidate-table cluster is projected into the later aux-record bank and then into the live clone
|
||||||
families.
|
families.
|
||||||
|
The root scan narrows the real corpus for that question too. `runtime scan-candidate-table-headers
|
||||||
|
rt3_wineprefix/drive_c/rt3/maps` shows `37` probe-bearing shipped maps and `4` skips, while the
|
||||||
|
narrower `runtime scan-candidate-table-named-runs` command confirms that `Louisiana.gmp` and
|
||||||
|
`Dutchlantis.gmp` share the same split shape:
|
||||||
|
isolated `Port00` at row `35`, contiguous `Port01..11` at rows `45..55`, isolated
|
||||||
|
`Warehouse00` at row `43`, and contiguous `Warehouse01..11` at rows `56..66`. Raw string
|
||||||
|
presence is broader than that actual fixed-candidate-table seam too: `Port00` appears in all
|
||||||
|
`41` shipped `.gmp` files, but `Central Pacific.gmp`, `Italy.gmp`, `Tex-Mex.gmp`, and
|
||||||
|
`Texas Tea.gmp` do not expose the fixed candidate-table header at all. So the next Tier-2
|
||||||
|
source pass should target the `37` probe-bearing maps rather than the noisier full
|
||||||
|
string-bearing map corpus.
|
||||||
The direct `+0xba/+0xbb` writer census now rules out a broad false lead too. The obvious new
|
The direct `+0xba/+0xbb` writer census now rules out a broad false lead too. The obvious new
|
||||||
stores at `0x004ecd42/0x004ecdaa` and `0x004ed5d5/0x004ed625` are only shell-side
|
stores at `0x004ecd42/0x004ecdaa` and `0x004ed5d5/0x004ed625` are only shell-side
|
||||||
portrait/string refresh helpers over a different id-keyed collection rooted through
|
portrait/string refresh helpers over a different id-keyed collection rooted through
|
||||||
|
|
|
||||||
|
|
@ -755,6 +755,17 @@ Working rule:
|
||||||
is no longer whether those names exist as stable scenario rows; it is how that stable
|
is no longer whether those names exist as stable scenario rows; it is how that stable
|
||||||
candidate-table cluster is projected into the later aux-record bank and then into the live
|
candidate-table cluster is projected into the later aux-record bank and then into the live
|
||||||
clone families.
|
clone families.
|
||||||
|
The new root scan sharpens that boundary further. `runtime scan-candidate-table-headers
|
||||||
|
rt3_wineprefix/drive_c/rt3/maps` shows `37` probe-bearing shipped maps and `4` skips, while
|
||||||
|
the narrower `runtime scan-candidate-table-named-runs` command confirms that
|
||||||
|
`Louisiana.gmp` and `Dutchlantis.gmp` share the same split shape:
|
||||||
|
`Port00` as an isolated run at row `35`, `Port01..11` as one contiguous run at rows `45..55`,
|
||||||
|
`Warehouse00` isolated at row `43`, and `Warehouse01..11` contiguous at rows `56..66`.
|
||||||
|
Raw map-string presence is broader than that actual candidate-table seam too:
|
||||||
|
`Port00` appears in all `41` shipped `.gmp` files, but `Central Pacific.gmp`, `Italy.gmp`,
|
||||||
|
`Tex-Mex.gmp`, and `Texas Tea.gmp` do not expose the fixed candidate-table header at all. So
|
||||||
|
the next Tier-2 source pass should target the `37` probe-bearing maps rather than the noisier
|
||||||
|
full string-bearing map corpus.
|
||||||
The direct `+0xba/+0xbb` writer census is narrower now too. The obvious newly surfaced stores
|
The direct `+0xba/+0xbb` writer census is narrower now too. The obvious newly surfaced stores
|
||||||
at `0x004ecd42/0x004ecdaa` and `0x004ed5d5/0x004ed625` are only shell-side portrait/string
|
at `0x004ecd42/0x004ecdaa` and `0x004ed5d5/0x004ed625` are only shell-side portrait/string
|
||||||
refresh helpers: they walk a separate id-keyed collection through `0x0053f830`, free and
|
refresh helpers: they walk a separate id-keyed collection through `0x0053f830`, free and
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue