{"record":{"id":"edadd565c68ee126","repo":"babalae/better-genshin-impact","slug":"taskname","errorCode":null,"errorMessage":"未找到{taskName}的素材文件夹","messagePattern":"未找到(.+?)的素材文件夹","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Core/Recognition/RecognitionAssets.cs","lineNumber":86,"sourceCode":"            new RecognitionObjectJsonLoadContext\n            {\n                CaptureHeight = key.CaptureHeight,\n                CaptureWidth = key.CaptureWidth,\n                TemplateLoader = (template, mode) => LoadTemplateImage(key.TaskName, template, key.CaptureWidth, key.CaptureHeight, mode),\n            });\n    }\n\n    private static Mat LoadTemplateImage(string taskName, string assetName, int captureWidth, int captureHeight, ImreadModes flags)\n    {\n        var assetsFolder = Global.Absolute($@\"GameTask\\{taskName}\\Assets\\{captureWidth}x{captureHeight}\");\n        if (!Directory.Exists(assetsFolder))\n        {\n            assetsFolder = Global.Absolute($@\"GameTask\\{taskName}\\Assets\\1920x1080\");\n        }\n\n        if (!Directory.Exists(assetsFolder))\n        {\n            throw new FileNotFoundException($\"未找到{taskName}的素材文件夹\");\n        }\n\n        var filePath = Path.Combine(assetsFolder, assetName);\n        if (!File.Exists(filePath))\n        {\n            throw new FileNotFoundException($\"未找到{taskName}中的{assetName}文件\");\n        }\n\n        using var stream = File.OpenRead(filePath);\n        var mat = Mat.FromStream(stream, flags);\n        if (captureWidth < 1920)\n        {\n            using (mat)\n            {\n                return ResizeHelper.Resize(mat, captureWidth / 1920d);\n            }\n        }\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Recognition/RecognitionAssets.cs#L68-L104","documentation":"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.","triggerScenarios":"Calling RecognitionAssets.Get(taskName, objectName, ...) for a task whose Assets folder is entirely absent at both the requested resolution and the 1920x1080 fallback.","commonSituations":"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.","solutions":["Create GameTask\\{taskName}\\Assets\\1920x1080\\ with at least the required template images.","Confirm the taskName passed to RecognitionAssets.Get matches the actual folder name exactly (case-sensitive on some filesystems).","Verify Global.Absolute resolves to the project/app root where GameTask lives.","If a non-1080p capture is expected, also add a {captureWidth}x{captureHeight} folder or rely on the automatic resize from the 1080p fallback."],"exampleFix":"// before\nvar ro = RecognitionAssets.Get(\"AutoFishing\", \"rod\"); // folder missing -> throws\n\n// after\nvar folder = Global.Absolute(@\"GameTask\\AutoFishing\\Assets\\1920x1080\");\nif (!Directory.Exists(folder))\n    throw new InvalidOperationException($\"Assets folder missing: {folder}\");\nvar ro = RecognitionAssets.Get(\"AutoFishing\", \"rod\");","handlingStrategy":"validation","validationCode":"bool HasAssetsFolder(string taskName)\n{\n    var root = Global.Absolute($@\"GameTask\\{taskName}\\Assets\");\n    return Directory.Exists(Path.Combine(root, \"1920x1080\"))\n        || Directory.EnumerateDirectories(root).Any(d => d.EndsWith(\"x1080\", StringComparison.OrdinalIgnoreCase));\n}\n\nif (!HasAssetsFolder(taskName))\n    throw new InvalidOperationException($\"Assets folder missing for task {taskName}\");","typeGuard":null,"tryCatchPattern":"try { var ro = RecognitionAssets.Get(taskName, objectName); }\ncatch (FileNotFoundException ex) when (ex.Message.Contains(\"的素材文件夹\"))\n{ Logger.LogError(ex, \"Assets folder missing for {Task}.\", taskName); throw; }","preventionTips":["Always ship at least a 1920x1080 Assets folder for every game task.","Keep taskName in code identical to the folder name.","Add a build step that fails when a GameTask folder has no Assets directory."],"tags":["assets","game-task","asset-missing","template","resolution"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}