Shawn Hargreaves Blog
The XNA Framework provides no less than three different APIs for reading data out of files. This table attempts to explain the differences, and thus help you understand which to choose:
Note that I did not include ContentManager.Load in this table, although that is probably the most commonly used API for loading data into XNA games! There is an important but easily missed layering here:
The aforementioned three APIs are responsible for opening streams that can be used to read sequences of bytes from a filesystem. They do not know or care what these bytes represent, or what format they are in.
ContentManager is primarily a deserialization mechanism. It is responsible for taking a sequence of bytes which contains a .xnb file created by the XNA Framework Content Pipeline, and turning those bytes into managed objects. It is also responsible for managing the lifespan of the resulting objects.
By default, ContentManager.OpenStream is wired up to call TitleContainer.OpenStream, because .xnb files are usually deployed as part of the game, so you most often want to load them from the title container. But if you override the OpenStream method, you can make ContentManager read from somewhere else. It could load from isolated storage, or a save game storage container, or a MemoryStream (options that have limited usefulness in practice, because you cannot compile to .xnb format at runtime, so the only way to get .xnb data into isolated storage would be to copy over one that was created at build time, and I can't think of any reason that would ever be useful, but there you go :-)
In the same way that ContentManager can deserialize from anywhere that provides a stream, you can also use any other deserialization mechanism to interpret the bytes obtained from any of these sources. If your title container contains files that are not in .xnb format, you could process them using BinaryReader, or XmlSerializer, or Texture2D.FromStream, or whatever else makes sense for the format of that particular data.
"options that have limited usefulness in practice, because you cannot compile to .xnb format at runtime, so the only way to get .xnb data into isolated storage would be to copy over one that was created at build time, and I can't think of any reason that would ever be useful, but there you go"
On Windows Phone, you could download extra levels or game data to extend the game and save it in isolated storage. To satisfy the App Cert Requirements you would not be allowed to charge for these extras, but it is a useful reason.
Now there's an odd thought - would it be possible to pass built .xnb files across the web to sort of load-on-demand for a game? The .xnb files would still be compiled/built at build time, but could be stored on a central server somewhere.
There are most certainly better ways of doing such a thing, but would it be possible to do such a thing (in theory)?
I havent ported my xna 3.1 storage system to 4.0 yet, but this reminds me of my confusion/concern: How do you discover what files are available in the Title Container?
xna 3.1 let you enumerate what files are in the title container. But no API seems to let you do this in 4.0.
the only workaround I see is to construct a index file that informs what files are available. Is this the case?
> xna 3.1 let you enumerate what files are in the title container. But no API seems to let you do this in 4.0.
Right. See this sample: create.msdn.com/.../contentmanifestextensions
thanks for that link shawn. That sounds like an acceptable solution to me (Especially since I don't have to write the code myself!)
I have forgotten to subscribe to the xna samples rss feed, so was not aware of this (or I'm sure other awesome stuff)
Awesome post, thank you very much!