2015/06/29

Content Management: Design Questions

I spent the better part of the second week writing three blog posts about content management. I'm not going to post them. The amount of useful code I got out of them is exactly zero. It was kind of fun writing them, and there is still some useful info in there, so let me give you a brief rundown. Read this as a cautionary tale.

The Holy Grail

outlined the features I would expect from an ideal content management system. I also described an architecture I would use to build such a system from scratch. I immediately conceded that I would not do that, though, because the content manager in MonoGame works fine.
Essentially, I would love to unify pretty much every file access the engine has to make into the content manager: configuration, localization, asset loading, and save games.
Config and save files, I figured, should be both read and written with this system. If you treat strings like assets, I thought, supporting localization gets you a long way towards full blown mod support (or the other way around, depending on your point of view). Naturally, the actual file accesses should happen in a background thread while the main thread could safely use loaded assets. Finally, to save memory, I decided I would also allow selective unloading of content. The XNA and MonoGame content managers only allow unloading of all content, after all.

It's certainly possible to build all that on top of MonoGame, but nothing in life is without compromises, and I ended up nowhere near total unification. If you have to compromise on every feature, what's the point in covering each in detail?

Journey to the Center of the Code, Part 1

I really should have done my research at this point. I can't be the first person to want this stuff in all of the combined history of XNA and MonoGame, right? Well, past-me didn't care, and decided to start reading the MG source code, writing this post in parallel.
I learned some really cool stuff about the undocumented implementation details of the ContentManager and how it's used in the Game class, too. But I made a premature judgement about the raw asset feature I discovered in the process, which like the last third of the post and half of the next one are based on.

Those implementation details aren't really relevant to what I'll be doing, though (when that statement inevitably comes back to bite me in the ass, I'll explain the relevant parts only). The argumentation that follows them has a false premise and the project planning after that is based on it, so that's also pointless.

Journey to the Center of the Code, Part 2

I'm not even sure why I named it that, but in this post there's some more faulty project planning, and a much more insightful piece on selective unloading of content. The latter, thankfully, was not compromised by my lack of research, as I knew from prior projects that you're supposed to use multiple instances of ContentManager for this. If you have trouble trusting my word for this, the game state management code sample also does this.
Anyway, the interesting bit is a list of different systems to manage multiple instances of ContentManager and what type of game they work for best. Despite all that, however, I was still indecisive about what system to use, because I'm still not quite sure what specific kind of game I'll be building.

Once we get to partial unloading, I may get back to this. For now, the question is how to proceed.

The Plan

is to deal with configuration and save games first, since they will be treated separately in code. We'll start with an abstraction above the ConfigurationManager to make a type safe Configuration class that can easily be saved back to the app.config file.
For save games, there is the Microsoft.Xna.Storage namespace I never even knew about. We'll play a bit with that later on.
And then we can revisit parallelization and selective unloading. Localization will use the content pipeline, and we'll cover it once everything else is in place.

No comments:

Post a Comment