Good day to the community.
There’s a problem i could’nt quite understand. I’ve recently migrated on the latest monogame version (been using old one for a year or so), and suddenly my content pipeline stops working.
After some source trawling, i’ve discovered that from this line (which was entirely plausible before)
Since it couldn’t be loaded as xnb, it goes all the way to the ReadRawAsset(), which acquires two arguments - full path and original string, and then it calls TitleContainer.OpenStream with a full path, which isn’t really what TitleContainer is used to.
public static Stream OpenStream(string name)
{
// Normalize the file path.
var safeName = GetFilename(name);
// We do not accept absolute paths here.
if (Path.IsPathRooted(safeName))
throw new ArgumentException("Invalid filename. TitleContainer.OpenStream requires a relative path.");
Is this an intended behaviour? And if so, how one should load raw (non-xnb) assets?
ContentManager.cs
Running code starts after the “MonoGame try to load as a non-content file” commentary.
It all make any sense only if you specify ContentManager’s RootDirectory as a relative instead of absolute i’ve used it to. Then content manager adds a content portion of the path and TitleContainer makes it platform-independent absolute. Is that the case?
The RootDirectory is relative, but MonoGame has to convert it to an absolute path. You can have a look at the MonoGame call stack to see where things went wrong.
I don’t know if there’s something wrong in first place.
I’ve probably made a mistake, setting ContentManager.RootDirectory as absolute. It just worked in previous versions, that’s what confused me. I’ll try to remake it to relative and will report back.
Ahh, so you set the RootDirectory as absolute. Yes, that’s a problem since tha game can be installed anywhere and MonoGame is designed to work with relative paths.
Well, of course i’ve been detecting this absolute path from current working directory. I’m not THAT bad =).
The thing is, relative path won’t work either.
Code from the master branch ContentManager.cs with my comments:
//MonoGame try to load as a non-content file
//a333: RootDirectory is relative, so assetName variable will be relative too
assetName = TitleContainer.GetFilename(Path.Combine(RootDirectory, assetName));
//a333: this normalization method only accepts absolute paths, and will yield null if applied to relative
assetName = Normalize<T>(assetName);
//a333: as a result, we'll get a throw.
if (string.IsNullOrEmpty(assetName))
{
throw new ContentLoadException("Could not load " + originalAssetName + " asset as a non-content file!", ex);
}
We create ContentManager, then set its RootDirectory to some path. Either relative or absolute.
We try to load some (non-builded) asset with ContentManager.Load(assetName), which could include subdirectories.
If the RootDirectory was relative, path gets normalized to null just before ReadRawAsset call in the CM.Load method. Exception as a result.
If the RootDirectory was absolute, it proceeds further to the ReadRawAsset and then to the TitleContainer.OpenStream, where absolute paths aren’t allowed.