babalae/better-genshin-impact · error · FileNotFoundException

未找到{taskName}的素材文件夹

Error message

未找到{taskName}的素材文件夹

What it means

RecognitionAssets.LoadTemplateImage resolves the resolution-specific assets folder GameTask\{taskName}\Assets\{W}x{H}, then falls back to 1920x1080. If neither directory exists it throws FileNotFoundException for the whole folder, so template-based recognition for that task cannot load any image.

Source

Thrown at BetterGenshinImpact/Core/Recognition/RecognitionAssets.cs:86

            new RecognitionObjectJsonLoadContext
            {
                CaptureHeight = key.CaptureHeight,
                CaptureWidth = key.CaptureWidth,
                TemplateLoader = (template, mode) => LoadTemplateImage(key.TaskName, template, key.CaptureWidth, key.CaptureHeight, mode),
            });
    }

    private static Mat LoadTemplateImage(string taskName, string assetName, int captureWidth, int captureHeight, ImreadModes flags)
    {
        var assetsFolder = Global.Absolute($@"GameTask\{taskName}\Assets\{captureWidth}x{captureHeight}");
        if (!Directory.Exists(assetsFolder))
        {
            assetsFolder = Global.Absolute($@"GameTask\{taskName}\Assets\1920x1080");
        }

        if (!Directory.Exists(assetsFolder))
        {
            throw new FileNotFoundException($"未找到{taskName}的素材文件夹");
        }

        var filePath = Path.Combine(assetsFolder, assetName);
        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException($"未找到{taskName}中的{assetName}文件");
        }

        using var stream = File.OpenRead(filePath);
        var mat = Mat.FromStream(stream, flags);
        if (captureWidth < 1920)
        {
            using (mat)
            {
                return ResizeHelper.Resize(mat, captureWidth / 1920d);
            }
        }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Create GameTask\{taskName}\Assets\1920x1080\ with at least the required template images.
  2. Confirm the taskName passed to RecognitionAssets.Get matches the actual folder name exactly (case-sensitive on some filesystems).
  3. Verify Global.Absolute resolves to the project/app root where GameTask lives.
  4. If a non-1080p capture is expected, also add a {captureWidth}x{captureHeight} folder or rely on the automatic resize from the 1080p fallback.

Example fix

// before
var ro = RecognitionAssets.Get("AutoFishing", "rod"); // folder missing -> throws

// after
var folder = Global.Absolute(@"GameTask\AutoFishing\Assets\1920x1080");
if (!Directory.Exists(folder))
    throw new InvalidOperationException($"Assets folder missing: {folder}");
var ro = RecognitionAssets.Get("AutoFishing", "rod");
Defensive patterns

Strategy: validation

Validate before calling

bool HasAssetsFolder(string taskName)
{
    var root = Global.Absolute($@"GameTask\{taskName}\Assets");
    return Directory.Exists(Path.Combine(root, "1920x1080"))
        || Directory.EnumerateDirectories(root).Any(d => d.EndsWith("x1080", StringComparison.OrdinalIgnoreCase));
}

if (!HasAssetsFolder(taskName))
    throw new InvalidOperationException($"Assets folder missing for task {taskName}");

Try / catch

try { var ro = RecognitionAssets.Get(taskName, objectName); }
catch (FileNotFoundException ex) when (ex.Message.Contains("的素材文件夹"))
{ Logger.LogError(ex, "Assets folder missing for {Task}.", taskName); throw; }

Prevention

When it happens

Trigger: Calling RecognitionAssets.Get(taskName, objectName, ...) for a task whose Assets folder is entirely absent at both the requested resolution and the 1920x1080 fallback.

Common situations: New game task added without shipping its Assets folder; task renamed but assets not moved; capture resolution folder named with the wrong format (e.g. 1080x1920 vs 1920x1080); assets excluded from the build.

Related errors


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