babalae/better-genshin-impact · critical · Exception

地图数据加载失败,文件: {kpFilePath}

Error message

地图数据加载失败,文件: {kpFilePath}

What it means

Thrown in BaseMapLayer.LoadLayers when FeatureStorageHelper.LoadKeyPointArray(kpFilePath) returns null. That helper returns null only when File.Exists(kpPath) is false (it throws FileFormatException for malformed files). So this exception means the keypoint .kp.bin file referenced by the group does not exist on disk, even though the filename was enumerated by Directory.GetFiles — typically because GetFileNameWithoutExtension stripped only one extension leaving a path mismatch, or the file was deleted between enumeration and load.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayer.cs:95

            {
                throw new Exception($"分层地图数据文件夹中中存在无法解析的文件名: {fileName}");
            }

            return int.TryParse(parts[1], out var floor) ? floor : throw new Exception($"分层地图数据文件夹中中存在无法解析的文件名: {fileName}");
        });

        foreach (var group in groupedFiles)
        {
            var floor = group.Key;
            var layer = new BaseMapLayer(baseMap) { Floor = floor };

            // 查找特征文件路径
            var kpFilePath = group.First(f => f.EndsWith(".kp.bin"));
            var matFilePath = group.First(f => f.EndsWith(".mat.png"));

            SpeedTimer speedTimer = new($"加载 {Path.GetFileNameWithoutExtension(kpFilePath)} 地图特征");
            // 加载特征数据
            layer.TrainKeyPoints = FeatureStorageHelper.LoadKeyPointArray(kpFilePath) ?? throw new Exception($"地图数据加载失败,文件: {kpFilePath}");
            speedTimer.Record("特征点");
            layer.TrainDescriptors = FeatureStorageHelper.LoadDescriptorMat(matFilePath) ?? throw new Exception($"地图数据加载失败,文件: {matFilePath}");
            speedTimer.Record("特征描述");

            // 切割特征数据
            if (baseMap.SplitRow > 0 || baseMap.SplitCol > 0)
            {
                layer.SplitBlocks = KeyPointFeatureBlockHelper.SplitFeatures(baseMap.MapSize, baseMap.SplitRow, baseMap.SplitCol, layer.TrainKeyPoints, layer.TrainDescriptors);
                speedTimer.Record("切割特征点");
            }

            speedTimer.DebugPrint();

            layers.Add(layer);
        }

        // 从 0, -1, -2 这样的顺序对这个list排序
        layers.Sort((a, b) =>

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the .kp.bin file reported in the message actually exists at that path at load time.
  2. Ensure no antivirus or sync tool is removing .bin files from Assets\Map.
  3. If the file is genuinely missing, regenerate the map feature dataset.
  4. Check file permissions and that the path is not on an unreliable mount.
Defensive patterns

Strategy: validation

Validate before calling

foreach (var f in validFiles.Where(f => f.EndsWith(".kp.bin")))
{
    if (!File.Exists(f)) Logger.LogWarning("特征点文件不存在: {Path}", f);
}

Prevention

When it happens

Trigger: In the foreach over groupedFiles, kpFilePath = group.First(f => f.EndsWith(".kp.bin")) is the full path returned by Directory.GetFiles, then LoadKeyPointArray checks File.Exists. Because Path.GetFileNameWithoutExtension removes only the last extension, 'Teyvat_0_2048_SIFT.kp.bin' becomes 'Teyvat_0_2048_SIFT.kp' — but that only affects the parse, not the existence check. The null result specifically means the file vanished or the path is otherwise invalid.

Common situations: Antivirus/quarantine removed a .bin file after enumeration; the directory is on a network/removable drive with intermittent availability; a concurrent process deleted the file; the path contains characters that make File.Exists behave unexpectedly under some locales.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/63be1bb5a26eb32d. Report an issue: GitHub.