-
|
|
What's the most confusing thing about the content pipeline?
|
I've started to look through some of the feedback from our recent survey, and noticed that there's a lot of you out there who are having trouble understanding the content pipeline. Documentation was a frequent complaint, and a few people mentioned a lack of a high level overview.
To remedy this, I'm considering starting a series of blog posts on the content pipeline. Are there any topics in particular you would like me to cover, or any parts that you find particularly confusing? I'll see what I can do to pay particular attention to those areas. Please, remember to be specific! "It's no good!" doesn't help me :)
Eli Tayrien - XNA Framework Developer
|
|
-
-
- (462)
-
premium membership
Team XNA
-
Posts
562
|
Re: What's the most confusing thing about the content pipeline?
|
Here are a few problems and suggestions from someone who understands the content pipeline pretty well: Problem: Debugging behavior differs from typical applications. As you know, you need to use "Attach to Process" or "Debugger.Launch()" to debug code in the content pipeline. This is highly confusing for most users and a big nuisance to everyone else. Once you understand why this is true, you can learn to live with it, but it is still not an ideal situation. Additionally, this has the side effect of making the content pipeline a big mysterious bit of technology. I'd be willing to bet that the majority of content pipeline confusion stems from this as it greatly weakens the ability of users to putz around with it in the same manner that they putz around with something such as SpriteBatch.
Suggested Solution: Perform lazy builds by default.
When you change a content item or modify the code for an importer or processor, the content needs to be rebuilt. Rather than building content at compile time, build it the first time it is loaded by ContentManager.Load<T>(). This is obviously less than ideal performance wise, but it will enable users to place a breakpoints and do the debugging thing. Allow users to manually invoke a full content build from the Visual Studio UI to avoid the load-time processing and automatically perform this full content build when packaging a game for release. Additionally, provide a Right-click->"Debug Content Build" option for items in a content project in the Solution Explorer.
Problem: ContentTypeWriter and ContentTypeReader are frustratingly manual. Suggested Solution: Why not utilize the .net serialization architecture? I understand that the performance and storage characteristics of the default BinaryFormatter are less than ideal, but it should be possible to generate the IL for a fast (reflection-free) serializer at design-time which is better suited to XNA's needs.
Problem: Types used by the content pipeline and at run-time often have a great deal of overlap. Suggested Solution: This is a tough one! I know Shawn had some ideas. Go ask him :-) Problem: Loaded content objects are inherently singletons, but a lot of game data is inherently not. Take a look at the Simple Animation sample. Extend the sample to have two instances of the Tank class. What you will quickly recognize is that you need to store the original bone transforms as well as the ModelBone objects. if you wish to do the matrix construction during Update (which you should), you'll need to use CopyAbsoluteBoneTransforms to a private Matrix[]. If you don't you'll wind up with a bunch of tanks with all the same animations because of the shared ModelBone objects. Suggested Solution: There needs to be a way to separate objects which should be shared (such as the vertices of the tank) and objects which should be unique for each instance (the bones).
Feel free to start a file labeled "Work Brandon has signed himself up for in July" :-)
Brandon Bloom Software Design Engineer XNA Platform and Tools
|
|
-
-
- (10493)
-
Team XNA
-
Posts
7,929
|
Re: What's the most confusing thing about the content pipeline?
|
I suspect Eli was asking for more of a "what needs to be documented better about the current implementation", rather than "what sweeping architectural changes might be interesting in future" :-)
All good points though...
XNA Framework Developer -
blog - homepage
|
|
-
-
- (462)
-
premium membership
Team XNA
-
Posts
562
|
Re: What's the most confusing thing about the content pipeline?
|
Oh, right... :-)
Well, a lot of the confusion stems from those issues, so there are definitely some blog post topics in there ;-)
Brandon Bloom Software Design Engineer XNA Platform and Tools
|
|
-
-
- (1282)
-
premium membership
Team XNA
-
Posts
1,102
|
Re: What's the most confusing thing about the content pipeline?
|
Brandon Bloom:Problem: Debugging behavior differs from typical applications.
As you know, you need to use "Attach to Process" or "Debugger.Launch()" to debug code in the content pipeline. This is highly confusing for most users and a big nuisance to everyone else. Once you understand why this is true, you can learn to live with it, but it is still not an ideal situation. Additionally, this has the side effect of making the content pipeline a big mysterious bit of technology. I'd be willing to bet that the majority of content pipeline confusion stems from this as it greatly weakens the ability of users to putz around with it in the same manner that they putz around with something such as SpriteBatch.
As someone who understands debugging, I heartily disagree here. Debugging the content pipeline is exactly like debugging other applications. The problem is that "F5" is a mystery to most people, not the content pipeline.
When you set your startup project to WindowsGame1, and that project's output is WindowsGame1.exe, F5 will start debugging WindowsGame1.exe. Your content is built before WindowsGame1.exe starts, so it should not be any kind of mystery that, when debugging starts, it's both too late to debug the content build, and the wrong target process in the first place.
If you want to debug the Content Pipeline, you have to configure your project to debug the content pipeline. Once you do that, you can debug it from the IDE with F5.
I've written a blog post on how to do it here. There, you'll find a link to a project template that is pre-configured for the purpose of debugging your Content Pipeline Extension projects (it even works in VC# Express). After all, you don't really want to debug your entire content build -- just the components that you're working on.
The two posts before that one explain in detail what F5 really does, and why it doesn't make any sense when people expect to hit breakpoints in their pipeline extensions.
Part 1, Part 2.
When you say, "Once you understand why this is true, you can learn to live with it, ..." You should be saying that once you realize why, you are empowered to fix it. The problem isn't the tools, it's that you are launching "debug" on the wrong thing.
Brandon Bloom:... Additionally, provide a Right-click->"Debug Content Build" option for items in a content project in the Solution Explorer.
This is an excellent idea!
Stephen Styrchak | XNA Game Studio Developer
|
|
-
-
- (462)
-
premium membership
Team XNA
-
Posts
562
|
Re: What's the most confusing thing about the content pipeline?
|
Stephen Styrchak:Debugging the content pipeline is exactly like debugging other applications. The problem is that "F5" is a mystery to most people, not the content pipeline.
I guess they are both mysteries to most users then :-) Of course debugging the content pipeline is exactly like debugging other applications, but only in the most technical sense. The reality is that users equate F5 with "run and test out my code" regardless of what it actually means. Whenever I finish making a change to my code, I immediately press F5 to test it. If I introduce a bug in a content build which raises an exception, then I will get a content build error. This is clearly different than if I introduced a similar bug in run-time code; in that case, I will immediately break into the debugger and be presented with an environment in which I am better equipped to diagnose the problem. In order to reduce the cognitive friction of debugging a content build, users must be able to change the code, press F5, and deal with errors identically to errors with normal code and without additional effort or setup on their part.EDIT: Is there any reason why XNA can't override the behavior of F5 to debug the content build AND THEN immediately debug the application? That seems like a perfectly good compromise...
Brandon Bloom Software Design Engineer XNA Platform and Tools
|
|
-
-
- (1728)
-
premium membership
-
Posts
1,192
|
Re: What's the most confusing thing about the content pipeline?
|
I honestly have programmed shaders, physics, and AI, but have never touched the content pipeline. It's always been one of those thingslike my car where if it works, dont mess with it.
Now, I may not know about it but I will admit this is from lack of trying.
If you were to start a blog, it would be great if you could start broad, and then touch on specific areas. Maybe have a poll up about things you could clarify, or go into greater depth with. And always have concrete examples. So, basically, a ginourmous tutorial.
FV
Regards, Louis Ingenthron Fortis Venaliter Lead Developer of FV Productions
|
|
-
-
- (1282)
-
premium membership
Team XNA
-
Posts
1,102
|
Re: What's the most confusing thing about the content pipeline?
|
Brandon Bloom: Stephen Styrchak:
Debugging the content pipeline is exactly like debugging other applications. The problem is that "F5" is a mystery to most people, not the content pipeline.
I guess they are both mysteries to most users then :-)
Of course debugging the content pipeline is exactly like debugging other applications, but only in the most technical sense. The reality is that users equate F5 with "run and test out my code" regardless of what it actually means.
Why, "only in the most technical sense"? It's the same thing as changing the startup project in a solution, or the program to debug in a project. If you want to debug some code, you need to launch an application that executes it.
I grant you that debugging the Content Pipeline could be made easier, but it is not currently as bad as you claim (you do not need to use Attach to Process or Debug.Launch).
The problem today is that the tools hide so much complexity that people don't understand what went wrong when it doesn't "just work". Even though it can be made to work, they don't know how (and don't find it in our docs). I find it ironic that your proposed solution is to hide even more complexity. Of course, that doesn't mean we won't do it. :-)
Brandon Bloom:EDIT: Is there any reason why XNA can't override the behavior of F5 to debug the content build AND THEN immediately debug the application? That seems like a perfectly good compromise...
Yes, several. Although the scenario sounds compelling, you've greatly oversimplified the required change.
I do really like your earlier suggestion of having a specific "Debug Content Build" command. Whether per-project or per-item, that would be pretty easy to do. We could also easily add an option to make that the default debug target for F5 instead of the game, but really, does it have to be F5? Why not Shift-F5 or F2 (nobody uses Edit Label anyway)?
Stephen Styrchak | XNA Game Studio Developer
|
|
-
-
- (462)
-
premium membership
Team XNA
-
Posts
562
|
Re: What's the most confusing thing about the content pipeline?
|
Stephen Styrchak:I do really like your earlier suggestion of having a specific "Debug Content Build" command. Whether per-project or per-item, that would be pretty easy to do. We could also easily add an option to make that the default debug target for F5 instead of the game, but really, does it have to be F5? Why not Shift-F5 or F2 (nobody uses Edit Label anyway)?
I also like the idea of a "Debug Content Build" on a per-item basis -- great if you have many models and want to test building just one. Please do this :-) The reason I stress enabling content build debugging on F5 is because people press F5 and expect their breakpoints to be hit regardless of what project the breakpoint is in. I totally understand how everything works and I still mistakenly set breakpoints in Processors and slap F5 just out of habit! You'll also notice that C# Express (without XNA) hides the build configurations UI by default. I recall reading that this was because their studies have proved it to be confusing, but this is all I can find right now: http://blogs.msdn.com/lukeh/archive/2005/10/17/482045.aspx Oh, and I use F2 for the rename refactoring all the time! The shortcut nicely mirrors renaming files Explorer, which I do often. I wonder what the Customer Experience Improvement Program data has to say about this... I fear we've completely derailed this thread, so let me add that a complete start-to-finish Content Pipeline Tutorial with a real-world usage example would be a perfect series for a blog :-)
Brandon Bloom Software Design Engineer XNA Platform and Tools
|
|
-
|
|
Re: What's the most confusing thing about the content pipeline?
|
Louis Ingenthron:I honestly have programmed shaders, physics, and AI, but have never touched the content pipeline. It's always been one of those thingslike my car where if it works, dont mess with it. Now, I may not know about it but I will admit this is from lack of trying. If you were to start a blog, it would be great if you could start broad, and then touch on specific areas. Maybe have a poll up about things you could clarify, or go into greater depth with. And always have concrete examples. So, basically, a ginourmous tutorial. FV
I agree with Louis here. For many of us with some programming background, but cursory experience in games & the accompanying new terminology that comes along with them, a nice global overview of what the content processor is and what it does would be very useful. To use Louis's example, when learning to drive a new car I'm going to be frustrated to learn the wiring diagram only to discover that it doesn't help me make the car go faster. If my blinker comes on when I press the gas pedal, then I might need the wiring diagram. So, some general discussion of the pipline in terms of its functionality would be useful. The pipeline will come in handy when you want a direct way to....
Best,
Byron
..shaders make you feel... powerful, or very very stupid. http://drjbn.spaces.live.com/
|
|
-
-
- (734)
-
premium membership
MVP
-
Posts
898
|
Re: What's the most confusing thing about the content pipeline?
|
I'd say that there's not enough info about making custom importers that have a complex dependency graph :-) so, for example, how one can create a level importer that imports a bunch of other things ... potentially even further invoking custom importers.
Joel Martinez - XNA MVP Blog: http://codecube.netPlay Videos on an XNA Texture: Scurvy MediaXNA Unit Testing: Scurvy Test
|
|
-
|
|
Re: What's the most confusing thing about the content pipeline?
|
It's not so much the content pipeline that I am entirely confused by but there is another issue I'd like to bring up, fallowed by a aspect of the content pipeline I'd like to see better *officially* explained. First is it not generally considered bad coding practice to hard code strings (IE: game asset names) into your code? This issue was very apparent to me the first time I typed ContentManager.Load<Type>('name') When happends when you finish writing your code for your game and the art manager or the person in charge of managing the game assets decides to rearrange or re-organize the game assets. Poof there goes your game. At run time your game will not be able to load the asset files. Or more commenly if you rename a game asset you also have to do a search through your entire code base to ensure that any content.load calls point to the right asset files. There is an easy way to overcome this issue by having a pre-build tool analize each game asset and generate a namespae ad constant for each asset. I have created a utility to do just that. It is availible on my website at http://www.createdbyx.com/id-Build+Tools__XNAContentCode-XNA.aspx The utility was written for xna 1.1 and I have updated it for 2.0 but have not gotten around to uploading the 2.0 version to my site yet. Here is the write up availible at the web page link I provided above (I'm lazy so i'm cut and pasting it) XNAContentCode is a utility
meant to be called during the pre build event of what ever project you want it to
process. What it does is parse the project *.csproj file, and generate C# code that
mirrors whatever game assets may be included in your GSE project. This allows you
the ability to, instead of using strings, to use C# code to reference your game
assets. Think of the VS.net Resources system, where you would type Resources.YourCustomResourceName,
only XNAContentCode generates static classes (and nested classes if needed) and
static const members that you can write code against instead of using strings.
For example say you had added a few game assets to your GSE project. After XNAContentCode
is run you can reference those assets by typing Content.SomeGameAsset. This also
has the advantage of giving you compile errors if you move or rename a game asset.
Where as normally you would use a string in your code to access a game asset if
you moved or renamed a game asset you would not know weather or not your game would
work until run time when you ran the game, with XNAContentCode you can get feedback
in the form of compile errors at design time. So why can't ms come up with a more similar or better implementation then having to use hard coded strings. As far as I can recall in all my years of programming, hard coding strings in your code has generally been considered a bad coding practice?!? Am I wrong?!? You should use resources or something else. Not to mention how is a pro level game supposed to be developed with xna if issues as fundamental as this have not been addresed.
Secondly, I would like a better description of just what exactly is the framework doing behind the scenes. I have written a stream processor and importer that basically gives the user the ability to load a asset file using content.load<system.io.stream>('name') availible at http://www.createdbyx.com/id-Content+Pipeline__StreamContentProcessor-XNA.aspx I created it because I already had existing code written and wanted a convient way to load a asset file as a stream. (The stream content processor is written for xna 1.1 and yes I have not gotten around to uploading xna 2.0 versions for this and most other xna stuff I have on my site) The full read method code is provided below as a reference.
But here is the thing. The existingInstance parameter of the Read method. Now to look at it, it should be obvious. It should refer to any existing instance of the object that was previously loaded. For example if you loaded a texture2d obj then a few lines of code later loaded the same texture asset. You would think the existingInstance parameter would reference the first texture. In fact the second time the content.load call is made the read method of the reader does not even get called?!? I know this because I descoverd it when using my stream content processor/importer loading the same asset 2 times in a row. What appears to be happening is that the framework is caching all assets for quick retrieval when calling the content.load method. Which means that the reader would only get called a second time if absolutly nessary such as after a device lost event or if the framework detected a change in the asset file after the first call to content.load.
Correct me if I'm wrong but this kind of behind the scenes info, is rather non existant in the xna documentation. The same was true for the sprite batch object. I think shawn blogged about what render states etc the sprite batch object was or was not setting. This kind behind of the behind the scenes info should be in the docs! As well as an explanation as to why it was done that way.
I am not a open source nut, or ms hater either way. But this is a classic example for going open source. If the framework was open source I would not have to make gesses as to what the framework was really doing behind the scenes because I could simply look at the code and there would be the answer. Not only would there be the answer but the understanding that goes with it. AND people would not have to post in the fourms or plea to ms to get answers, they could simply get the answers them selves by studying the framework code. Just a thought. probably never happen. But a thought none the less. It's not like making the xna framework source open will brake the bank for ms, xna is really just an over glorified wrapper for directx after all. And framkly I would not have to spend over an hour typing all this!!! So to recap: - More behind the scenes tech info needs to be provided in the docs as well as reasons for why things are the way they are.
- A better system needs to be implemented to address issues that can occoure when a asset gets moved or renamed.
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics;
// TODO: replace this with the type you want to read. using TRead = System.IO.MemoryStream;
namespace StreamContentReader { /// <summary> /// This class will be instantiated by the XNA Framework Content /// Pipeline to read the specified data type from binary .xnb format. /// /// Unlike the other Content Pipeline support classes, this should /// be a part of your main game project, and not the Content Pipeline /// Extension Library project. /// </summary> public class StreamContentReader : ContentTypeReader<TRead> { protected override TRead Read(ContentReader input, TRead existingInstance) { System.Diagnostics.Debugger.Launch(); // calc the number of characters that will be read int count = (int)(input.BaseStream.Length - input.BaseStream.Position);
// create a string reader to store the data that will be read System.IO.MemoryStream data = new System.IO.MemoryStream(count);
// read "count" number of characters from the input object and write the date to the memory stream data.Write(input.ReadBytes(count), 0, count); data.Seek(0, System.IO.SeekOrigin.Begin);
// return the reference the Doc varible return data; } } }
Created by: X http://www.createdbyx.com/
|
|
-
-
- (352)
-
premium membership
-
Posts
342
|
Re: What's the most confusing thing about the content pipeline?
|
You're not the first to see the content pipeline and say "Ugh, I have
to hardcode my asset names", but I just don't understand why having a
method that takes a string parameter makes people think you have to
hard code those strings into your code.
For example, WPF
provides methods for loading image files. Some of those methods take
string parameters to specify the path to the image file. If I was
writing a slide show program in WPF would I hard code my image names
into the source code? Of course not, I'd get the user to select a
directory and search for files in that directory, or store details
about albums and images that are in those albums in a settings file.
It's
the same with XNA, I don't need to hard code the name of my space ship
model in my source code - the name of the model could be in a config
file, or a level file, or I could search for files in a specific
directory relative to the game executable, or all manner of schemes.
This approach is often called "data driven". You could use data to
drive the selection of your spaceship model, the texture, the colour of
the shield glow, etc.
XNA's content pipeline is perfectly
capable of being used for data driven games. Although I will say that
the default method of building content with your code perhaps
encourages a stronger connection between code/game and assets than I
would like (note, your resource class idea is still hard coding the
assets, just into the program rather than directly into the game source
code). The recent sample that shows building assets within a win forms
program is a good start but more documentation and samples like that,
that show how the content pipeline can be used in different ways. This
would at least let people know there are other ways, even if sticking
assets into the project works happily for most.
|
|
-
|
|
Re: What's the most confusing thing about the content pipeline?
|
All good points. The reason I initially created the XNA prebuild utility was to get feed back in the form of compile errors telling me when any of assets were renamed, moved, or deleted.
Created by: X http://www.createdbyx.com/
|
|
|