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

  1. Replace `.expect` with `if let Ok(val) = s.parse::<f32>()` and skip/log malformed entries instead of crashing.
  2. Validate or sanitize the stats file format before parsing — e.g., `s.chars().all(|c| c.is_numeric() || c == '.' || c == '-')`.
  3. Back up and reset the stats file when corruption is detected, logging the issue.
  4. 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

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


AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13). Data as JSON: /api/errors/6b428ce2147603f1. Report an issue: GitHub.