{"record":{"id":"43d1cebc005b3e4b","repo":"babalae/better-genshin-impact","slug":"matfilepath","errorCode":null,"errorMessage":"地图数据加载失败，文件: {matFilePath}","messagePattern":"地图数据加载失败，文件: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayer.cs","lineNumber":97,"sourceCode":"            }\n\n            return int.TryParse(parts[1], out var floor) ? floor : throw new Exception($\"分层地图数据文件夹中中存在无法解析的文件名: {fileName}\");\n        });\n\n        foreach (var group in groupedFiles)\n        {\n            var floor = group.Key;\n            var layer = new BaseMapLayer(baseMap) { Floor = floor };\n\n            // 查找特征文件路径\n            var kpFilePath = group.First(f => f.EndsWith(\".kp.bin\"));\n            var matFilePath = group.First(f => f.EndsWith(\".mat.png\"));\n\n            SpeedTimer speedTimer = new($\"加载 {Path.GetFileNameWithoutExtension(kpFilePath)} 地图特征\");\n            // 加载特征数据\n            layer.TrainKeyPoints = FeatureStorageHelper.LoadKeyPointArray(kpFilePath) ?? throw new Exception($\"地图数据加载失败，文件: {kpFilePath}\");\n            speedTimer.Record(\"特征点\");\n            layer.TrainDescriptors = FeatureStorageHelper.LoadDescriptorMat(matFilePath) ?? throw new Exception($\"地图数据加载失败，文件: {matFilePath}\");\n            speedTimer.Record(\"特征描述\");\n\n            // 切割特征数据\n            if (baseMap.SplitRow > 0 || baseMap.SplitCol > 0)\n            {\n                layer.SplitBlocks = KeyPointFeatureBlockHelper.SplitFeatures(baseMap.MapSize, baseMap.SplitRow, baseMap.SplitCol, layer.TrainKeyPoints, layer.TrainDescriptors);\n                speedTimer.Record(\"切割特征点\");\n            }\n\n            speedTimer.DebugPrint();\n\n            layers.Add(layer);\n        }\n\n        // 从 0, -1, -2 这样的顺序对这个list排序\n        layers.Sort((a, b) =>\n        {\n            if (a.Floor == b.Floor)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayer.cs#L79-L115","documentation":"Companion to error 403, thrown one line later when FeatureStorageHelper.LoadDescriptorMat(matFilePath) returns null. LoadDescriptorMat returns null only when File.Exists(descriptorPath) is false; otherwise it reads the image and converts it. So this means the descriptor .mat.png file for the floor does not exist on disk.","triggerScenarios":"After the keypoint file loaded successfully, the code loads matFilePath = group.First(f => f.EndsWith(\".mat.png\")) and calls LoadDescriptorMat, which returns null because the .mat.png is absent. This usually indicates an incomplete dataset: the .kp.bin is present but its paired .mat.png is not.","commonSituations":"Partial dataset where a .kp.bin exists but the matching .mat.png was not generated/copied; file copy interrupted; generation tool failed midway and wrote only one of the pair.","solutions":["Confirm both '<name>.kp.bin' and '<name>.mat.png' exist together for every floor in Assets\\Map\\<Type>.","Regenerate the full dataset so pairs are always produced together.","Add a pre-load validation pass that checks each group has both extensions before attempting to load."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify each group has BOTH a kp and a mat file before loading\nforeach (var g in groupedFiles)\n{\n    if (!g.Any(f => f.EndsWith(\".kp.bin\")) || !g.Any(f => f.EndsWith(\".mat.png\")))\n        throw new Exception($\"楼层 {g.Key} 缺少配对的 .kp.bin 或 .mat.png\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate and ship keypoint/descriptor files as atomic pairs.","Add a startup asset-integrity check that reports missing pairs."],"tags":["map-data","asset-loading","missing-file","feature-match"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}