-
-
Notifications
You must be signed in to change notification settings - Fork 264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to properly setup Content Pipeline projects #126
Comments
At the moment there isn't really a solution to do this, only to build the content with a pure XNA project then build the FNA version separately. We have this in the docs:
One way to deal with this is have both an XNA csproj and an FNA csproj within the same solution, and have all the output in one folder. Depending on how much your content cares about the exe name (easily the worst feature of the pipeline) you may have to separate the folders and just have your FNA Debug config reference "../DebugXNA/Content" as your ContentManager.RootDirectory, for example. |
Ok yet some more detective work. :) As I like neat solutions, I was trying to make a more automated solution than having a completely separate XNA solution to build the content. After I gave up on my two previous tries I figured I would setup a project as you suggested. Turns out I got the same runtime error as I did before, so the problem must lie elsewhere! First the good news! It's not perfect, but instead of having a separate game project to build the content, it is completely fine to build content from a FNA game project even if it has custom content processors that requires access to base engine code, as long as the content project doesn't reference FNA itself, thus the best setup I've found is the following (in case someone else finds this and wants a solution, or se example attachment).
So why didn't this work the first time around for me? Turns out there is a very obscure (at least for me) difference between FNA and XNA when the content is loaded. If my ContentProcessor attaches any kind of class, that has any type of Here is an example project that shows this problem, it also shows how to do the setup properly. Right now the project works fine, comment out line 20 in EngineClass.cs to reproduce the crash. |
If anyone will be able to fix this it probably won't be me... I think I've seen something like this maybe one time ever out of 50-something games and if I remember correctly there was some kind of [Attribute] that could hide certain properties to work correctly. You'll want to debug this yourself since you know your data better than me. Here's where you will most likely want to start: https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentReader.cs#L275 |
Now I remember, it was [ContentSerializerIgnore]: https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentSerializerIgnoreAttribute.cs Shows how often I deal with the content pipeline... |
Oh good to know! Except it doesn't help if that attribute is set to something in the processor, as it will be ignored by the serializer. Anyway, sadly this isn't my strongest area or expertise either or I might try and fix it, but as you say it's probably very seldom anyone would run into this.. If they do hopefully they find this thread, or maybe it would be something just to add some info to that exception message, I don't know. Cheers anyhow, I've got mine working for now! :) |
@flibitijibibo sorry to jump in, but I've a somewhat related question, I haven't had much luck with MonoGame, even after 3.6 which I thought would be quite similar to FNA under the hood I'm having all kinds of problems, especially on integrated cards, so I'm sticking with FNA since I don't plan to target mobiles/consoles anytime soon. I know your efforts are focused on preserving the existing games, but after reading this:
I'm wondering if you've grander plans for FNA :). I especially like how you have full access to SDL2-CS in FNA, and performance is really great. After XNA was discontinued there's not much option for a simpler 2D game in C# that doesn't involve a lot of overhead, there's UV but it apparently isn't getting much love, and I see you're planning to implement modern APIs in XNA, what strikes me as odd since I don't think existing games will really benefit from that, unless you're doing that to push to MG or something. While SFML.Net is an alternative, it's certainly not getting Vulkan or Metal support anytime soon, and I really prefer SDL as a backend, but there's no modern reliable alternative to FNA that uses it and includes audio, input and possibly a binary format for contents. Other than that I just want to congratulate on your fantastic work on both SDL2-CS and FNA! They're terrific high-quality products that so far have proven to be extremely dependable and it's a bit sad to see that they're apparently geared towards the past :P |
@Alan-FGR Accurate reimplementation is grand enough for me, so that's probably where it will stay. The nice thing about XNA is that all the lower-level stuff that the high-level stuff uses is almost entirely exposed - if you want to Build a Better SpriteBatch, that's entirely possible to do (you can even rip off the existing SpriteBatch to do it). Vulkan/Metal/D3D12 still have benefits even for the existing XNA library if only to remove a lot of validation that we currently go through with OpenGL, and having explicit API compatibility makes it a whole lot more compatible with systems where explicit APIs are your only real option (i.e. consoles). In a similar vein, I don't have a whole lot planned for the Content subsystem because XNA's content pipeline is kind of terrible in a whole lot more ways than even I was expecting. XNA has a lot of bad ideas in it that I've been willing to follow through on, but the content pipeline might be my limit in that regard. Writing your own content pipeline that's optimized for the data that you have along with better ways to compress the files you have in your game would probably pay off way more than trying to replicate a system that's pretty much designed to be as Not Streamlined as humanly possible. Grab some DXT compressors, audio encoders/decoders, and PhysicsFS, and you could probably write a superior content editing workflow for the programmer and the artist in a weekend of goofing around. |
@flibitijibibo thanks for your reply. Yeah, I definitely agree. Effects need to be compiled though, and although the latest compilers in the DX SDK still work perfectly (when specifying the version), effects are obsolete at this point, so even though there's a way to build a game from scratch with FNA, some things are a bit weird when doing so. What I'm saying is that although I use and love FNA, I always have this feeling that it's not really intended for what I'm doing 😛. |
This might be worth looking at, though a lot of it isn't helpful until we get Shader Model 5 and a source compiler working: https://blogs.msdn.microsoft.com/chuckw/2012/10/23/effects-for-direct3d-11-update/ https://github.com/Microsoft/FX11 Here's MojoShader's existing compiler: https://hg.icculus.org/icculus/mojoshader/file/tip/mojoshader_compiler.c We could bring back Effect.FromSource as an extension if we really wanted to... but that's like 3 new projects all at once. Most importantly, FNA can be used for whatever; the only difference is that we can't change the API at all. MonoGame could do that but at the moment it's probably not profitable to do so (and probably won't be until XNA games stop showing up...?). |
I want to share my bit of wisdom on this. I have been using MonoGame's Pipeline Tool since forever in combination with FNA. The Content project ( I've only made two small adjustments to the Pipeline Tool by adding two custom Content Processors (using
The combination of this gives you pretty much the same experience as XNA, while allowing Content to be build for all platforms at once. |
Digging this up - most of what's been discussed here should probably go into what fixes #154 but I would like to return to this:
@jsmars, might this block have anything to do with this? https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentReaders/ReflectiveReader.cs#L248 Should we also skip ReadSharedResource for the block on line 268? |
Here's a patch that might fix this @jsmars:
Let me know if this fixes it and I'll commit to master. |
Thanks for looking into this again! I tried it out with my test-case project, sadly for my example it seems the exception persists. Here is an updated archive of the test-case with the patch. It is using the same FNA version as it was before with only the patch applied though, I'm not sure if that could make any difference? |
Content hasn’t changed in a while so that shouldn’t be too bad - we do need a full trace though. Think running msbuild in a VS command prompt will give us the whole thing? |
Any progress here? I'm inclined to close this due to old age, but I'm sure I'll get another question about this so I dunno. @LennardF1989, I may need your Processor files as part of dealing with #154. In documenting MG compatibility it may be needed when talking about MGCB. |
@flibitijibibo Here is everything I have right now: https://gist.github.com/LennardF1989/a5d7d54c89cb6cd0e6bc9551b6fa6a48 And older revision off the OggSongProcessor used the SongProcessor as a base, which allows you to do whatever MonoGame does. It's much safer for changes in the future, but also restraints the process. Eg. Even if you know you won't have to regenerate, you still will have to wait for the original SongProcessor to do it's thing. But the version as it is right now, doesn't retain Duration-information. |
To be honest I probably won't be the one to find the solution on this issue as it's a bit outside my area of expertise and I can't put too much more time into this at the moment - though I may look into it more in the future if it's needed. For my own solution it's enough to know how to avoid the errors. I would suggest adding a verbose exception message here to any custom content being loaded with a list type property that doesn't include a set accessor, to inform that this is in fact needed, to avoid having anyone get stuck in the same way again though. |
@LennardF1989 Thanks for this! I'll probably link directly to that if that's okay. @jsmars I finally figured out what's happening. First of all, I was actually right about the ReflectiveReader stuff being too aggressive: With this change it almost fixes the problem. What's happening is that the very last object is the Tag, and while it does read in your EngineClass, it does NOT read the List inside, which means that when we start reading shared resources, it just reads the next object which is actually that inner List, meaning the shared list was off by one and all the fixups broke. A fun exercise: Change this line in your old FNA version to arbitrarily read https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentReader.cs#L306 But that wasn't enough. It was also failing here: https://github.com/FNA-XNA/FNA/blob/master/src/Content/ContentReaders/ReflectiveReader.cs#L222 And for your convenience:
As you will see, the type we're looking for is actually in the Dictionary... it's looking for With this, the model FINALLY loads properly without a set accessor. Unless there are any further issues, I think this is finished? |
Ah yes, there it is! That should wrap this up I think. As always, thanks a lot @flibitijibibo for all your hard work! :) |
Excellent! I’ll go ahead and close this then. Anything regarding Lennard’s stuff can be continued in #154. |
@flibitijibibo No problem, much obliged! My way of contributing back to FNA :) |
What is the proper way to setup a content pipeline project in an FNA environment when the pipeline needs to reference classes from my main source code?
Normally I just reference the FNA libraries for all my projects, except content projects which build the content via original XNA references, as described in the wiki. However, if for example
CustomModelType
inCustomModelProcessor
needs to referenceCustomRenderer
, which is found in myEngine
project, which is also referenced byGame
, both of which reference FNA.CustomModelProcessor
needs a reference to FNA as well as XNA, which creates a collision and the build cannot be completed because FNA can't build that content.I've tried two solutions for this.
CustomModelProcessor
, I only reference byEngine
classes where needed, and create helpers to convert betweenFNA.Vector3
andXNA.Vector3, Matrix, BoundingBox
and others which are used. The content still cannot be built though, since the content project has a reference to FNA throughEngine
and I can't seem to make it only use the XNA reference to build the content. Not sure if it would work in the end anyway.Game->Engine->FNA
, andGameContent->CustomModelProcessor->EngineXNA->XNA
. (I figure theEngineXNA
can be a lightweight copy having only the required classes theCustomModelType
uses, but they names/namespaces must match exactly!) However, upon loading the content built on the pure XNA reference hierarchy, I get the following error when loading my asset. I can't really understand what thisfixup()
method is doing?Any help? Or is there an even easier solution altogether?
Could be a good idea to have a mention of how this should be done on the Wiki, if there is a decent way.
The text was updated successfully, but these errors were encountered: