coding-horror/basic-computer-games · error
Corrupt stats file!
Error message
Corrupt stats file!
What it means
This panic is triggered by `.expect("Corrupt stats file!")` on `s.parse::<f32>()` inside `Stats::new()` in Splat's stats module (line 32). It fires when a comma-separated value in `src/stats.txt` cannot be parsed as an `f32`. The preceding `is_empty()` check filters empty strings (e.g., trailing commas), but any non-numeric token like `"abc"`, `"1.2.3"`, or `"NaN_x"` will panic.
Source
Thrown at 81_Splat/rust/src/stats.rs:32
if utility::prompt_bool("WOULD YOU LIKE TO LOAD PREVIOUS GAME DATA?", false) {
let path = "src/stats.txt";
let mut altitudes = Vec::new();
if let Ok(stats) = fs::read_to_string(path) {
if stats.is_empty() {
return Some(Stats {
altitudes: Vec::new(),
});
}
let stats: Vec<&str> = stats.trim().split(",").collect();
for s in stats {
if s.is_empty() {
continue;
}
let s = s.parse::<f32>().expect("Corrupt stats file!");
altitudes.push(s);
}
return Some(Stats { altitudes });
} else {
println!("PREVIOUS GAME DATA NOT FOUND!");
if !utility::prompt_bool("WOULD YOU LIKE TO CREATE ONE?", false) {
return None;
} else {
let mut file = File::create(path).expect("Invalid file path!");
file.write_all("".as_bytes())
.expect("Could not create file!");
return Some(Stats {
altitudes: Vec::new(),
});
}View on GitHub (pinned to 5301155192)
Solutions
- Replace `.expect` with `if let Ok(val) = s.parse::<f32>()` and skip/log malformed entries instead of crashing.
- Validate or sanitize the stats file format before parsing — e.g., `s.chars().all(|c| c.is_numeric() || c == '.' || c == '-')`.
- Back up and reset the stats file when corruption is detected, logging the issue.
- Use a more robust serialization format (e.g., serde JSON) to avoid CSV parsing fragility.
Example fix
// before
let s = s.parse::<f32>().expect("Corrupt stats file!");
altitudes.push(s);
// after
match s.parse::<f32>() {
Ok(val) => altitudes.push(val),
Err(_) => {
eprintln!("Warning: skipping invalid stat value '{}'", s);
continue;
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the stats file content before parsing
fn is_valid_stat(s: &str) -> bool {
!s.is_empty() && s.parse::<f32>().is_ok()
}
// Before loading:
let raw = fs::read_to_string("src/stats.txt").unwrap_or_default();
let all_valid = raw.trim().split(',').all(|s| s.is_empty() || is_valid_stat(s));
if !all_valid {
eprintln!("Stats file is corrupt. Resetting.");
// back up and recreate
} Type guard
fn parse_stat(s: &str) -> Option<f32> {
s.trim().parse::<f32>().ok().filter(|v| v.is_finite())
} Try / catch
for s in stats {
if s.is_empty() { continue; }
match s.parse::<f32>() {
Ok(val) => altitudes.push(val),
Err(_) => eprintln!("Skipping invalid stat: '{}'", s),
}
} Prevention
- Validate each CSV field with parse::<f32>().is_ok() before using .expect or unwrap.
- Back up and reset corrupt stats files instead of crashing.
- Consider serde/JSON for stats persistence to avoid CSV parsing fragility.
- Filter out non-finite values (NaN, Infinity) if they are not meaningful game data.
When it happens
Trigger: The stats file contains a malformed altitude value. This can happen if the file was hand-edited, corrupted by a partial write, or written by a different version of the program using a different format. Values like `inf`, `nan` are actually valid for `f32::parse` but locale-specific decimal separators (comma vs period) are not.
Common situations: Manual editing of `src/stats.txt` introducing non-numeric text. A crash during a previous `write()` leaving a truncated or partial CSV. Locale confusion where the system writes `1,5` (European decimal comma) which then splits into `"1"` and `"5"` — though in this case each piece parses fine, creating phantom extra entries. File from a different game version with a different schema.
Related errors
- Could not create file!
- Error loading stats data!
- ERROR WRITING Stats FILE!
- Invalid file path!
- Failed read_line
AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13).
Data as JSON: /api/errors/6b428ce2147603f1.
Report an issue: GitHub.