FyroxEngine/Fyrox · error
Invalid pixel position
Error message
Invalid pixel position: ({}, {}) within ({}, {}) What it means
StrokeChunks::pixel_index converts a 2D position into a linear index into a chunk's texture data, after validating it with `is_valid_pixel`. It panics when the position lies outside the chunk's `[0, chunk_size)` bounds, preventing an out-of-bounds write into texture memory.
Solutions
- Call `is_valid_pixel(position)` first and skip/handle invalid positions instead of panicking.
- Convert global terrain positions to chunk-local positions before calling pixel_index.
- Clamp or split the brush footprint so each position stays within the owning chunk's chunk_size.
Example fix
// before
let idx = chunk.pixel_index(position);
// after
if chunk.is_valid_pixel(position) {
let idx = chunk.pixel_index(position);
} Defensive patterns
Strategy: validation
Validate before calling
if chunk.is_valid_pixel(position) {
let idx = chunk.pixel_index(position);
} Try / catch
// Rust panic - avoid instead with is_valid_pixel pre-check (see validationCode).
Prevention
- Always convert global terrain coordinates to chunk-local coordinates before pixel_index.
- Clamp brush footprints to chunk bounds; skip out-of-range pixels.
- Add assert-style unit tests around chunk boundary positions (0 and chunk_size - 1).
When it happens
Trigger: Calling `pixel_index(position)` where `position.x < 0 || position.y < 0 || position.x >= chunk_size.x || position.y >= chunk_size.y` — e.g. painting at a terrain coordinate that maps into a neighboring chunk or beyond the chunk's edge.
Common situations: Custom brush code not clamping positions to chunk bounds; brush radius extending past chunk edges; using global terrain coordinates instead of chunk-local coordinates.
Related errors
- Height data type error
- Missing hole mask texture
- only rectangle textures can be used as render target!
- only rectangle textures can be used as render target!
- Setting latest value of missing element
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/cc62cf026c1c4314.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/scene/terrain/brushstroke/strokechunks.rs:161
pub fn chunk_to_origin(&self, grid_position: Vector2<i32>) -> Vector2<i32> {
Vector2::new(
grid_position.x * self.chunk_size.x as i32,
grid_position.y * self.chunk_size.y as i32,
)
}
/// The width of the texture in pixels.
pub fn row_size(&self) -> usize {
match self.kind {
TerrainTextureKind::Height => (self.chunk_size.x + 3) as usize,
TerrainTextureKind::Mask => self.chunk_size.x as usize,
}
}
/// Calculate the index of a pixel at the given position within texture data,
/// based on the row size. The given position is relative to the origin of the texture
/// and must be within the bounds of the texture.
pub fn pixel_index(&self, position: Vector2<i32>) -> usize {
if !self.is_valid_pixel(position) {
panic!(
"Invalid pixel position: ({}, {}) within ({}, {})",
position.x, position.y, self.chunk_size.x, self.chunk_size.y
);
}
let p = match self.kind {
TerrainTextureKind::Height => position.map(|x| (x + 1) as usize),
TerrainTextureKind::Mask => position.map(|x| x as usize),
};
p.x + p.y * self.row_size()
}
/// True if the given pixel position is within the bounds of a chunk for the current kind of chunk data.
/// Due to the margins of the height textures, it is permitted to index height textures to -1 and chunk_size.x + 1.
pub fn is_valid_pixel(&self, position: Vector2<i32>) -> bool {
let size = self.chunk_size.map(|x| x as i32);
match self.kind {
TerrainTextureKind::Height => {
(-1..=size.x + 1).contains(&position.x) && (-1..=size.y + 1).contains(&position.y)
}View on GitHub (pinned to 76c91aad8e)