FyroxEngine/Fyrox · error

Height data type error

Error message

Height data type error: {:?}

What it means

The Index impl for ChunkHeightMutData reads height values as f32 via Texture::data_of_type::<f32>(). When the heightmap texture's pixel data is not stored as f32 (wrong TexturePixelKind), data_of_type returns None and the code panics with "Height data type error" including the texture debug output. Terrain heightmaps must internally be f32 pixel data.

Solutions

  1. Create the heightmap texture via make_height_map_texture / the terrain API so pixel data is f32 (correct TexturePixelKind).
  2. If importing an image, convert its pixels to f32 first (e.g. normalize u8 to 0.0..1.0) and build the texture with an f32 pixel kind.
  3. Check texture.data_ref().data_of_type::<f32>().is_some() before indexing and regenerate the heightmap if None.
  4. Keep using the public height-map editing APIs which guarantee the f32 representation.

Example fix

// before
let img = image::open("height.png").unwrap();
let tex = Texture::from_pixels(w, h, TexturePixelKind::RGBA8, img.into_raw());
chunk.set_height_map(tex);
let v = chunk.height_data_mut()[pos]; // panics: not f32
// after
let heights: Vec<f32> = img.pixels().map(|p| p[0] as f32 / 255.0).collect();
let tex = make_height_map_texture(heights, size);
chunk.set_height_map(tex);
Defensive patterns

Strategy: validation

Validate before calling

let data = chunk.height_map().unwrap().data_ref();
assert!(data.data_of_type::<f32>().is_some(), "terrain heightmap must contain f32 pixel data");

Type guard

fn is_f32_heightmap(tex: &TextureResource) -> bool {
    tex.data_ref().data_of_type::<f32>().is_some()
}

Try / catch

// Guard rather than catch: check dtype before indexing
if is_f32_heightmap(&chunk.height_map().unwrap()) {
    let v = chunk.height_data_mut()[pos];
} else {
    // rebuild heightmap as f32
}

Prevention

When it happens

Trigger: Indexing ChunkHeightMutData when the heightmap texture was created with a non-f32 pixel format (e.g. RGBA8, R8), typically by replacing the chunk heightmap with a hand-built texture instead of make_height_map_texture.

Common situations: Importing a heightmap from an image file (PNG/JPG yields u8 RGBA data) directly as terrain heightmap; custom terrain generation pipelines that forget to convert pixel data to f32; scene assets edited externally.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/246eb9914b345a4e. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-impl/src/scene/terrain/mod.rs:216

    }
    #[inline]
    fn is_valid_index(&self, position: Vector2<i32>) -> bool {
        let s = self.size();
        (-1..=s.x as i32).contains(&position.x) && (-1..=s.y as i32).contains(&position.y)
    }
}

impl std::ops::Index<Vector2<i32>> for ChunkHeightData<'_> {
    type Output = f32;

    fn index(&self, position: Vector2<i32>) -> &Self::Output {
        assert!(self.is_valid_index(position));
        let row_size = self.row_size();
        let x = (position.x + 1) as usize;
        let y = (position.y + 1) as usize;
        match self.0.data_of_type::<f32>() {
            Some(d) => &d[y * row_size + x],
            None => panic!("Height data type error: {:?}", self.0),
        }
    }
}
impl std::ops::Index<Vector2<i32>> for ChunkHeightMutData<'_> {
    type Output = f32;

    fn index(&self, position: Vector2<i32>) -> &Self::Output {
        assert!(self.is_valid_index(position));
        let row_size = self.row_size();
        let x = (position.x + 1) as usize;
        let y = (position.y + 1) as usize;
        &self.0.data_of_type::<f32>().unwrap()[y * row_size + x]
    }
}
impl std::ops::IndexMut<Vector2<i32>> for ChunkHeightMutData<'_> {
    fn index_mut(&mut self, position: Vector2<i32>) -> &mut Self::Output {
        assert!(self.is_valid_index(position));
        let row_size = self.row_size();

View on GitHub (pinned to 76c91aad8e)