{"record":{"id":"aff15d8b4cd5f757","repo":"FyroxEngine/Fyrox","slug":"tile-data-swap-error","errorCode":null,"errorMessage":"Tile data swap error","messagePattern":"Tile data swap error","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fyrox-impl/src/scene/tilemap/update.rs","lineNumber":291,"sourceCode":"        match std::mem::take(self) {\n            TileDataUpdate::MaterialTile(d) => d,\n            _ => panic!(),\n        }\n    }\n    /// Remove `TileDefinition` and turn this object into `Erase`, if this is a FreeformTile. Otherwise, panic.\n    pub fn take_definition(&mut self) -> TileDefinition {\n        match std::mem::take(self) {\n            TileDataUpdate::FreeformTile(d) => d,\n            _ => panic!(),\n        }\n    }\n    /// Swap whatever value is in this tile update with the corresponding value in the given TileData.\n    /// If this update has no data to swap, then do nothing and set this update to `DoNothing`.\n    pub fn swap_with_data(&mut self, data: &mut TileData) {\n        match self {\n            TileDataUpdate::DoNothing => (),\n            TileDataUpdate::Erase => {\n                Log::err(\"Tile data swap error\");\n                *self = Self::DoNothing;\n            }\n            TileDataUpdate::MaterialTile(tile_data) => std::mem::swap(tile_data, data),\n            TileDataUpdate::FreeformTile(tile_definition) => {\n                std::mem::swap(&mut tile_definition.data, data)\n            }\n            TileDataUpdate::Color(color) => std::mem::swap(color, &mut data.color),\n            TileDataUpdate::Collider(colliders) => {\n                for (uuid, value) in colliders.iter_mut() {\n                    match data.colliders.entry(*uuid) {\n                        Entry::Occupied(mut e) => {\n                            if let TileCollider::None = value {\n                                *value = e.remove();\n                            } else {\n                                std::mem::swap(e.get_mut(), value)\n                            }\n                        }\n                        Entry::Vacant(e) => {","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-impl/src/scene/tilemap/update.rs#L273-L309","documentation":"TileDataUpdate::swap_with_data swaps the update's payload with a TileData value. It is called when the update variant carries per-tile data (MaterialTile/FreeformTile/Property). If the variant is Erase (or another non-data variant) it cannot swap anything, so the engine logs this error and downgrades the update to DoNothing to keep the update list consistent.","triggerScenarios":"Calling swap_with_data on a TileDataUpdate that is TileDataUpdate::Erase; this happens in tilemap update processing when an erase-marker update is applied against tile data.","commonSituations":"Custom tilemap tooling or editor plugins that construct TileDataUpdate sequences manually and mix Erase updates with data swaps; applying recorded tile updates from a stale or mismatched update batch.","solutions":["Ensure only MaterialTile, FreeformTile, or Property (with payload) updates are passed to swap_with_data","Send Erase updates through the normal tile-set erase path instead of the data-swap path","Check for logic that appends Erase updates where data updates were intended"],"exampleFix":"// before\nupdate.swap_with_data(&mut tile_data); // update may be Erase\n// after\nif matches!(update, TileDataUpdate::MaterialTile(_) | TileDataUpdate::FreeformTile(_) | TileDataUpdate::Property(..)) {\n    update.swap_with_data(&mut tile_data);\n}","handlingStrategy":"validation","validationCode":"if matches!(update, TileDataUpdate::Erase | TileDataUpdate::DoNothing | TileDataUpdate::TransformSet(_) | TileDataUpdate::Material(_)) {\n    return; // do not call swap_with_data\n}\nupdate.swap_with_data(&mut tile_data);","typeGuard":"fn can_swap(u: &TileDataUpdate) -> bool {\n    matches!(u, TileDataUpdate::MaterialTile(_) | TileDataUpdate::FreeformTile(_) | TileDataUpdate::Property(..))\n}","tryCatchPattern":null,"preventionTips":["Only pass data-carrying variants to swap_with_data","Route erase/transform/material updates through their dedicated paths","Log update variant before swapping when debugging tilemap batches"],"tags":["tilemap","invalid-state","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}