babalae/better-genshin-impact · critical · Exception

彩色分层地图 {LayerId} 读取失败

Error message

彩色分层地图 {LayerId} 读取失败

What it means

Thrown in BaseMapLayerByTemplateMatch.LoadLayer when reading the color map image for a template-match layer. NOTE: Bv.ImRead returns a non-nullable Mat (it calls Mat.FromStream(File.OpenRead(fileName), flags)), so the '?? throw' is effectively dead code — ImRead can never return null. The real failure path is File.OpenRead throwing FileNotFoundException/FolderNameException when colorMapPath (LayerId + "_color.webp") does not exist. The custom message is therefore only reachable in theory, not in practice.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Map/Maps/Base/BaseMapLayerByTemplateMatch.cs:37

    public string LayerGroupId { get; set; } = string.Empty;
    public string LayerId { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public float Scale { get; set; } = 1;
    public int Floor { get; set; } = 0;
    public float Top { get; set; } = 0;
    public float Left { get; set; } = 0;
    public bool IsOverSize  { get; set; } = false;
    [JsonIgnore]
    public required FastSqDiffMatcher CoarseColorMatcher; // 小尺寸彩图
    [JsonIgnore]
    public Mat FineGrayMap = new Mat(); // 大尺寸灰度图
    
    public void LoadLayer(string layerDir)
    {
        SpeedTimer speedTimer = new($"加载 {LayerId} 地图图片");
        var colorMapFileName = LayerId + "_color" + ".webp";
        var colorMapPath = Path.Combine(layerDir, colorMapFileName);
        var coarseColorMap = Bv.ImRead(colorMapPath)?? throw new Exception($"彩色分层地图 {LayerId} 读取失败");
        speedTimer.Record("精确匹配用彩图");
        CoarseColorMatcher = new FastSqDiffMatcher(coarseColorMap, new Size(52, 52));
        var grayMapFileName = LayerId + "_gray" + (IsOverSize ? ".png" : ".webp");
        var grayMapPath = Path.Combine(layerDir, grayMapFileName);
        FineGrayMap = Bv.ImRead(grayMapPath, ImreadModes.Grayscale)?? throw new Exception($"灰度分层地图 {LayerId} 读取失败");
        speedTimer.Record("粗匹配用灰度图");
        speedTimer.DebugPrint();
    }

    public static List<BaseMapLayerByTemplateMatch> LoadLayers(SceneBaseMapByTemplateMatch sceneBaseMap)
    {
        var layers = new List<BaseMapLayerByTemplateMatch>();
        var layerDir = Path.Combine(Global.Absolute(@"Assets\Map\"), sceneBaseMap.Type.ToString());
        if (!Directory.Exists(layerDir))
        {
            return layers;
        }
        var jsonFiles = Directory.GetFiles(layerDir, "*.json", SearchOption.AllDirectories);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify that <LayerId>_color.webp exists in the map directory for every layer defined in the JSON files.
  2. Make sure the LayerId in each JSON matches the image filename prefix exactly.
  3. If you actually want a clear error, guard with File.Exists before ImRead, since the current ?? never fires.
  4. Redeploy the complete map image assets for the affected map type.

Example fix

// before
var coarseColorMap = Bv.ImRead(colorMapPath)?? throw new Exception($"彩色分层地图 {LayerId} 读取失败");

// after — ImRead is non-nullable, so guard existence explicitly to get the intended message
if (!File.Exists(colorMapPath)) throw new Exception($"彩色分层地图 {LayerId} 读取失败: 缺少 {colorMapPath}");
var coarseColorMap = Bv.ImRead(colorMapPath);
Defensive patterns

Strategy: validation

Validate before calling

var colorMapPath = Path.Combine(layerDir, LayerId + "_color.webp");
if (!File.Exists(colorMapPath)) throw new FileNotFoundException($"缺少彩色地图: {colorMapPath}", colorMapPath);

Prevention

When it happens

Trigger: LoadLayer computes colorMapPath = Path.Combine(layerDir, LayerId + "_color.webp") and calls Bv.ImRead(colorMapPath). If the .webp is missing, File.OpenRead throws FileNotFoundException (not this exception). The '?? throw' branch is unreachable because ImRead's declared return type is non-nullable Mat.

Common situations: A template-match layer JSON was deserialized (LayerId set) but its corresponding <LayerId>_color.webp was not shipped in Assets\Map\<Type>; LayerId in the JSON doesn't match the image filename; assets partially deployed.

Related errors


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