babalae/better-genshin-impact · critical · Exception
地图数据加载失败,文件
Error message
地图数据加载失败,文件: {kpFilePath} What it means
Thrown in the BigMapTeyvat256Layer constructor (lazy singleton) when FeatureStorageHelper.LoadKeyPointArray(kpFilePath) returns null for the special 256-scale Teyvat SIFT keypoint file ('Teyvat_0_256_SIFT.kp.bin'). This is the dedicated large-map fast-matching dataset; if the file is absent the singleton cannot be built. Note this exact filename is explicitly excluded from the generic LoadLayers scan, so it is only loaded here.
Solutions
- Confirm Assets\Map\Teyvat\Teyvat_0_256_SIFT.kp.bin exists; restore it from the repo or the asset release.
- Ensure binary map assets are tracked (Git LFS or direct) and fetched after clone.
- If running a slimmed build that omits 256 data, avoid invoking the big-map 256 matcher or fall back to the 2048 path.
Defensive patterns
Strategy: validation
Validate before calling
var kpFilePath = Path.Combine(layerDir, "Teyvat_0_256_SIFT.kp.bin");
if (!File.Exists(kpFilePath)) throw new FileNotFoundException($"缺少提瓦特 256 特征数据: {kpFilePath}", kpFilePath); Prevention
- Ensure 256-scale Teyvat assets are fetched (Git LFS / asset release).
- Run an asset-presence check before constructing the singleton.
- Avoid the 256 big-map matcher in slim builds that omit the dataset.
When it happens
Trigger: GetInstance(baseMap) is first called; the private constructor builds kpFilePath = <mapDir>/Teyvat_0_256_SIFT.kp.bin and calls LoadKeyPointArray, which returns null because the file does not exist. The ?? throws.
Common situations: The 256-scale Teyvat dataset was not included in the deployment/build; a clean checkout omitted the large binary assets; the file was gitignored or not fetched via LFS; the assets folder was pruned to save space.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/7449f7bb38b4aede.
Report an issue: GitHub.
Appendix: source
Thrown at BetterGenshinImpact/GameTask/Common/Map/Maps/Layer/BigMapTeyvat256Layer.cs:29
public class BigMapTeyvat256Layer : BaseMapLayer
{
// 大地图使用256 相对 2048 区块的缩放比例 2048/256=8
public const int BigMap256ScaleTo2048 = 8;
private static BigMapTeyvat256Layer? _instance;
private static readonly object LockObject = new();
private readonly Size _mapSize256;
private readonly Feature2D _siftMatcher;
private BigMapTeyvat256Layer(SceneBaseMap baseMap) : base(baseMap)
{
Floor = 0;
var layerDir = Path.Combine(Global.Absolute(@"Assets\Map\"), baseMap.Type.ToString());
var kpFilePath = Path.Combine(layerDir, "Teyvat_0_256_SIFT.kp.bin");
var matFilePath = Path.Combine(layerDir, "Teyvat_0_256_SIFT.mat.png");
TrainKeyPoints = FeatureStorageHelper.LoadKeyPointArray(kpFilePath) ?? throw new Exception($"地图数据加载失败,文件: {kpFilePath}");
TrainDescriptors = FeatureStorageHelper.LoadDescriptorMat(matFilePath) ?? throw new Exception($"地图数据加载失败,文件: {matFilePath}");
_mapSize256 = new Size(baseMap.MapSize.Width / BigMap256ScaleTo2048, baseMap.MapSize.Height / BigMap256ScaleTo2048);
SplitBlocks = KeyPointFeatureBlockHelper.SplitFeatures(_mapSize256, TeyvatMap.GameMapRows * 4, TeyvatMap.GameMapCols * 4, TrainKeyPoints, TrainDescriptors);
_siftMatcher = baseMap.SiftMatcher;
}
public static BigMapTeyvat256Layer GetInstance(SceneBaseMap baseMap)
{
if (_instance != null)
{
return _instance;
}
lock (LockObject)
{
if (_instance == null)View on GitHub (pinned to a7cb36712d)